EventListener.java revision b174f2fef6b1d8ee82424e19de3ad21f872c1ed7
/**
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2005 Sun Microsystems Inc. All Rights Reserved
*
* The contents of this file are subject to the terms
* of the Common Development and Distribution License
* (the License). You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the License at
* See the License for the specific language governing
* permission and limitations under the License.
*
* When distributing Covered Code, include this CDDL
* Header Notice in each file and include the License file
* at opensso/legal/CDDLv1.0.txt.
* If applicable, add the following below the CDDL Header,
* with the fields enclosed by brackets [] replaced by
* your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* $Id: EventListener.java,v 1.12 2008/06/27 20:56:23 arviranga Exp $
*
*/
/**
* Portions Copyrighted 2011-2013 ForgeRock AS
*/
/**
* The <code>EventListener</code> handles the events generated from the
* server. If notification URL is provided, the class registers the URL with the
* Server and waits for notifications. Else it polls the server at configurable
* time periods to get updates from the server.
*/
class EventListener {
private static SOAPClient client;
private static final String NOTIFICATION_PROPERTY =
"com.sun.identity.idm.remote.notification.enabled";
private static final String CACHE_POLLING_TIME_PROPERTY =
"com.iplanet.am.sdk.remote.pollingTime";
private static final int DEFAULT_CACHE_POLLING_TIME = 1;
public synchronized static EventListener getInstance() {
instance = new EventListener();
}
return instance;
}
/**
* Constructor for <class>EventListener</class>. Should be instantiated
* once by <code>RemoteServicesImpl</code>
*
*/
private EventListener() {
// Construct the SOAP Client
// Check if notification is enabled
// Default the notification enabled to true if the property
// is not found for backward compatibility.
NOTIFICATION_PROPERTY, "true");
// Run in notifications mode
// Check if notification URL is provided
try {
// Register for notification with AM Server
}
if (debug.messageEnabled()) {
}
} else {
if (debug.messageEnabled()) {
}
}
if (shutdownMan.acquireValidLock()) {
try {
public void shutdown() {
try {
if (debug.messageEnabled()) {
}
} else {
if (debug.messageEnabled()) {
"due to null ID");
}
}
} catch (Exception e) {
"deRegisterNotificationURL with ID " + remoteId, e);
}
}
});
} finally {
}
}
// Register with PLLClient for notification
new EventNotificationHandler());
if (debug.messageEnabled()) {
+ "mechanism for cache updates: "
}
} catch (Exception e) {
// Use polling mechanism to update caches
if (debug.warningEnabled()) {
+ "notification via URL failed for " + url
+ e.getMessage()
+ "\nUsing polling mechanism for updates");
}
// Start Polling thread only if enabled.
}
} else {
// Start Polling thread only if enabled.
}
}
private int getCachePollingInterval() {
// If the property is not configured, default it to 1 minute.
if (cachePollingTimeStr != null) {
try {
} catch (NumberFormatException nfe) {
+ "Invalid Polling Time: " + cachePollingTimeStr +
" Defaulting to " + DEFAULT_CACHE_POLLING_TIME +
" minute");
}
}
return cachePollingInterval;
}
private static void startPollingThreadIfEnabled(int cachePollingInterval) {
if (cachePollingInterval > 0) {
if (debug.messageEnabled()) {
"Starting the polling thread..");
}
// Run in polling mode
} else {
if (debug.warningEnabled()) {
CACHE_POLLING_TIME_PROPERTY + "=" +
}
}
}
throws AMEventManagerException {
// Validate the token
try {
} catch (SSOException ssoe) {
}
// Add to listeners
synchronized (listeners) {
}
}
/**
* Sends notifications to listeners added via <code>addListener</code>.
* The parameter <code>nItem</code> is an XML document having a single
* notification event, using the following DTD.
* <p>
*
* <pre>
* <!-- EventNotification element specifes the change notification
* which contains AttributeValuePairs. The attributes defined
* are "method", "entityName", "
* eventType" and "attrNames". -->
* <!ELEMENT EventNotification ( AttributeValuePairs )* >
*
* <!-- AttributeValuePair element contains attribute name and
* values -->
* <!ELEMENT AttributeValuPair ( Attribute, Value*) >
*
* <!-- Attribute contains the attribute names, and the allowed
* names are "method", "entityName",
* "eventType" and "attrNames" -->
* <!ELEMENT Attribute EMPTY>
* <!ATTRLIST Attribute
* name ( method | entityName | eventType | attrNames )
* "method"
* >
*
* <!-- Value element specifies the values for the attributes
* --> <!ELEMENT Value (#PCDATA) >
* </pre>
*
* @param nItem
* notification event as a xml document
*
*/
if (debug.messageEnabled()) {
+ "Received notification.");
}
// Construct the XML document
try {
if (debug.messageEnabled()) {
+ "Decoded Event: " + attrs);
}
// Get method name
}
// Get entity name
if (entityName == null) {
}
// Switch based on method
// Call objectChanged method on the listeners
// Update the Remote Cache
if (RemoteServicesFactory.isCachingEnabled()) {
}
synchronized (listeners) {
{
.next();
}
}
if (RemoteServicesFactory.isCachingEnabled()) {
eventType, true, false, attributes);
}
// Call objectsChanged method on the listeners
synchronized (listeners) {
{
.next();
attributes, null);
}
}
if (RemoteServicesFactory.isCachingEnabled()) {
AMEvent.OBJECT_CHANGED, false, true,
}
// Call permissionChanged method on the listeners
synchronized (listeners) {
{
.next();
}
}
if (RemoteServicesFactory.isCachingEnabled()) {
}
// Call allObjectsChanged method on listeners
synchronized (listeners) {
{
.next();
}
}
} else {
// Invalid method name
}
if (debug.messageEnabled()) {
+ "notification.");
}
} catch (Exception e) {
if (debug.warningEnabled()) {
+ " notification: " + nItem, e);
}
}
}
// Debug the message and throw an exception
}
}
return (answer);
}
// throw an exception
throw (new Exception("EventListener::sendNotification: "
+ "invalid event type: " + eventSet));
}
}
static class NotificationRunnable extends GeneralTaskRunnable {
private int pollingTime;
private long runPeriod;
NotificationRunnable(int interval) {
}
return false;
}
return false;
}
public boolean isEmpty() {
return true;
}
public long getRunPeriod() {
return runPeriod;
}
public void run() {
try {
if (debug.messageEnabled()) {
+ "retrived changes: " + mods);
}
}
} catch (NumberFormatException nfe) {
// Should not happend
+ "Number Format Exception for polling Time: "
+ pollingTime, nfe);
+ "Exception", ex);
}
}
}
static class EventNotificationHandler implements NotificationHandler {
// Empty constructor
}
.elementAt(i);
if (debug.messageEnabled()) {
+ "IdRepoEventNotificationHandler: received "
+ "notification: " + content);
}
// Send notification
}
}
}
// Static varaibles
}