bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington/*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Copyright (c) 2005 Sun Microsystems Inc. All Rights Reserved
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
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 *
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 * opensso/legal/CDDLv1.0.txt
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * See the License for the specific language governing
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * permission and limitations under the License.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * When distributing Covered Code, include this CDDL
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Header Notice in each file and include the License file
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * at opensso/legal/CDDLv1.0.txt.
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 *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * $Id: EventService.java,v 1.19 2009/09/28 21:47:33 ww203982 Exp $
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington * Portions Copyrighted 2010-2015 ForgeRock AS.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterpackage com.iplanet.services.ldap.event;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunningtonimport java.math.BigInteger;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.security.AccessController;
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunningtonimport java.util.ArrayList;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.util.Collection;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.util.HashMap;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.util.Iterator;
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunningtonimport java.util.List;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.util.Map;
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunningtonimport java.util.Random;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.util.Set;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunningtonimport com.iplanet.am.sdk.ldap.ACIEventListener;
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunningtonimport com.iplanet.am.sdk.ldap.EntryEventListener;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.iplanet.am.util.SystemProperties;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.iplanet.services.ldap.DSConfigMgr;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.iplanet.services.ldap.LDAPServiceException;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.iplanet.services.ldap.LDAPUser;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.iplanet.services.util.I18n;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.iplanet.sso.SSOException;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.iplanet.ums.IUMSConstants;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.sun.identity.idm.IdConstants;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.sun.identity.security.AdminTokenAction;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.sun.identity.shared.Constants;
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunningtonimport com.sun.identity.shared.debug.Debug;
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunningtonimport com.sun.identity.sm.SMSException;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.sun.identity.sm.ServiceSchema;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.sun.identity.sm.ServiceSchemaManager;
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunningtonimport com.sun.identity.sm.ldap.LDAPEventManager;
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunningtonimport org.forgerock.opendj.ldap.ConnectionFactory;
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunningtonimport org.forgerock.opendj.ldap.DN;
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunningtonimport org.forgerock.opendj.ldap.Entry;
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunningtonimport org.forgerock.opendj.ldap.Filter;
ce4d3fddc8fe2eddd68a20af9570b3cc63ece5abNeil Maddenimport org.forgerock.opendj.ldap.LdapException;
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunningtonimport org.forgerock.opendj.ldap.SearchScope;
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunningtonimport org.forgerock.opendj.ldap.controls.PersistentSearchChangeType;
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunningtonimport org.forgerock.opendj.ldap.responses.SearchResultEntry;
57a1b25dcdf865eacb2fe2e17c5ca83e942da047David Lunaimport org.forgerock.util.thread.listener.ShutdownListener;
57a1b25dcdf865eacb2fe2e17c5ca83e942da047David Lunaimport org.forgerock.util.thread.listener.ShutdownManager;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/**
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington *
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * @supported.api
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunningtonpublic class EventService {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington private static Debug logger = Debug.getInstance("amEventService");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private static I18n i18n = I18n.getInstance(IUMSConstants.UMS_PKG);
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington private static DSConfigMgr cm = null;
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington private static final String EVENT_CONNECTION_RETRY_INTERVAL =
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington "com.iplanet.am.event.connection.delay.between.retries";
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington private static final int RETRY_INTERVAL = SystemProperties.getAsInt(EVENT_CONNECTION_RETRY_INTERVAL, 3000);
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington private static final String EVENT_LISTENER_DISABLE_LIST = "com.sun.am.event.connection.disable.list";
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington private static final Class<? extends IDSEventListener> ACI_EVENT_LISTENER_CLASS_NAME = ACIEventListener.class;
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington private static final Class<? extends IDSEventListener> ENTRY_EVENT_LISTENER_CLASS_NAME = EntryEventListener.class;
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington private static final Class<? extends IDSEventListener> LDAP_EVENT_LISTENER_CLASS_NAME = LDAPEventManager.class;
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington private static volatile boolean isShutdownCalled = false;
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington private static volatile boolean isRunning = false;
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington private ConnectionFactory adminConnectionFactory;
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington private ConnectionFactory smsConnectionFactory;
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington private final Map<Class<? extends IDSEventListener>, ListenerSearch> persistentSearches = new HashMap<>();
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington private static final class ListenerSearch {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington private final IDSEventListener listener;
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington private final EventServicePersistentSearch search;
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington private ListenerSearch(IDSEventListener listener, EventServicePersistentSearch search) {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington this.listener = listener;
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington this.search = search;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington private enum Singleton {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington INSTANCE;
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington private EventService eventService;
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington private EventException eventException;
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington Singleton() {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster try {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington eventService = new EventService();
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington ShutdownManager shutdownMan = com.sun.identity.common.ShutdownManager.getInstance();
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington shutdownMan.addShutdownListener(
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington new ShutdownListener() {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington public void shutdown() {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington if (eventService != null) {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington eventService.stopPSearches();
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington }
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington }
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington });
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington } catch (EventException e) {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington eventException = e;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington private EventService getEventService() throws EventException {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington if (eventException != null) {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington throw eventException;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington return eventService;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington private EventService() throws EventException {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington try {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington cm = DSConfigMgr.getDSConfigMgr();
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington } catch (LDAPServiceException lse) {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington logger.error("EventService.getConfigManager() - Failed to get handle to Configuration Manager", lse);
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington throw new EventException(i18n.getString(IUMSConstants.DSCFG_NOCFGMGR), lse);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington *
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * @supported.api
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
ce4d3fddc8fe2eddd68a20af9570b3cc63ece5abNeil Madden public synchronized static EventService getEventService() throws EventException, LdapException {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington if (isShutdownCalled) {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington return null;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington return Singleton.INSTANCE.getEventService();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington //Question: is ok to not actually restart running psearches if the listener is still enabled?
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington public synchronized void restartPSearches() {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington List<Class<? extends IDSEventListener>> listenersClasses = getEnabledListenersClasses();
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington for (Iterator<Class<? extends IDSEventListener>> iterator = persistentSearches.keySet().iterator();
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington iterator.hasNext();) {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington Class<? extends IDSEventListener> pSearchListenerClass = iterator.next();
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington //remove any running psearches that do not have enabled listeners
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington if (!listenersClasses.contains(pSearchListenerClass)) {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington persistentSearches.get(pSearchListenerClass).search.stopSearch();
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington iterator.remove();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } else {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington listenersClasses.remove(pSearchListenerClass);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington for (Iterator<Class<? extends IDSEventListener>> iterator = listenersClasses.iterator(); iterator.hasNext();) {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington Class<? extends IDSEventListener> listenerClass = iterator.next();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington try {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington IDSEventListener listener = listenerClass.newInstance();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington EventServicePersistentSearch pSearch = new EventServicePersistentSearch(RETRY_INTERVAL,
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington DN.valueOf(listener.getBase()), Filter.valueOf(listener.getFilter()),
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington SearchScope.valueOf(listener.getScope()), getConnectionFactory(listener.getClass()),
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington "objectclass");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington pSearch.addListener(listener, new BigInteger(130, new Random()).toString());
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington pSearch.startSearch();
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington persistentSearches.put(listenerClass, new ListenerSearch(listener, pSearch));
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington logger.message("EventService.restartPSearches() - successfully initialized: {}", listenerClass);
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington iterator.remove();
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington } catch (Exception e) {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington logger.error("EventService.restartPSearches() Unable to start listener {}", listenerClass, e);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington if (!listenersClasses.isEmpty()) {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington for (Class<? extends IDSEventListener> listenerClass : listenersClasses) {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington logger.error("EventService.restartPSearches(): unable add listener: {}", listenerClass);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington isRunning = true;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington public synchronized void stopPSearches() {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington isShutdownCalled = true;
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington for (ListenerSearch pSearch : persistentSearches.values()) {
7f1ad89d15984c64fde1e507c3b38238cb2e3f8dJames Phillpotts pSearch.search.removeListener(pSearch.listener);
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington pSearch.search.stopSearch();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington public static boolean isStarted() {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington return isRunning && !isShutdownCalled;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington public IDSEventListener getListener(Class<? extends IDSEventListener> listenerClass) {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington return persistentSearches.get(listenerClass).listener;
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington private static List<Class<? extends IDSEventListener>> getEnabledListenersClasses() {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington Collection<String> disabledListeners = getDisabledListeners();
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington boolean disableACI = disabledListeners.contains("aci");
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington boolean disableUM = disabledListeners.contains("um");
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington boolean disableSM = disabledListeners.contains("sm");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington if (!disableUM || !disableACI) {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington // Check if AMSDK is configured
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington if (!isAMSDKConfigured()) {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington disableUM = true;
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington disableACI = true;
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington if (logger.messageEnabled()) {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington logger.message("EventService.getListenerList(): AMSDK is not configured or config time. "
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington + "Disabling UM and ACI event listeners");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
7e1f38ed3474c45b25b65d5784e78f72fc25556bDavid Luna //psearch terminated if you disable the DB notifications, or add 'sm' to the list of disabled
7e1f38ed3474c45b25b65d5784e78f72fc25556bDavid Luna if (!disableSM) {
7e1f38ed3474c45b25b65d5784e78f72fc25556bDavid Luna disableSM = !Boolean.parseBoolean(SystemProperties.get(Constants.SMS_ENABLE_DB_NOTIFICATION));
7e1f38ed3474c45b25b65d5784e78f72fc25556bDavid Luna }
7e1f38ed3474c45b25b65d5784e78f72fc25556bDavid Luna
7e1f38ed3474c45b25b65d5784e78f72fc25556bDavid Luna if (logger.messageEnabled()) {
7e1f38ed3474c45b25b65d5784e78f72fc25556bDavid Luna logger.message("EventService.getListenerList(): SMS listener is enabled: {}", !disableSM);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington List<Class<? extends IDSEventListener>> listeners = new ArrayList<>();
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington // Disable the selected listeners
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington if (!disableACI) {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington listeners.add(ACI_EVENT_LISTENER_CLASS_NAME);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington if (!disableUM) {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington listeners.add(ENTRY_EVENT_LISTENER_CLASS_NAME);
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington }
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington if (!disableSM) {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington listeners.add(LDAP_EVENT_LISTENER_CLASS_NAME);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington if (disableACI && disableUM && disableSM) {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington logger.message("EventService.getListenerList() - all listeners are disabled, EventService won't start");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington return listeners;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington private ConnectionFactory getConnectionFactory(Class<? extends IDSEventListener> listenerClass)
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington throws LDAPServiceException {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington if (LDAPEventManager.class.equals(listenerClass) && cm.getServerGroup("sms") != null) {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington return getSmsConnectionFactory();
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington } else {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington return getAdminConnectionFactory();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington private ConnectionFactory getAdminConnectionFactory() throws LDAPServiceException {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington if (adminConnectionFactory == null) {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington adminConnectionFactory = DSConfigMgr.getDSConfigMgr().getNewAdminConnectionFactory();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington return adminConnectionFactory;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington private ConnectionFactory getSmsConnectionFactory() throws LDAPServiceException {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington if (smsConnectionFactory == null) {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington smsConnectionFactory = DSConfigMgr.getDSConfigMgr()
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington .getNewConnectionFactory("sms", LDAPUser.Type.AUTH_ADMIN);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington return smsConnectionFactory;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington private void dispatchException(Exception e, String requestId, IDSEventListener listener) {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington logger.error("EventService.dispatchException() - dispatching exception to the listener: {} Listener: {}",
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington requestId, listener, e);
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington listener.eventError(e.toString());
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington private void dispatchEvent(DSEvent dirEvent, IDSEventListener listener) {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington listener.entryChanged(dirEvent);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington private DSEvent createDSEvent(Entry entry, PersistentSearchChangeType changeType, String requestId,
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington IDSEventListener listener) throws Exception {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster DSEvent dsEvent = new DSEvent();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington logger.message("EventService.createDSEvent() - Notifying event to: {}", listener);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Get the dn from the entry
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington String dn = entry.getName().toString();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster dsEvent.setID(dn);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Get information on the type of change made
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington dsEvent.setEventType(changeType.intValue());
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Pass the search ID as the event's change info
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington dsEvent.setSearchID(requestId);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // set the object class name
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String className = entry.getAttribute("objectclass").toString();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster dsEvent.setClassName(className);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return dsEvent;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington private static Collection<String> getDisabledListeners() {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington List<String> disabledListeners = new ArrayList<>();
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington String list = SystemProperties.get(EVENT_LISTENER_DISABLE_LIST, "");
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington logger.message("EventService.getListenerList(): {}: {}", EVENT_LISTENER_DISABLE_LIST, list);
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington for (String disabledListener : list.split(",")) {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington disabledListeners.add(disabledListener.trim());
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington return disabledListeners;
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington }
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington private static boolean isDuringConfigurationTime() {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington return Boolean.parseBoolean(SystemProperties.get(Constants.SYS_PROPERTY_INSTALL_TIME));
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington }
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington private static boolean isAMSDKConfigured() {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington boolean isAMSDKConfigured = false;
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington boolean configTime = isDuringConfigurationTime();
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington logger.message("EventService.getListenerList(): {}: {}", Constants.SYS_PROPERTY_INSTALL_TIME, configTime);
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington if (!configTime) {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington try {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington ServiceSchemaManager scm = new ServiceSchemaManager(
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington AccessController.doPrivileged(AdminTokenAction.getInstance()), IdConstants.REPO_SERVICE, "1.0");
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington ServiceSchema idRepoSubSchema = scm.getOrganizationSchema();
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington Set idRepoPlugins = idRepoSubSchema.getSubSchemaNames();
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington if (idRepoPlugins.contains("amSDK")) {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington isAMSDKConfigured = true;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington } catch (SMSException ex) {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington logger.warning("EventService.getListenerList() - Unable to obtain idrepo service", ex);
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington } catch (SSOException ex) {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington // Should not happen, ignore the exception
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington return isAMSDKConfigured;
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington }
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington private final class EventServicePersistentSearch extends LDAPv3PersistentSearch<IDSEventListener, String> {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington private final SearchResultEntryHandler resultEntryHandler = new PSearchResultEntryHandler();
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington public EventServicePersistentSearch(int retryInterval, DN pSearchBaseDN, Filter pSearchFilter,
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington SearchScope pSearchScope, ConnectionFactory factory, String... attributeNames) {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington super(retryInterval, pSearchBaseDN, pSearchFilter, pSearchScope, factory, attributeNames);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington @Override
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington protected void clearCaches() {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington for (IDSEventListener listener : getListeners().keySet()) {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington listener.allEntriesChanged();
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington @Override
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington protected SearchResultEntryHandler getSearchResultEntryHandler() {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington return resultEntryHandler;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington private final class PSearchResultEntryHandler implements LDAPv3PersistentSearch.SearchResultEntryHandler {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington private final Exception EXCEPTION =
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington new Exception("EventService - Cannot create NamingEvent, no change control info");
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington @Override
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington public boolean handle(SearchResultEntry entry, String dn, DN previousDn, PersistentSearchChangeType type) {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington for (Map.Entry<IDSEventListener, String> listener : getListeners().entrySet()) {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington if (type != null) {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington logger.message("EventService.processSearchResultMessage() changeCtrl = {}", type.toString());
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington // Convert control into a DSEvent and dispatch to listeners
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington try {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington DSEvent event = createDSEvent(entry, type, listener.getValue(), listener.getKey());
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington dispatchEvent(event, listener.getKey());
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington } catch (Exception ex) {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington dispatchException(ex, listener.getValue(), listener.getKey());
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington }
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington } else {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington dispatchException(EXCEPTION, listener.getValue(), listener.getKey());
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington }
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington }
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington return true;
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster}