001/* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at 010 * docs/licenses/cddl.txt 011 * or http://www.opensource.org/licenses/cddl1.php. 012 * See the License for the specific language governing permissions 013 * and limitations under the License. 014 * 015 * When distributing Covered Code, include this CDDL HEADER in each 016 * file and include the License file at 017 * docs/licenses/cddl.txt. If applicable, 018 * add the following below this CDDL HEADER, with the fields enclosed 019 * by brackets "[]" replaced with your own identifying information: 020 * Portions Copyright [yyyy] [name of copyright owner] 021 * 022 * CDDL HEADER END 023 * 024 * 025 * Portions Copyright 2010-2024 Ping Identity Corporation 026 */ 027package com.unboundid.directory.sdk.common.api; 028 029 030 031import java.util.Collections; 032import java.util.List; 033import java.util.Map; 034 035import com.unboundid.directory.sdk.broker.internal.BrokerExtension; 036import com.unboundid.directory.sdk.common.config.AlertHandlerConfig; 037import com.unboundid.directory.sdk.common.internal.ExampleUsageProvider; 038import com.unboundid.directory.sdk.common.internal.Reconfigurable; 039import com.unboundid.directory.sdk.common.internal.UnboundIDExtension; 040import com.unboundid.directory.sdk.common.types.AlertNotification; 041import com.unboundid.directory.sdk.common.types.ServerContext; 042import com.unboundid.directory.sdk.ds.internal.DirectoryServerExtension; 043import com.unboundid.directory.sdk.metrics.internal.MetricsEngineExtension; 044import com.unboundid.directory.sdk.proxy.internal.DirectoryProxyServerExtension; 045import com.unboundid.directory.sdk.sync.internal.SynchronizationServerExtension; 046import com.unboundid.ldap.sdk.LDAPException; 047import com.unboundid.ldap.sdk.ResultCode; 048import com.unboundid.util.Extensible; 049import com.unboundid.util.ThreadSafety; 050import com.unboundid.util.ThreadSafetyLevel; 051import com.unboundid.util.args.ArgumentException; 052import com.unboundid.util.args.ArgumentParser; 053 054 055 056/** 057 * This class defines an API that must be implemented by extensions which will 058 * be invoked whenever an administrative alert is generated within the server. 059 * Administrative alerts may be used to notify administrators whenever a 060 * significant error, warning, or other type of event occurs within the server. 061 * Alert handlers may be used to help ensure that those notifications are made 062 * available to administrators in an appropriate manner. 063 * <BR><BR> 064 * Each alert handler may be configured so that it will only be invoked for 065 * certain types of alerts, either based on the specific alert type or based on 066 * the alert severity. This is handled automatically by the server, so 067 * individual alert handler implementations do not need to attempt to perform 068 * that filtering on their own. However, they may perform additional processing 069 * if desired to further narrow the set of alerts that should be made available 070 * to administrators. 071 * <BR> 072 * <H2>Configuring Alert Handlers</H2> 073 * In order to configure an alert handler created using this API, use a command 074 * like: 075 * <PRE> 076 * dsconfig create-alert-handler \ 077 * --handler-name "<I>{handler-name}</I>" \ 078 * --type third-party \ 079 * --set enabled:true \ 080 * --set "extension-class:<I>{class-name}</I>" \ 081 * --set "extension-argument:<I>{name=value}</I>" 082 * </PRE> 083 * where "<I>{handler-name}</I>" is the name to use for the alert handler 084 * instance, "<I>{class-name}</I>" is the fully-qualified name of the Java class 085 * that extends {@code com.unboundid.directory.sdk.common.api.AlertHandler}, 086 * and "<I>{name=value}</I>" represents name-value pairs for any arguments to 087 * provide to the alert handler. If multiple arguments should be provided to 088 * the alert handler, then the 089 * "<CODE>--set extension-argument:<I>{name=value}</I></CODE>" option should be 090 * provided multiple times. 091 * 092 * @see com.unboundid.directory.sdk.common.scripting.ScriptedAlertHandler 093 */ 094@Extensible() 095@DirectoryServerExtension() 096@DirectoryProxyServerExtension(appliesToLocalContent=true, 097 appliesToRemoteContent=false) 098@SynchronizationServerExtension(appliesToLocalContent=true, 099 appliesToSynchronizedContent=false) 100@MetricsEngineExtension() 101@BrokerExtension() 102@ThreadSafety(level=ThreadSafetyLevel.INTERFACE_THREADSAFE) 103public abstract class AlertHandler 104 implements UnboundIDExtension, Reconfigurable<AlertHandlerConfig>, 105 ExampleUsageProvider 106{ 107 /** 108 * Creates a new instance of this alert handler. All alert handler 109 * implementations must include a default constructor, but any initialization 110 * should generally be done in the {@code initializeAlertHandler} method. 111 */ 112 public AlertHandler() 113 { 114 // No implementation is required. 115 } 116 117 118 119 /** 120 * {@inheritDoc} 121 */ 122 public abstract String getExtensionName(); 123 124 125 126 /** 127 * {@inheritDoc} 128 */ 129 public abstract String[] getExtensionDescription(); 130 131 132 133 /** 134 * {@inheritDoc} 135 */ 136 public void defineConfigArguments(final ArgumentParser parser) 137 throws ArgumentException 138 { 139 // No arguments will be allowed by default. 140 } 141 142 143 144 /** 145 * Initializes this alert handler. 146 * 147 * @param serverContext A handle to the server context for the server in 148 * which this extension is running. 149 * @param config The general configuration for this alert handler. 150 * @param parser The argument parser which has been initialized from 151 * the configuration for this alert handler. 152 * 153 * @throws LDAPException If a problem occurs while initializing this alert 154 * handler. 155 */ 156 public void initializeAlertHandler(final ServerContext serverContext, 157 final AlertHandlerConfig config, 158 final ArgumentParser parser) 159 throws LDAPException 160 { 161 // No initialization will be performed by default. 162 } 163 164 165 166 /** 167 * {@inheritDoc} 168 */ 169 public boolean isConfigurationAcceptable(final AlertHandlerConfig config, 170 final ArgumentParser parser, 171 final List<String> unacceptableReasons) 172 { 173 // No extended validation will be performed by default. 174 return true; 175 } 176 177 178 179 /** 180 * {@inheritDoc} 181 */ 182 public ResultCode applyConfiguration(final AlertHandlerConfig config, 183 final ArgumentParser parser, 184 final List<String> adminActionsRequired, 185 final List<String> messages) 186 { 187 // By default, no configuration changes will be applied. If there are any 188 // arguments, then add an admin action message indicating that the extension 189 // needs to be restarted for any changes to take effect. 190 if (! parser.getNamedArguments().isEmpty()) 191 { 192 adminActionsRequired.add( 193 "No configuration change has actually been applied. The new " + 194 "configuration will not take effect until this alert handler " + 195 "is disabled and re-enabled or until the server is restarted."); 196 } 197 198 return ResultCode.SUCCESS; 199 } 200 201 202 203 /** 204 * Performs any cleanup which may be necessary when this alert handler is to 205 * be taken out of service. 206 */ 207 public void finalizeAlertHandler() 208 { 209 // No implementation is required. 210 } 211 212 213 214 /** 215 * Performs any processing which may be necessary to handle the provided alert 216 * notification. 217 * 218 * @param alert The alert notification generated within the server. 219 */ 220 public abstract void handleAlert(final AlertNotification alert); 221 222 223 224 /** 225 * {@inheritDoc} 226 */ 227 public Map<List<String>,String> getExamplesArgumentSets() 228 { 229 return Collections.emptyMap(); 230 } 231}