blob: 64a4adc8abef773922a980587dc392e10b4cb38d [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.ambari.server.agent.stomp.dto;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.apache.ambari.server.events.AlertDefinitionEventType;
import org.apache.ambari.server.state.alert.AlertDefinition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
@JsonInclude(JsonInclude.Include.NON_NULL)
public class AlertCluster {
private static final Logger LOG = LoggerFactory.getLogger(AlertCluster.class);
private final Map<Long, AlertDefinition> alertDefinitions;
private final String hostName;
private Integer staleIntervalMultiplier;
public AlertCluster(AlertDefinition alertDefinition, String hostName, Integer staleIntervalMultiplier) {
this(Collections.singletonMap(alertDefinition.getDefinitionId(), alertDefinition), hostName, staleIntervalMultiplier);
}
public AlertCluster(Map<Long, AlertDefinition> alertDefinitions, String hostName, Integer staleIntervalMultiplier) {
this.alertDefinitions = new HashMap<>(alertDefinitions);
this.hostName = hostName;
this.staleIntervalMultiplier = staleIntervalMultiplier;
}
public AlertCluster(AlertDefinition alertDefinition, String hostName) {
this(Collections.singletonMap(alertDefinition.getDefinitionId(), alertDefinition), hostName, null);
}
public AlertCluster(Map<Long, AlertDefinition> alertDefinitions, String hostName) {
this.alertDefinitions = new HashMap<>(alertDefinitions);
this.hostName = hostName;
this.staleIntervalMultiplier = null;
}
private AlertCluster() {
alertDefinitions = null;
hostName = null;
}
@JsonProperty("staleIntervalMultiplier")
public Integer getStaleIntervalMultiplier() {
return staleIntervalMultiplier;
}
@JsonProperty("alertDefinitions")
public Collection<AlertDefinition> getAlertDefinitions() {
return alertDefinitions == null ? Collections.emptyList() : alertDefinitions.values();
}
@JsonProperty("hostName")
public String getHostName() {
return hostName;
}
public AlertCluster handleUpdate(AlertDefinitionEventType eventType, AlertCluster update) {
boolean changed = false;
AlertCluster mergedCluster = null;
Map<Long, AlertDefinition> mergedDefinitions = new HashMap<>();
Integer mergedStaleIntervalMultiplier = null;
switch (eventType) {
case CREATE:
// FIXME should clear map first?
case UPDATE:
for (Map.Entry<Long, AlertDefinition> alertDefinitionEntry : alertDefinitions.entrySet()) {
Long definitionId = alertDefinitionEntry.getKey();
if (!update.alertDefinitions.containsKey(definitionId)) {
mergedDefinitions.put(definitionId, alertDefinitionEntry.getValue());
} else {
AlertDefinition newDefinition = update.alertDefinitions.get(definitionId);
AlertDefinition oldDefinition = alertDefinitionEntry.getValue();
if (!oldDefinition.deeplyEquals(newDefinition)) {
changed = true;
}
mergedDefinitions.put(definitionId, newDefinition);
}
}
if (addNewAlertDefinitions(update, mergedDefinitions)) {
changed = true;
}
if (update.getStaleIntervalMultiplier() != null
&& !update.getStaleIntervalMultiplier().equals(staleIntervalMultiplier)) {
mergedStaleIntervalMultiplier = update.getStaleIntervalMultiplier();
changed = true;
} else {
mergedStaleIntervalMultiplier = staleIntervalMultiplier;
}
LOG.debug("Handled {} of {} alerts, changed = {}", eventType, update.alertDefinitions.size(), changed);
break;
case DELETE:
for (Map.Entry<Long, AlertDefinition> alertDefinitionEntry : alertDefinitions.entrySet()) {
Long definitionId = alertDefinitionEntry.getKey();
if (!update.alertDefinitions.containsKey(definitionId)) {
mergedDefinitions.put(definitionId, alertDefinitionEntry.getValue());
} else {
changed = true;
}
}
mergedStaleIntervalMultiplier = staleIntervalMultiplier;
LOG.debug("Handled {} of {} alerts", eventType, update.alertDefinitions.size());
break;
default:
LOG.warn("Unhandled event type {}", eventType);
break;
}
if (changed) {
mergedCluster = new AlertCluster(mergedDefinitions, hostName, mergedStaleIntervalMultiplier);
}
return mergedCluster;
}
/**
* Add each alert definitions from the update event which are not included in mergedDefinitions
* @return true if there was such an alert definition
*/
private boolean addNewAlertDefinitions(AlertCluster update, Map<Long, AlertDefinition> mergedDefinitions) {
boolean hasNew = false;
for (Map.Entry<Long, AlertDefinition> each : update.alertDefinitions.entrySet()) {
if (!mergedDefinitions.containsKey(each.getKey())) {
mergedDefinitions.put(each.getKey(), each.getValue());
hasNew = true;
}
}
return hasNew;
}
public static AlertCluster emptyAlertCluster() {
return new AlertCluster();
}
}