IdRepoListener.java revision 60e9e896a1a7a9e62db162e1e9fb6b3c2df50c33
3349N/A/*
3349N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3349N/A *
3349N/A * Copyright (c) 2005 Sun Microsystems Inc. All Rights Reserved
3349N/A *
3349N/A * The contents of this file are subject to the terms
3349N/A * of the Common Development and Distribution License
3349N/A * (the License). You may not use this file except in
3349N/A * compliance with the License.
3349N/A *
3349N/A * You can obtain a copy of the License at
3349N/A * https://opensso.dev.java.net/public/CDDLv1.0.html or
3349N/A * opensso/legal/CDDLv1.0.txt
3349N/A * See the License for the specific language governing
3349N/A * permission and limitations under the License.
3349N/A *
3349N/A * When distributing Covered Code, include this CDDL
3349N/A * Header Notice in each file and include the License file
3349N/A * at opensso/legal/CDDLv1.0.txt.
3349N/A * If applicable, add the following below the CDDL Header,
3349N/A * with the fields enclosed by brackets [] replaced by
3349N/A * your own identifying information:
3349N/A * "Portions Copyrighted [year] [name of copyright owner]"
3349N/A *
4287N/A * $Id: IdRepoListener.java,v 1.16 2009/01/28 05:34:59 ww203982 Exp $
6077N/A *
3349N/A * Portions Copyrighted 2011-2015 ForgeRock AS.
3349N/A */
3349N/Apackage com.sun.identity.idm;
3678N/A
3349N/Aimport java.security.AccessController;
3349N/Aimport java.util.ArrayList;
3349N/Aimport java.util.Collections;
3349N/Aimport java.util.HashSet;
3349N/Aimport java.util.List;
3349N/Aimport java.util.Map;
3349N/Aimport java.util.Set;
3349N/A
3349N/Aimport org.forgerock.openam.ldap.LDAPUtils;
3349N/Aimport org.forgerock.openam.ldap.PersistentSearchChangeType;
3349N/A
3349N/Aimport com.iplanet.sso.SSOException;
3349N/Aimport com.iplanet.sso.SSOToken;
3678N/Aimport com.sun.identity.security.AdminTokenAction;
3678N/Aimport com.sun.identity.shared.debug.Debug;
3678N/Aimport com.sun.identity.shared.jaxrpc.SOAPClient;
3349N/Aimport com.sun.identity.sm.SMSException;
3349N/Aimport com.sun.identity.sm.ServiceConfig;
3678N/Aimport com.sun.identity.sm.ServiceConfigManager;
3349N/Aimport com.sun.identity.sm.ServiceManager;
3349N/A
3349N/A/**
3349N/A * Provides methods that can be called by IdRepo plugins to notify change
3349N/A * events. Used to update cache and also to send notifications to registered
3349N/A * listeners. Each IdRepo plugin will be given a unique instance of this object.
3349N/A *
3619N/A * Additionally, this class maintains the configuration data for the IdRepo
3678N/A * plugin and also to store the SMS Service attributes for the organization.
3349N/A *
3387N/A * @supported.all.api
3387N/A */
3387N/Apublic final class IdRepoListener {
3349N/A
3387N/A // Configuration data for the IdRepo plugin
3349N/A // Must have "realm" key to correctly send the notifications to clients
3349N/A private Map configMap = null;
3349N/A
3349N/A // Listener registed by JAXRPC Impl to send notifications
3349N/A private static IdEventListener remoteListener = null;
3349N/A
3349N/A private static Debug debug = Debug.getInstance("idrepoListener");
3349N/A
3349N/A // To serialize and deserialize configMap
3387N/A protected static SOAPClient sclient;
3349N/A
3349N/A // Configured Identity Types
3349N/A private static IdType[] defaultIdTypes;
3387N/A
3349N/A // Flags to check if caching is enabled and to clear them
3349N/A private static boolean cacheChecked;
3349N/A private static boolean cacheEnabled;
3387N/A private static IdServices idServices;
3349N/A
3349N/A /*
3349N/A * (non-Javadoc)
3387N/A *
3349N/A * @see com.iplanet.am.sdk.AMObjectListener#allObjectsChanged()
3349N/A */
3349N/A public void allObjectsChanged() {
3387N/A if (debug.messageEnabled()) {
3349N/A debug.message("IdRepoListener: allObjectsChanged Called!");
3349N/A }
3387N/A
3387N/A // Check if caching is enabled
3349N/A if (!cacheChecked) {
3349N/A idServices = IdServicesFactory.getDataStoreServices();
3349N/A if (idServices instanceof IdCachedServices) {
3387N/A // If Caching was enabled - then clear the cache!!
3349N/A cacheEnabled = true;
3349N/A }
3349N/A cacheChecked = true;
3387N/A }
3349N/A if (cacheEnabled) {
3349N/A // If Caching was enabled - then clear the cache!!
3349N/A ((IdCachedServices) idServices).clearCache();
3387N/A }
3349N/A
3349N/A // Get the list of listeners setup with idRepo
3349N/A String org = (String) configMap.get("realm");
3567N/A ArrayList list = (ArrayList) AMIdentityRepository.listeners.get(org);
3678N/A // Update any listeners registered with IdRepo
3567N/A if (list != null) {
3387N/A int size = list.size();
3387N/A for (int j = 0; j < size; j++) {
3387N/A IdEventListener l = (IdEventListener) list.get(j);
3349N/A l.allIdentitiesChanged();
3619N/A }
3349N/A }
3387N/A if (remoteListener != null) {
3387N/A remoteListener.allIdentitiesChanged();
3387N/A }
3387N/A }
6077N/A
3619N/A /**
3387N/A *
3349N/A * This method has been deprecated as of OpenSSO Enterprise 8.0.
3619N/A *
3349N/A * @param name name of the identity that changed
3349N/A * @param type change type i.e., add, delete, modify, etc.
3387N/A * @param cMap configuration map that contains realm and plugin-name
3387N/A *
3349N/A * @deprecated As of Sun Java System Access Manager 7.1.
3349N/A */
6077N/A public void objectChanged(String name, int type, Map cMap) {
3349N/A objectChanged(name, null, type, cMap);
3349N/A }
3349N/A
3387N/A /**
3387N/A * Notification mechanism for IdRepo plugins to specify the identiy name
3387N/A * and identity type that has been changed.
3387N/A *
3387N/A * @param name name of the identity that changed
3387N/A * @param idType IdType i.e., user, group, etc.
3387N/A * @param changeType change type i.e., add, delete, modify, etc.
3387N/A * @param cMap configuration map that contains realm and plugin-name
3349N/A */
3349N/A public void objectChanged(String name, IdType idType, int changeType,
3349N/A Map cMap) {
3349N/A if (debug.messageEnabled()) {
3349N/A debug.message("objectChanged called with IdType= name: " + name +
3349N/A " IdType: " + idType + " ChangeType: " + changeType +
3349N/A "\nConfigmap = " + cMap);
3349N/A }
3349N/A // Get the list of listeners setup with idRepo
3349N/A String org = (String) configMap.get("realm");
3349N/A List<IdEventListener> list = (List<IdEventListener>) AMIdentityRepository.listeners.get(org);
3349N/A list = list == null ? new ArrayList<IdEventListener>() : new ArrayList<>(list);
3349N/A if (remoteListener != null) {
3349N/A list.add(remoteListener);
3349N/A }
3349N/A
3349N/A // Check if caching is enabled
3349N/A if (!cacheChecked) {
3349N/A idServices = IdServicesFactory.getDataStoreServices();
3349N/A if (idServices instanceof IdCachedServices) {
3349N/A // If Caching was enabled - then clear the cache!!
3349N/A cacheEnabled = true;
3349N/A }
3349N/A cacheChecked = true;
3349N/A }
3387N/A
3387N/A if (name.length() > 0) {
3349N/A String[] changed = getChangedIds(name, idType, cMap);
3349N/A for (int i = 0; i < changed.length; i++) {
3349N/A
3387N/A if (cacheEnabled) {
3349N/A ((IdCachedServices) idServices).dirtyCache(changed[i],
3349N/A changeType, false, false, Collections.EMPTY_SET);
3349N/A }
3349N/A
3349N/A for (IdEventListener l : list) {
3349N/A // Update any listeners registered with IdRepo
3349N/A if(changeType == OBJECT_CHANGED || changeType == OBJECT_ADDED) {
3349N/A l.identityChanged(changed[i]);
3349N/A } else if (changeType == OBJECT_REMOVED) {
3349N/A l.identityDeleted(changed[i]);
3349N/A } else if (changeType == OBJECT_RENAMED) {
3349N/A l.identityRenamed(changed[i]);
3349N/A }
3349N/A }
3387N/A }
3349N/A }
3349N/A }
3349N/A
3349N/A public static void addRemoteListener(IdEventListener l) {
3349N/A remoteListener = l;
3387N/A }
3387N/A
3349N/A /*
3349N/A * Returns the configurations for the IdRepo plugins
3349N/A */
3349N/A public Map getConfigMap() {
3387N/A return configMap;
3619N/A }
3619N/A
3349N/A /*
3349N/A * Maintains the configurations for the IdRepo plugins
3349N/A */
3349N/A public void setConfigMap(Map cMap) {
3349N/A configMap = cMap;
3349N/A }
3349N/A
3349N/A /**
3567N/A * Stores service's dynamic attributes within the IdRepo plugin
3349N/A * configuration. In the current implementation changes to dynamic
3349N/A * attributes to LDAPv3Repo restart the plugin, since it triggers
3349N/A * a configuration change notification.
3349N/A *
3349N/A * @param sName service name for which attributes are being set
3349N/A * @param attrs service synamic attributes
3349N/A * @throws com.sun.identity.idm.IdRepoException
3349N/A */
3349N/A public void setServiceAttributes(String sName, Map attrs)
3349N/A throws IdRepoException {
3349N/A String realm = (String) configMap.get("realm");
3349N/A String pluginName = (String) configMap.get("plugin-name");
3619N/A if (realm == null || pluginName == null) {
6077N/A AMIdentityRepository.debug.error(
6077N/A "IdRepoListener.setServiveAttribute: realm or plugin name"
3619N/A + " is null");
3619N/A Object[] args = { sName, IdType.ROLE.getName() };
3349N/A throw new IdRepoException(IdRepoBundle.BUNDLE_NAME, IdRepoErrorCode.SERVICE_ALREADY_ASSIGNED, args);
3548N/A }
3349N/A try {
3349N/A SSOToken token = (SSOToken) AccessController
3349N/A .doPrivileged(AdminTokenAction.getInstance());
3349N/A ServiceConfigManager scm = new ServiceConfigManager(token,
3349N/A IdConstants.REPO_SERVICE, "1.0");
3349N/A ServiceConfig sc = scm.getOrganizationConfig(realm, null);
3619N/A if (sc == null) {
3619N/A return;
3619N/A }
3678N/A
3349N/A ServiceConfig subConfig = sc.getSubConfig(pluginName);
3349N/A if (subConfig == null) {
3349N/A return;
3349N/A }
3349N/A Map attributes = subConfig.getAttributes();
3678N/A Set vals = (Set) attributes.get(IdConstants.SERVICE_ATTRS);
3678N/A if (vals == null || vals == Collections.EMPTY_SET) {
3678N/A vals = new HashSet();
3678N/A }
3678N/A if (sclient == null) {
3678N/A sclient = new SOAPClient("dummy");
3678N/A }
3678N/A String mapStr = sclient.encodeMap("result", attrs);
3678N/A vals = new HashSet();
3678N/A vals.add(mapStr);
3349N/A attributes.put(IdConstants.SERVICE_ATTRS, vals);
3678N/A subConfig.setAttributes(attributes);
3678N/A } catch (SMSException smse) {
3678N/A AMIdentityRepository.debug.error(
3678N/A "IdRepoListener: Unable to set service attributes", smse);
3678N/A Object[] args = { sName, IdType.ROLE.getName() };
3678N/A throw new IdRepoException(IdRepoBundle.BUNDLE_NAME, IdRepoErrorCode.SERVICE_ALREADY_ASSIGNED, args);
3678N/A } catch (SSOException ssoe) {
3678N/A AMIdentityRepository.debug.error(
3678N/A "IdRepoListener: Unable to set service attributes", ssoe);
3678N/A Object[] args = { sName, IdType.ROLE.getName() };
3678N/A throw new IdRepoException(IdRepoBundle.BUNDLE_NAME, IdRepoErrorCode.SERVICE_ALREADY_ASSIGNED, args);
3678N/A }
3678N/A }
3678N/A
3678N/A private String[] getChangedIds(String name, IdType type, Map cMap) {
3678N/A int size = IdUtils.supportedTypes.size();
3678N/A // If configMap is null, then this is a "remote" cache update
3678N/A if ((cMap == null) || cMap.isEmpty()) {
3678N/A String ct[] = new String[1];
3349N/A if (LDAPUtils.isDN(name)) {
3349N/A // Name should be the universal id
3349N/A ct[0] = name;
3349N/A } else {
3349N/A if (type == null) {
3349N/A // Default to user
3349N/A type = IdType.USER;
3548N/A }
3567N/A ct[0] = "id=" + name + ",ou=" + type.getName() + "," +
3567N/A ServiceManager.getBaseDN();
3567N/A }
3349N/A return ct;
3349N/A }
3387N/A String changedTypes[] = null;
3349N/A IdType types[] = null;
3619N/A if (type == null) {
3619N/A changedTypes = new String[size];
3349N/A if (defaultIdTypes == null) {
3349N/A Set idtypes = IdUtils.supportedTypes;
3349N/A defaultIdTypes = new IdType[idtypes.size()];
3387N/A defaultIdTypes = (IdType[]) idtypes.toArray(defaultIdTypes);
3387N/A }
3387N/A types = defaultIdTypes;
3349N/A } else {
3349N/A changedTypes = new String[1];
3678N/A types = new IdType[1];
3678N/A types[0] = type;
3678N/A }
3678N/A String realm = (String) cMap.get("realm");
3678N/A String Amsdk = (String) cMap.get("amsdk");
3678N/A boolean isAmsdk = Amsdk != null;
3678N/A
3678N/A for (int i = 0; i < types.length; i++) {
3678N/A IdType itype = types[i];
3349N/A String n = LDAPUtils.isDN(name) ? LDAPUtils.rdnValueFromDn(name) : name;
3387N/A String id = "id=" + n + ",ou=" + itype.getName() + "," + realm;
3349N/A if (isAmsdk) {
3349N/A id = id + ",amsdkdn=" + name;
3387N/A }
3349N/A changedTypes[i] = id;
3567N/A }
3567N/A return changedTypes;
3619N/A }
3567N/A
3567N/A // Constants for change type recevied from the IdRepo plugins
3567N/A
3349N/A /**
3619N/A * Represents an object addition event type.
3619N/A */
3349N/A public static final int OBJECT_ADDED = PersistentSearchChangeType.ADDED;
3349N/A
3349N/A /**
3349N/A * Represents an object change event type.
3548N/A */
3349N/A public static final int OBJECT_CHANGED = PersistentSearchChangeType.MODIFIED;
3349N/A
3349N/A /**
3349N/A * Represents an object removal event type.
3349N/A */
3349N/A public static final int OBJECT_REMOVED = PersistentSearchChangeType.REMOVED;
3349N/A
3349N/A /**
3349N/A * Represents an object renaming event type.
6078N/A */
3349N/A public static final int OBJECT_RENAMED = PersistentSearchChangeType.RENAMED;
3349N/A}
3349N/A