8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Copyright (c) 2005 Sun Microsystems Inc. All Rights Reserved
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * The contents of this file are subject to the terms
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * of the Common Development and Distribution License
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * (the License). You may not use this file except in
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * compliance with the License.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * You can obtain a copy of the License at
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * https://opensso.dev.java.net/public/CDDLv1.0.html or
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * See the License for the specific language governing
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * permission and limitations under the License.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * When distributing Covered Code, include this CDDL
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Header Notice in each file and include the License file
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * If applicable, add the following below the CDDL Header,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * with the fields enclosed by brackets [] replaced by
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * your own identifying information:
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "Portions Copyrighted [year] [name of copyright owner]"
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * $Id: EntryEventListener.java,v 1.4 2009/01/28 05:34:48 ww203982 Exp $
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington * Portions Copyright 2015 ForgeRock AS.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.iplanet.am.sdk.common.ICachedDirectoryServices;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.iplanet.am.sdk.common.IDirectoryServices;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.iplanet.services.ldap.event.IDSEventListener;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.sun.identity.security.AdminTokenAction;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.sun.identity.sm.ServiceSchemaManager;
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunningtonimport org.forgerock.openam.ldap.PersistentSearchChangeType;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * The <code>AMEntryEventListener</code> handles all the events that are
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * triggered by any modification/deletion/renaming LDAP entires which do not
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * contain ACI's. This class implements the <code>com.iplanet.services
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * .ldap.event.IDSEventListener</code>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * interface.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterpublic class EntryEventListener implements IDSEventListener {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Filter to separate entires which do not contain aci's
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster protected static final String SEARCH_FILTER = "(&(objectclass=*)"
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster + "(!(|(objectclass=sunService)(objectclass=sunServiceComponent)"
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster + "(aci=*))))";
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington protected static final int OPERATIONS = PersistentSearchChangeType.ALL_OPERATIONS;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Instance variables
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.error("EntryEventListener() Exception occurred while "
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private Set getDynamicAttributeNames(String serviceName) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ServiceSchemaManager sm = new ServiceSchemaManager(serviceName,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ServiceSchema sschema = sm.getSchema(SchemaType.DYNAMIC);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.warning("EntryEventListener.entryChanged(): "
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.error("EntryEventListener.entryChanged(): "
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * This method will be invoked by the <code>EventService</code> if the
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * events for which this listener registered has been triggered. Since this
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * listener is interested in modifications/deletions/renaming of normal
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * directory entires, it identifies the distinguished names affected by this
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * event and sends a notification to the <code>AMObjectImpl</code> by
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * calling the appropriate method.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * @param dsEvent
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * <code>DSEvent</code> object generated by the
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * <code>EventService</code>.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Get the "dn" responsible for the event
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington String normalizedDN = dn.toString().toLowerCase();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("EntryEventListener.entryChanged(): DSEvent "
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Check if the event was caused by changes/deletions to cos entries
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // (cosdefinitions & costemplates) and figure out the affected dn
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // subtree. Parse the dn in case of cos related events to find out the
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // affected subtree of dns Examples of costemplate dn:
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // "cn="cn=RoleThree,o=hp.com,o=vortex.com",cn=nsCalUser,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // o=hp.com,o=vortex.com"
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // affectDNs will be all those which suffix match
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // "o=hp.com,o=vortex.com"
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Examples of cosdefintion dn:
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // "cn=nsCalUser,o=hp.com,o=vortex.com";
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // affectDNs => "o=hp.com,o=vortex.com"
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster boolean cosType = true;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (objClasses.indexOf("cosClassicDefinition") != -1) {// COS
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // definition
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington affectDNs = dn.parent().toString().toLowerCase();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Get the serviceName this applies to, and get the attribute
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // names of this service which impact the DNs.
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington serviceName = LDAPUtils.rdnValueFromDn(dn);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster attrNames = getDynamicAttributeNames(serviceName);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("EntryEventListener.entryChanged() "
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster + "Cos Definition changed for service: " + serviceName
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } else if (objClasses.indexOf("costemplate") != -1) { // COS template
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington affectDNs = dn.parent().parent().toString().toLowerCase();
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington serviceName = LDAPUtils.rdnValueFromDn(dn.parent());
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster attrNames = getDynamicAttributeNames(serviceName);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("EntryEventListener." + "entryChanged()"
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster + "Cos template changed for service: " + serviceName
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } else { // Not cos related - only a single dn affected
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("EntryEventListener.entryChanged(): Affected dn: "
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster IDirectoryServices dsServices = DirectoryServicesFactory.getInstance();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Call the listeners
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster synchronized (listeners) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster for (Iterator items = keys.iterator(); items.hasNext();) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster AMObjectListener listener = (AMObjectListener) items.next();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (cosType) { // All affected service attributes must be
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // removed for user entries as well the affected template
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (DirectoryServicesFactory.isCachingEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ((ICachedDirectoryServices) dsServices).dirtyCache(
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster affectDNs, dsEvent.getEventType(), true, false,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ((ICachedDirectoryServices) dsServices).dirtyCache(
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster listener.objectsChanged(affectDNs, dsEvent.getEventType(),
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // first call removes the attributes. now remove
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // the template.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (DirectoryServicesFactory.isCachingEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ((ICachedDirectoryServices) dsServices).dirtyCache(
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster listener.objectChanged(affectDNs, dsEvent.getEventType(),
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * This method is invoked by the <code>EventService</code> if it
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * encounters an error.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * @param errorStr
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * error string.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.error("EntryEventListener.eventError(): " + errorStr);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.error("EntryEventListener: Received all entries changed event"
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster + "from event service");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster IDirectoryServices dsServices = DirectoryServicesFactory.getInstance();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (DirectoryServicesFactory.isCachingEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ((ICachedDirectoryServices) dsServices).clearCache();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Call the listeners
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster synchronized (listeners) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster for (Iterator items = keys.iterator(); items.hasNext();) {