summaryrefslogtreecommitdiffstats
path: root/base/server/cmscore/src/com/netscape/cmscore/profile/LDAPProfileSubsystem.java
diff options
context:
space:
mode:
Diffstat (limited to 'base/server/cmscore/src/com/netscape/cmscore/profile/LDAPProfileSubsystem.java')
-rw-r--r--base/server/cmscore/src/com/netscape/cmscore/profile/LDAPProfileSubsystem.java112
1 files changed, 92 insertions, 20 deletions
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 b16a33fe2..f48aea391 100644
--- a/base/server/cmscore/src/com/netscape/cmscore/profile/LDAPProfileSubsystem.java
+++ b/base/server/cmscore/src/com/netscape/cmscore/profile/LDAPProfileSubsystem.java
@@ -22,6 +22,7 @@ import java.io.InputStream;
import java.util.Hashtable;
import java.util.LinkedHashMap;
import java.util.TreeMap;
+import java.util.TreeSet;
import netscape.ldap.LDAPAttribute;
import netscape.ldap.LDAPConnection;
@@ -62,6 +63,11 @@ public class LDAPProfileSubsystem
* of the profile entry that this instance has seen */
private TreeMap<String,Integer> entryUSNs;
+ private TreeMap<String,String> nsUniqueIds;
+
+ /* Set of nsUniqueIds of deleted entries */
+ private TreeSet<String> deletedNsUniqueIds;
+
/**
* Initializes this subsystem with the given configuration
* store.
@@ -79,6 +85,8 @@ public class LDAPProfileSubsystem
mProfiles = new LinkedHashMap<String, IProfile>();
mProfileClassIds = new Hashtable<String, String>();
entryUSNs = new TreeMap<>();
+ nsUniqueIds = new TreeMap<>();
+ deletedNsUniqueIds = new TreeSet<>();
IConfigStore cs = CMS.getConfigStore();
IConfigStore dbCfg = cs.getSubStore("internaldb");
@@ -110,6 +118,14 @@ public class LDAPProfileSubsystem
IPluginRegistry registry = (IPluginRegistry)
CMS.getSubsystem(CMS.SUBSYSTEM_REGISTRY);
+ String nsUniqueId =
+ ldapProfile.getAttribute("nsUniqueId").getStringValueArray()[0];
+ if (deletedNsUniqueIds.contains(nsUniqueId)) {
+ CMS.debug("readProfile: ignoring entry with nsUniqueId '"
+ + nsUniqueId + "' due to deletion");
+ return;
+ }
+
String profileId = null;
String dn = ldapProfile.getDN();
if (!dn.startsWith("cn=")) {
@@ -145,6 +161,7 @@ public class LDAPProfileSubsystem
CMS.debug("Start Profile Creation - " + profileId + " " + classId + " " + info.getClassName());
createProfile(profileId, classId, info.getClassName(), data);
entryUSNs.put(profileId, newEntryUSN);
+ nsUniqueIds.put(profileId, nsUniqueId);
CMS.debug("Done Profile Creation - " + profileId);
} catch (EProfileException e) {
CMS.debug("Error creating profile '" + profileId + "'; skipping.");
@@ -192,7 +209,7 @@ public class LDAPProfileSubsystem
}
}
- public void deleteProfile(String id) throws EProfileException {
+ public synchronized void deleteProfile(String id) throws EProfileException {
if (isProfileEnable(id)) {
throw new EProfileException("CMS_PROFILE_DELETE_ENABLEPROFILE");
}
@@ -215,9 +232,31 @@ public class LDAPProfileSubsystem
}
}
+ deletedNsUniqueIds.add(nsUniqueIds.get(id));
forgetProfile(id);
}
+ private synchronized void handleDELETE(LDAPEntry entry) {
+ LDAPAttribute attr = entry.getAttribute("nsUniqueId");
+ String nsUniqueId = null;
+ if (attr != null)
+ nsUniqueId = attr.getStringValueArray()[0];
+
+ if (deletedNsUniqueIds.remove(nsUniqueId)) {
+ CMS.debug("handleDELETE: delete was already effected");
+ return;
+ }
+
+ String profileId = null;
+ String dn = entry.getDN();
+ if (!dn.startsWith("cn=")) {
+ CMS.debug("handleDELETE: DN " + dn + " does not start with 'cn='");
+ return;
+ }
+ profileId = LDAPDN.explodeDN(dn, true)[0];
+ forgetProfile(profileId);
+ }
+
private synchronized void handleMODDN(DN oldDN, LDAPEntry entry) {
DN profilesDN = new DN(dn);
@@ -231,20 +270,61 @@ public class LDAPProfileSubsystem
@Override
public synchronized void commitProfile(String id) throws EProfileException {
LDAPConfigStore cs = (LDAPConfigStore) mProfiles.get(id).getConfigStore();
+
+ // first create a *new* profile object from the configStore
+ // and initialise it with the updated configStore
+ //
+ IPluginRegistry registry = (IPluginRegistry)
+ CMS.getSubsystem(CMS.SUBSYSTEM_REGISTRY);
+ String classId = mProfileClassIds.get(id);
+ IPluginInfo info = registry.getPluginInfo("profile", classId);
+ String className = info.getClassName();
+ IProfile newProfile = null;
try {
- String[] attrs = {"entryUSN"};
- LDAPEntry entry = cs.commitReturn(false, attrs);
+ newProfile = (IProfile) Class.forName(className).newInstance();
+ } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
+ throw new EProfileException("Could not instantiate class '"
+ + classId + "' for profile '" + id + "': " + e);
+ }
+ newProfile.setId(id);
+ try {
+ newProfile.init(this, cs);
+ } catch (EBaseException e) {
+ throw new EProfileException(
+ "Failed to initialise profile '" + id + "': " + e);
+ }
- LDAPAttribute attr = null;
- if (entry != null)
- attr = entry.getAttribute("entryUSN");
+ // next replace the existing profile with the new profile;
+ // this is to avoid any intermediate state where the profile
+ // is not fully initialised with its inputs, outputs and
+ // policy objects.
+ //
+ mProfiles.put(id, newProfile);
+
+ // finally commit the configStore and track the resulting
+ // entryUSN and (in case of add) the nsUniqueId
+ //
+ try {
+ String[] attrs = {"entryUSN", "nsUniqueId"};
+ LDAPEntry entry = cs.commitReturn(false, attrs);
+ if (entry == null) {
+ // shouldn't happen, but let's be sure not to crash anyway
+ return;
+ }
Integer entryUSN = null;
+ LDAPAttribute attr = entry.getAttribute("entryUSN");
if (attr != null)
entryUSN = new Integer(attr.getStringValueArray()[0]);
-
entryUSNs.put(id, entryUSN);
CMS.debug("commitProfile: new entryUSN = " + entryUSN);
+
+ String nsUniqueId = null;
+ attr = entry.getAttribute("nsUniqueId");
+ if (attr != null)
+ nsUniqueId = attr.getStringValueArray()[0];
+ CMS.debug("commitProfile: nsUniqueId = " + nsUniqueId);
+ nsUniqueIds.put(id, nsUniqueId);
} catch (ELdapException e) {
throw new EProfileException(
"Failed to commit config store of profile '" + id + ": " + e);
@@ -261,17 +341,7 @@ public class LDAPProfileSubsystem
mProfiles.remove(id);
mProfileClassIds.remove(id);
entryUSNs.remove(id);
- }
-
- private void forgetProfile(LDAPEntry entry) {
- String profileId = null;
- String dn = entry.getDN();
- if (!dn.startsWith("cn=")) {
- CMS.debug("forgetProfile: DN " + dn + " does not start with 'cn='");
- return;
- }
- profileId = LDAPDN.explodeDN(dn, true)[0];
- forgetProfile(profileId);
+ nsUniqueIds.remove(id);
}
/**
@@ -296,6 +366,8 @@ public class LDAPProfileSubsystem
mProfiles.clear();
mProfileClassIds.clear();
entryUSNs.clear();
+ nsUniqueIds.clear();
+ deletedNsUniqueIds.clear();
}
/**
@@ -328,7 +400,7 @@ public class LDAPProfileSubsystem
cons.setServerControls(persistCtrl);
cons.setBatchSize(1);
cons.setServerTimeLimit(0 /* seconds */);
- String[] attrs = {"*", "entryUSN"};
+ String[] attrs = {"*", "entryUSN", "nsUniqueId"};
LDAPSearchResults results = conn.search(
dn, LDAPConnection.SCOPE_ONE, "(objectclass=*)",
attrs, false, cons);
@@ -347,7 +419,7 @@ public class LDAPProfileSubsystem
break;
case LDAPPersistSearchControl.DELETE:
CMS.debug("Profile change monitor: DELETE");
- forgetProfile(entry);
+ handleDELETE(entry);
break;
case LDAPPersistSearchControl.MODIFY:
CMS.debug("Profile change monitor: MODIFY");