Skip to content

Commit ef6d62d

Browse files
shwstpprLocharla, Sandeep
authored andcommitted
api,server: allow configuring repetitive alerts (apache#11325)
* api,server: allow configuring repetitive alerts Fixes apache#6613 Introduces support for configuring additional alert types that can be published repeatedly, beyond the default set. Operators can now use the dynamic configuration `alert.allowed.repetitive.types` to specify a comma-separated list of alert type names that should be allowed for repetitive publication. Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com> * add tests Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com> * fix Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com> * test fix Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com> * allow repetition for custom alerts Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com> * remove refactoring Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com> --------- Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
1 parent 5fc8c11 commit ef6d62d

File tree

6 files changed

+160
-39
lines changed

6 files changed

+160
-39
lines changed

api/src/main/java/org/apache/cloudstack/api/ApiConstants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,7 @@ public class ApiConstants {
503503
public static final String RECONNECT = "reconnect";
504504
public static final String RECOVER = "recover";
505505
public static final String REPAIR = "repair";
506+
public static final String REPETITION_ALLOWED = "repetitionallowed";
506507
public static final String REQUIRES_HVM = "requireshvm";
507508
public static final String RESOURCES = "resources";
508509
public static final String RESOURCE_COUNT = "resourcecount";

api/src/main/java/org/apache/cloudstack/api/command/admin/resource/ListAlertTypesCmd.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,18 @@
1616
// under the License.
1717
package org.apache.cloudstack.api.command.admin.resource;
1818

19-
import com.cloud.user.Account;
19+
import java.util.ArrayList;
20+
import java.util.List;
21+
import java.util.Set;
22+
2023
import org.apache.cloudstack.alert.AlertService;
2124
import org.apache.cloudstack.api.APICommand;
2225
import org.apache.cloudstack.api.BaseCmd;
2326
import org.apache.cloudstack.api.response.AlertResponse;
2427
import org.apache.cloudstack.api.response.AlertTypeResponse;
2528
import org.apache.cloudstack.api.response.ListResponse;
2629

27-
import java.util.ArrayList;
28-
import java.util.List;
29-
import java.util.Set;
30+
import com.cloud.user.Account;
3031

3132
@APICommand(name = "listAlertTypes", description = "Lists all alerts types", responseObject = AlertResponse.class,
3233
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
@@ -43,7 +44,8 @@ public void execute() {
4344
ListResponse<AlertTypeResponse> response = new ListResponse<>();
4445
List<AlertTypeResponse> typeResponseList = new ArrayList<>();
4546
for (AlertService.AlertType alertType : result) {
46-
AlertTypeResponse alertResponse = new AlertTypeResponse(alertType.getType(), alertType.getName());
47+
AlertTypeResponse alertResponse = new AlertTypeResponse(alertType.getType(), alertType.getName(),
48+
alertType.isRepetitionAllowed());
4749
alertResponse.setObjectName("alerttype");
4850
typeResponseList.add(alertResponse);
4951
}

api/src/main/java/org/apache/cloudstack/api/response/AlertTypeResponse.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@
1616
// under the License.
1717
package org.apache.cloudstack.api.response;
1818

19-
import com.cloud.serializer.Param;
20-
import com.google.gson.annotations.SerializedName;
2119
import org.apache.cloudstack.api.ApiConstants;
2220
import org.apache.cloudstack.api.BaseResponse;
2321

22+
import com.cloud.serializer.Param;
23+
import com.google.gson.annotations.SerializedName;
24+
2425
public class AlertTypeResponse extends BaseResponse {
2526

2627
@SerializedName("alerttypeid")
@@ -31,6 +32,10 @@ public class AlertTypeResponse extends BaseResponse {
3132
@Param(description = "description of alert type")
3233
private String name;
3334

35+
@SerializedName(ApiConstants.REPETITION_ALLOWED)
36+
@Param(description = "Whether repetitive alerts allowed for the alert type", since = "4.22.0")
37+
private boolean repetitionAllowed = true;
38+
3439
public String getName() {
3540
return name;
3641
}
@@ -47,9 +52,10 @@ public void setUsageType(short alertType) {
4752
this.alertType = alertType;
4853
}
4954

50-
public AlertTypeResponse(short alertType, String name) {
55+
public AlertTypeResponse(short alertType, String name, boolean repetitionAllowed) {
5156
this.alertType = alertType;
5257
this.name = name;
58+
this.repetitionAllowed = repetitionAllowed;
5359
setObjectName("alerttype");
5460
}
5561
}

engine/components-api/src/main/java/com/cloud/alert/AlertManager.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ public interface AlertManager extends Manager, AlertService {
4949
"Percentage (as a value between 0 and 1) of guest network IPv6 subnet utilization above which alerts will be sent.",
5050
true);
5151

52+
ConfigKey<String> AllowedRepetitiveAlertTypes = new ConfigKey<>(ConfigKey.CATEGORY_ALERT, String.class,
53+
"alert.allowed.repetitive.types", "",
54+
"Comma-separated list of alert types (by name) that can be sent multiple times", true);
55+
5256
void clearAlert(AlertType alertType, long dataCenterId, long podId);
5357

5458
void recalculateCapacity();

server/src/main/java/com/cloud/alert/AlertManagerImpl.java

Lines changed: 47 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import java.io.UnsupportedEncodingException;
2020
import java.text.DecimalFormat;
2121
import java.util.ArrayList;
22-
import java.util.Arrays;
2322
import java.util.Date;
2423
import java.util.HashMap;
2524
import java.util.HashSet;
@@ -37,15 +36,12 @@
3736
import javax.mail.MessagingException;
3837
import javax.naming.ConfigurationException;
3938

40-
import com.cloud.dc.DataCenter;
41-
import com.cloud.dc.Pod;
42-
import com.cloud.org.Cluster;
43-
4439
import org.apache.cloudstack.backup.BackupManager;
4540
import org.apache.cloudstack.framework.config.ConfigDepot;
4641
import org.apache.cloudstack.framework.config.ConfigKey;
4742
import org.apache.cloudstack.framework.config.Configurable;
4843
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
44+
import org.apache.cloudstack.framework.messagebus.MessageBus;
4945
import org.apache.cloudstack.managed.context.ManagedContextTimerTask;
5046
import org.apache.cloudstack.storage.datastore.db.ObjectStoreDao;
5147
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
@@ -54,6 +50,7 @@
5450
import org.apache.cloudstack.utils.mailing.SMTPMailProperties;
5551
import org.apache.cloudstack.utils.mailing.SMTPMailSender;
5652
import org.apache.commons.lang3.ArrayUtils;
53+
import org.apache.commons.lang3.StringUtils;
5754
import org.apache.commons.lang3.math.NumberUtils;
5855
import org.apache.logging.log4j.LogManager;
5956
import org.apache.logging.log4j.Logger;
@@ -70,9 +67,11 @@
7067
import com.cloud.configuration.Config;
7168
import com.cloud.configuration.ConfigurationManager;
7269
import com.cloud.dc.ClusterVO;
70+
import com.cloud.dc.DataCenter;
7371
import com.cloud.dc.DataCenter.NetworkType;
7472
import com.cloud.dc.DataCenterVO;
7573
import com.cloud.dc.HostPodVO;
74+
import com.cloud.dc.Pod;
7675
import com.cloud.dc.Vlan.VlanType;
7776
import com.cloud.dc.dao.ClusterDao;
7877
import com.cloud.dc.dao.DataCenterDao;
@@ -86,10 +85,12 @@
8685
import com.cloud.host.dao.HostDao;
8786
import com.cloud.network.Ipv6Service;
8887
import com.cloud.network.dao.IPAddressDao;
88+
import com.cloud.org.Cluster;
8989
import com.cloud.org.Grouping.AllocationState;
9090
import com.cloud.resource.ResourceManager;
9191
import com.cloud.storage.StorageManager;
9292
import com.cloud.utils.Pair;
93+
import com.cloud.utils.Ternary;
9394
import com.cloud.utils.component.ManagerBase;
9495
import com.cloud.utils.concurrency.NamedThreadFactory;
9596
import com.cloud.utils.db.SearchCriteria;
@@ -100,21 +101,6 @@
100101
public class AlertManagerImpl extends ManagerBase implements AlertManager, Configurable {
101102
protected Logger logger = LogManager.getLogger(AlertManagerImpl.class.getName());
102103

103-
public static final List<AlertType> ALERTS = Arrays.asList(AlertType.ALERT_TYPE_HOST
104-
, AlertType.ALERT_TYPE_USERVM
105-
, AlertType.ALERT_TYPE_DOMAIN_ROUTER
106-
, AlertType.ALERT_TYPE_CONSOLE_PROXY
107-
, AlertType.ALERT_TYPE_SSVM
108-
, AlertType.ALERT_TYPE_STORAGE_MISC
109-
, AlertType.ALERT_TYPE_MANAGEMENT_NODE
110-
, AlertType.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED
111-
, AlertType.ALERT_TYPE_UPLOAD_FAILED
112-
, AlertType.ALERT_TYPE_OOBM_AUTH_ERROR
113-
, AlertType.ALERT_TYPE_HA_ACTION
114-
, AlertType.ALERT_TYPE_CA_CERT
115-
, AlertType.ALERT_TYPE_EXTENSION_PATH_NOT_READY
116-
, AlertType.ALERT_TYPE_VPN_GATEWAY_OBSOLETE_PARAMETERS);
117-
118104
private static final long INITIAL_CAPACITY_CHECK_DELAY = 30L * 1000L; // Thirty seconds expressed in milliseconds.
119105

120106
private static final DecimalFormat DfPct = new DecimalFormat("###.##");
@@ -156,6 +142,8 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
156142
Ipv6Service ipv6Service;
157143
@Inject
158144
HostDao hostDao;
145+
@Inject
146+
MessageBus messageBus;
159147

160148
private Timer _timer = null;
161149
private long _capacityCheckPeriod = 60L * 60L * 1000L; // One hour by default.
@@ -175,6 +163,8 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
175163
protected String[] recipients = null;
176164
protected String senderAddress = null;
177165

166+
private final List<String> allowedRepetitiveAlertTypeNames = new ArrayList<>();
167+
178168
public AlertManagerImpl() {
179169
_executor = Executors.newCachedThreadPool(new NamedThreadFactory("Email-Alerts-Sender"));
180170
}
@@ -254,12 +244,32 @@ public boolean configure(String name, Map<String, Object> params) throws Configu
254244
_capacityCheckPeriod = Long.parseLong(Config.CapacityCheckPeriod.getDefaultValue());
255245
}
256246
}
247+
initMessageBusListener();
248+
setupRepetitiveAlertTypes();
257249

258250
_timer = new Timer("CapacityChecker");
259251

260252
return true;
261253
}
262254

255+
protected void setupRepetitiveAlertTypes() {
256+
allowedRepetitiveAlertTypeNames.clear();
257+
String allowedRepetitiveAlertsStr = AllowedRepetitiveAlertTypes.value();
258+
logger.trace("Allowed repetitive alert types specified by {}: {} ", AllowedRepetitiveAlertTypes.key(),
259+
allowedRepetitiveAlertsStr);
260+
if (StringUtils.isBlank(allowedRepetitiveAlertsStr)) {
261+
return;
262+
}
263+
String[] allowedRepetitiveAlertTypesArray = allowedRepetitiveAlertsStr.split(",");
264+
for (String allowedTypeName : allowedRepetitiveAlertTypesArray) {
265+
if (StringUtils.isBlank(allowedTypeName)) {
266+
continue;
267+
}
268+
allowedRepetitiveAlertTypeNames.add(allowedTypeName.toLowerCase());
269+
}
270+
logger.trace("{} alert types specified for repetitive alerts", allowedRepetitiveAlertTypeNames.size());
271+
}
272+
263273
@Override
264274
public boolean start() {
265275
_timer.schedule(new CapacityChecker(), INITIAL_CAPACITY_CHECK_DELAY, _capacityCheckPeriod);
@@ -850,11 +860,11 @@ public void sendAlert(AlertType alertType, DataCenter dataCenter, Pod pod, Clust
850860

851861
@Nullable
852862
private AlertVO getAlertForTrivialAlertType(AlertType alertType, long dataCenterId, Long podId, Long clusterId) {
853-
AlertVO alert = null;
854-
if (!ALERTS.contains(alertType)) {
855-
alert = _alertDao.getLastAlert(alertType.getType(), dataCenterId, podId, clusterId);
863+
if (alertType.isRepetitionAllowed() || (StringUtils.isNotBlank(alertType.getName()) &&
864+
allowedRepetitiveAlertTypeNames.contains(alertType.getName().toLowerCase()))) {
865+
return null;
856866
}
857-
return alert;
867+
return _alertDao.getLastAlert(alertType.getType(), dataCenterId, podId, clusterId);
858868
}
859869

860870
protected void sendMessage(SMTPMailProperties mailProps) {
@@ -883,7 +893,7 @@ public String getConfigComponentName() {
883893
@Override
884894
public ConfigKey<?>[] getConfigKeys() {
885895
return new ConfigKey<?>[] {CPUCapacityThreshold, MemoryCapacityThreshold, StorageAllocatedCapacityThreshold, StorageCapacityThreshold, AlertSmtpEnabledSecurityProtocols,
886-
AlertSmtpUseStartTLS, Ipv6SubnetCapacityThreshold, AlertSmtpUseAuth};
896+
AlertSmtpUseStartTLS, Ipv6SubnetCapacityThreshold, AlertSmtpUseAuth, AllowedRepetitiveAlertTypes};
887897
}
888898

889899
@Override
@@ -897,4 +907,16 @@ public boolean generateAlert(AlertType alertType, long dataCenterId, Long podId,
897907
return false;
898908
}
899909
}
910+
911+
@SuppressWarnings("unchecked")
912+
protected void initMessageBusListener() {
913+
messageBus.subscribe(EventTypes.EVENT_CONFIGURATION_VALUE_EDIT, (senderAddress, subject, args) -> {
914+
Ternary<String, ConfigKey.Scope, Long> updatedSetting = (Ternary<String, ConfigKey.Scope, Long>) args;
915+
String updatedSettingName = updatedSetting.first();
916+
if (!AllowedRepetitiveAlertTypes.key().equals(updatedSettingName)) {
917+
return;
918+
}
919+
setupRepetitiveAlertTypes();
920+
});
921+
}
900922
}

0 commit comments

Comments
 (0)