Repository: ambari
Updated Branches:
  refs/heads/branch-3.0-perf 0045c04b4 -> d1a11a312


AMBARI-22734. alert_definitions topic doesn't emit any events to client. 
Additional changes. (mpapirkovskyy)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/9bda5e2d
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/9bda5e2d
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/9bda5e2d

Branch: refs/heads/branch-3.0-perf
Commit: 9bda5e2dcf7572e1b6777dc504f6de209000ec61
Parents: 0045c04
Author: Myroslav Papirkovskyi <[email protected]>
Authored: Fri Jan 5 19:54:19 2018 +0200
Committer: Myroslav Papirkovskyi <[email protected]>
Committed: Fri Jan 5 20:12:01 2018 +0200

----------------------------------------------------------------------
 .../agent/stomp/AgentCurrentDataController.java |   4 +-
 .../agent/stomp/AlertDefinitionsHolder.java     |  96 +++----------
 .../server/agent/stomp/dto/AlertCluster.java    |   4 +-
 .../configuration/spring/RootStompConfig.java   |   6 -
 .../server/events/AlertDefinitionEventType.java |  28 ++++
 .../AlertDefinitionsAgentUpdateEvent.java       | 101 ++++++++++++++
 .../events/AlertDefinitionsMessageEmitter.java  |  38 -----
 .../events/AlertDefinitionsUIUpdateEvent.java   |  74 ++++++++++
 .../events/AlertDefinitionsUpdateEvent.java     | 112 ---------------
 .../ambari/server/events/AmbariUpdateEvent.java |   3 +-
 .../server/events/DefaultMessageEmitter.java    |   2 +
 .../AlertDefinitionsUIUpdateListener.java       | 139 +++++++++++++++++++
 .../listeners/requests/StateUpdateListener.java |   8 --
 .../server/state/alert/AlertDefinition.java     |  22 +++
 .../state/alert/AlertDefinitionFactory.java     |   2 +
 15 files changed, 390 insertions(+), 249 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/9bda5e2d/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/AgentCurrentDataController.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/AgentCurrentDataController.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/AgentCurrentDataController.java
index 0a46ce1..05d5e78 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/AgentCurrentDataController.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/AgentCurrentDataController.java
@@ -21,7 +21,7 @@ import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.agent.AgentSessionManager;
 import org.apache.ambari.server.agent.stomp.dto.Hash;
 import org.apache.ambari.server.events.AgentConfigsUpdateEvent;
-import org.apache.ambari.server.events.AlertDefinitionsUpdateEvent;
+import org.apache.ambari.server.events.AlertDefinitionsAgentUpdateEvent;
 import org.apache.ambari.server.events.HostLevelParamsUpdateEvent;
 import org.apache.ambari.server.events.MetadataUpdateEvent;
 import org.apache.ambari.server.events.TopologyUpdateEvent;
@@ -65,7 +65,7 @@ public class AgentCurrentDataController {
   }
 
   @MessageMapping("/alert_definitions")
-  public AlertDefinitionsUpdateEvent getAlertDefinitions(@Header String 
simpSessionId, Hash hash) throws AmbariException {
+  public AlertDefinitionsAgentUpdateEvent getAlertDefinitions(@Header String 
simpSessionId, Hash hash) throws AmbariException {
     Long hostId = agentSessionManager.getHost(simpSessionId).getHostId();
     return alertDefinitionsHolder.getUpdateIfChanged(hash.getHash(), hostId);
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/9bda5e2d/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/AlertDefinitionsHolder.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/AlertDefinitionsHolder.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/AlertDefinitionsHolder.java
index c31f9d8..1a6f7dc 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/AlertDefinitionsHolder.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/AlertDefinitionsHolder.java
@@ -17,14 +17,11 @@
  */
 package org.apache.ambari.server.agent.stomp;
 
-import static 
org.apache.ambari.server.events.AlertDefinitionsUpdateEvent.EventType.CREATE;
-import static 
org.apache.ambari.server.events.AlertDefinitionsUpdateEvent.EventType.DELETE;
-import static 
org.apache.ambari.server.events.AlertDefinitionsUpdateEvent.EventType.UPDATE;
+import static org.apache.ambari.server.events.AlertDefinitionEventType.CREATE;
 
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
-import java.util.Set;
 import java.util.TreeMap;
 
 import javax.inject.Inject;
@@ -33,16 +30,11 @@ import javax.inject.Singleton;
 
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.agent.stomp.dto.AlertCluster;
-import org.apache.ambari.server.events.AlertDefinitionChangedEvent;
-import org.apache.ambari.server.events.AlertDefinitionDeleteEvent;
-import org.apache.ambari.server.events.AlertDefinitionRegistrationEvent;
-import org.apache.ambari.server.events.AlertDefinitionsUpdateEvent;
+import org.apache.ambari.server.events.AlertDefinitionEventType;
+import org.apache.ambari.server.events.AlertDefinitionsAgentUpdateEvent;
 import org.apache.ambari.server.events.HostsAddedEvent;
 import org.apache.ambari.server.events.HostsRemovedEvent;
-import org.apache.ambari.server.events.ServiceComponentInstalledEvent;
-import org.apache.ambari.server.events.ServiceComponentUninstalledEvent;
 import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
-import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.alert.AlertDefinition;
 import org.apache.ambari.server.state.alert.AlertDefinitionHash;
@@ -53,7 +45,7 @@ import com.google.common.collect.Sets;
 import com.google.common.eventbus.Subscribe;
 
 @Singleton
-public class AlertDefinitionsHolder extends 
AgentHostDataHolder<AlertDefinitionsUpdateEvent> {
+public class AlertDefinitionsHolder extends 
AgentHostDataHolder<AlertDefinitionsAgentUpdateEvent> {
 
   private static final Logger LOG = 
LoggerFactory.getLogger(AlertDefinitionsHolder.class);
 
@@ -69,7 +61,7 @@ public class AlertDefinitionsHolder extends 
AgentHostDataHolder<AlertDefinitions
   }
 
   @Override
-  protected AlertDefinitionsUpdateEvent getCurrentData(Long hostId) throws 
AmbariException {
+  protected AlertDefinitionsAgentUpdateEvent getCurrentData(Long hostId) 
throws AmbariException {
     Map<Long, AlertCluster> result = new TreeMap<>();
     Map<Long, Map<Long, AlertDefinition>> alertDefinitions = 
helper.get().getAlertDefinitions(hostId);
     String hostName = clusters.get().getHostById(hostId).getHostName();
@@ -81,16 +73,16 @@ public class AlertDefinitionsHolder extends 
AgentHostDataHolder<AlertDefinitions
       count += definitionMap.size();
     }
     LOG.info("Loaded {} alert definitions for {} clusters for host {}", count, 
result.size(), hostName);
-    return new AlertDefinitionsUpdateEvent(CREATE, result, hostName, hostId);
+    return new AlertDefinitionsAgentUpdateEvent(CREATE, result, hostName, 
hostId);
   }
 
   @Override
-  protected AlertDefinitionsUpdateEvent getEmptyData() {
-    return AlertDefinitionsUpdateEvent.emptyEvent();
+  protected AlertDefinitionsAgentUpdateEvent getEmptyData() {
+    return AlertDefinitionsAgentUpdateEvent.emptyEvent();
   }
 
   @Override
-  protected boolean handleUpdate(AlertDefinitionsUpdateEvent update) throws 
AmbariException {
+  protected boolean handleUpdate(AlertDefinitionsAgentUpdateEvent update) 
throws AmbariException {
     Map<Long, AlertCluster> updateClusters = update.getClusters();
     if (updateClusters.isEmpty()) {
       return false;
@@ -130,21 +122,6 @@ public class AlertDefinitionsHolder extends 
AgentHostDataHolder<AlertDefinitions
   }
 
   @Subscribe
-  public void onAlertDefinitionRegistered(AlertDefinitionRegistrationEvent 
event) throws AmbariException {
-    handleSingleDefinitionChange(UPDATE, event.getDefinition());
-  }
-
-  @Subscribe
-  public void onAlertDefinitionChanged(AlertDefinitionChangedEvent event) 
throws AmbariException {
-    handleSingleDefinitionChange(UPDATE, event.getDefinition());
-  }
-
-  @Subscribe
-  public void onAlertDefinitionDeleted(AlertDefinitionDeleteEvent event) 
throws AmbariException {
-    handleSingleDefinitionChange(DELETE, event.getDefinition());
-  }
-
-  @Subscribe
   public void onHostToClusterAssign(HostsAddedEvent hostsAddedEvent) throws 
AmbariException {
     Long clusterId = hostsAddedEvent.getClusterId();
     for (String hostName : hostsAddedEvent.getHostNames()) {
@@ -157,50 +134,13 @@ public class AlertDefinitionsHolder extends 
AgentHostDataHolder<AlertDefinitions
   }
 
   @Subscribe
-  public void onServiceComponentInstalled(ServiceComponentInstalledEvent 
event) throws AmbariException {
-    String hostName = event.getHostName();
-    String serviceName = event.getServiceName();
-    String componentName = event.getComponentName();
-    Long hostId = clusters.get().getHost(hostName).getHostId();
-
-    Map<Long, AlertDefinition> definitions = 
helper.get().findByServiceComponent(event.getClusterId(), serviceName, 
componentName);
-
-    if (event.isMasterComponent()) {
-      try {
-        Cluster cluster = clusters.get().getClusterById(event.getClusterId());
-        if 
(cluster.getService(serviceName).getServiceComponents().get(componentName).getServiceComponentHosts().containsKey(hostName))
 {
-          
definitions.putAll(helper.get().findByServiceMaster(event.getClusterId(), 
serviceName));
-        }
-      } catch (AmbariException e) {
-        String msg = String.format("Failed to get alert definitions for master 
component %s/%s", serviceName, componentName);
-        LOG.warn(msg, e);
-      }
-    }
-
-    Map<Long, AlertCluster> map = 
Collections.singletonMap(event.getClusterId(), new AlertCluster(definitions, 
hostName));
-    safelyUpdateData(new AlertDefinitionsUpdateEvent(UPDATE, map, hostName, 
hostId));
-  }
-
-  @Subscribe
-  public void onServiceComponentUninstalled(ServiceComponentUninstalledEvent 
event) throws AmbariException {
-    String hostName = event.getHostName();
-    Long hostId = clusters.get().getHost(hostName).getHostId();
-    Map<Long, AlertDefinition> definitions = 
helper.get().findByServiceComponent(event.getClusterId(), 
event.getServiceName(), event.getComponentName());
-    if (event.isMasterComponent()) {
-      
definitions.putAll(helper.get().findByServiceMaster(event.getClusterId(), 
event.getServiceName()));
-    }
-    Map<Long, AlertCluster> map = 
Collections.singletonMap(event.getClusterId(), new AlertCluster(definitions, 
hostName));
-    safelyUpdateData(new AlertDefinitionsUpdateEvent(DELETE, map, hostName, 
hostId));
-  }
-
-  @Subscribe
   public void onHostsRemoved(HostsRemovedEvent event) {
     for (String hostName : event.getHostNames()) {
       onHostRemoved(hostName);
     }
   }
 
-  private void safelyUpdateData(AlertDefinitionsUpdateEvent event) {
+  private void safelyUpdateData(AlertDefinitionsAgentUpdateEvent event) {
     try {
       updateData(event);
     } catch (AmbariException e) {
@@ -216,15 +156,11 @@ public class AlertDefinitionsHolder extends 
AgentHostDataHolder<AlertDefinitions
     }
   }
 
-  private void 
handleSingleDefinitionChange(AlertDefinitionsUpdateEvent.EventType eventType, 
AlertDefinition alertDefinition) throws AmbariException {
-    LOG.info("{} alert definition '{}'", eventType, alertDefinition);
-    Set<String> hosts = helper.get().invalidateHosts(alertDefinition);
-    for (String hostName : hosts) {
-      Long hostId = clusters.get().getHost(hostName).getHostId();
-      Map<Long, AlertCluster> update = 
Collections.singletonMap(alertDefinition.getClusterId(), new 
AlertCluster(alertDefinition, hostName));
-      AlertDefinitionsUpdateEvent event = new 
AlertDefinitionsUpdateEvent(eventType, update, hostName, hostId);
-      safelyUpdateData(event);
-    }
+  public void provideAlertDefinitionAgentUpdateEvent(AlertDefinitionEventType 
eventType, Long clusterId,
+                                                     Map<Long, 
AlertDefinition> alertDefinitions, String hostName) throws AmbariException {
+    Long hostId = clusters.get().getHost(hostName).getHostId();
+    Map<Long, AlertCluster> update = Collections.singletonMap(clusterId, new 
AlertCluster(alertDefinitions, hostName));
+    AlertDefinitionsAgentUpdateEvent event = new 
AlertDefinitionsAgentUpdateEvent(eventType, update, hostName, hostId);
+    safelyUpdateData(event);
   }
-
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/9bda5e2d/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/dto/AlertCluster.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/dto/AlertCluster.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/dto/AlertCluster.java
index 53859a6..67f3526 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/dto/AlertCluster.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/dto/AlertCluster.java
@@ -22,7 +22,7 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 
-import org.apache.ambari.server.events.AlertDefinitionsUpdateEvent;
+import org.apache.ambari.server.events.AlertDefinitionEventType;
 import org.apache.ambari.server.state.alert.AlertDefinition;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -57,7 +57,7 @@ public class AlertCluster {
     return hostName;
   }
 
-  public boolean handleUpdate(AlertDefinitionsUpdateEvent.EventType eventType, 
AlertCluster update) {
+  public boolean handleUpdate(AlertDefinitionEventType eventType, AlertCluster 
update) {
     if (update.alertDefinitions.isEmpty()) {
       return false;
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/9bda5e2d/ambari-server/src/main/java/org/apache/ambari/server/configuration/spring/RootStompConfig.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/configuration/spring/RootStompConfig.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/configuration/spring/RootStompConfig.java
index c7e720b..db074ff 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/configuration/spring/RootStompConfig.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/configuration/spring/RootStompConfig.java
@@ -25,7 +25,6 @@ import javax.servlet.ServletContext;
 import org.apache.ambari.server.agent.AgentSessionManager;
 import org.apache.ambari.server.agent.stomp.AmbariSubscriptionRegistry;
 import org.apache.ambari.server.api.AmbariSendToMethodReturnValueHandler;
-import org.apache.ambari.server.events.AlertDefinitionsMessageEmitter;
 import org.apache.ambari.server.events.DefaultMessageEmitter;
 import org.apache.ambari.server.events.listeners.requests.StateUpdateListener;
 import org.eclipse.jetty.websocket.server.WebSocketServerFactory;
@@ -74,11 +73,6 @@ public class RootStompConfig {
   }
 
   @Bean
-  public AlertDefinitionsMessageEmitter alertDefinitionsMessageSender(Injector 
injector) {
-    return new 
AlertDefinitionsMessageEmitter(injector.getInstance(AgentSessionManager.class), 
brokerTemplate);
-  }
-
-  @Bean
   public DefaultHandshakeHandler handshakeHandler() {
 
     return new DefaultHandshakeHandler(

http://git-wip-us.apache.org/repos/asf/ambari/blob/9bda5e2d/ambari-server/src/main/java/org/apache/ambari/server/events/AlertDefinitionEventType.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/events/AlertDefinitionEventType.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/events/AlertDefinitionEventType.java
new file mode 100644
index 0000000..882a3d3
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/events/AlertDefinitionEventType.java
@@ -0,0 +1,28 @@
+/*
+ * 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.events;
+
+public enum AlertDefinitionEventType {
+  /** Full current alert definitions */
+  CREATE,
+  /** Remove existing alert definition */
+  DELETE,
+  /** Update existing alert definition, or add new one */
+  UPDATE,
+  ;
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/9bda5e2d/ambari-server/src/main/java/org/apache/ambari/server/events/AlertDefinitionsAgentUpdateEvent.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/events/AlertDefinitionsAgentUpdateEvent.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/events/AlertDefinitionsAgentUpdateEvent.java
new file mode 100644
index 0000000..cd1823b
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/events/AlertDefinitionsAgentUpdateEvent.java
@@ -0,0 +1,101 @@
+/*
+ * 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.events;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+import org.apache.ambari.server.agent.stomp.dto.AlertCluster;
+import org.apache.ambari.server.agent.stomp.dto.Hashable;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Contains info about alert definitions update. This update is specific to a 
single host.
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class AlertDefinitionsAgentUpdateEvent extends AmbariHostUpdateEvent 
implements Hashable {
+
+  private final Map<Long, AlertCluster> clusters;
+  private final AlertDefinitionEventType eventType;
+  private final String hostName;
+  private final Long hostId;
+  private String hash;
+
+  public static AlertDefinitionsAgentUpdateEvent emptyEvent() {
+    return new AlertDefinitionsAgentUpdateEvent(null, null, null, null);
+  }
+
+  public AlertDefinitionsAgentUpdateEvent(AlertDefinitionEventType eventType, 
Map<Long, AlertCluster> clusters, String hostName, Long hostId) {
+    super(Type.ALERT_DEFINITIONS);
+    this.eventType = eventType;
+    this.clusters = clusters != null ? new HashMap<>(clusters) : null;
+    this.hostName = hostName;
+    this.hostId = hostId;
+  }
+
+  @Override
+  public String getHash() {
+    return hash;
+  }
+
+  @Override
+  @JsonProperty("hash")
+  public void setHash(String hash) {
+    this.hash = hash;
+  }
+
+  @JsonProperty("hostName")
+  public String getHostName() {
+    return hostName;
+  }
+
+  @JsonProperty("eventType")
+  public AlertDefinitionEventType getEventType() {
+    return eventType;
+  }
+
+  @JsonProperty("clusters")
+  public Map<Long, AlertCluster> getClusters() {
+    return clusters;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+
+    AlertDefinitionsAgentUpdateEvent other = 
(AlertDefinitionsAgentUpdateEvent) o;
+
+    return Objects.equals(eventType, other.eventType) &&
+      Objects.equals(clusters, other.clusters);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(eventType, clusters);
+  }
+
+  @Override
+  public Long getHostId() {
+    return hostId;
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/9bda5e2d/ambari-server/src/main/java/org/apache/ambari/server/events/AlertDefinitionsMessageEmitter.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/events/AlertDefinitionsMessageEmitter.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/events/AlertDefinitionsMessageEmitter.java
deleted file mode 100644
index dd270bd..0000000
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/events/AlertDefinitionsMessageEmitter.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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
- * <p/>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p/>
- * 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.events;
-
-import org.apache.ambari.server.HostNotRegisteredException;
-import org.apache.ambari.server.agent.AgentSessionManager;
-import org.springframework.messaging.simp.SimpMessagingTemplate;
-
-public class AlertDefinitionsMessageEmitter extends MessageEmitter {
-
-  private final String ALERT_DESTINATION_TO_HOST = "/alert_definitions";
-  private final String ALERT_DESTINATION_TO_API = "/events/alert_definitions";
-
-  public AlertDefinitionsMessageEmitter(AgentSessionManager 
agentSessionManager, SimpMessagingTemplate simpMessagingTemplate) {
-    super(agentSessionManager, simpMessagingTemplate);
-  }
-
-  @Override
-  public void emitMessage(AmbariUpdateEvent event) throws 
HostNotRegisteredException {
-    emitMessageToHost((AmbariHostUpdateEvent) event, 
ALERT_DESTINATION_TO_HOST);
-    emitMessageToAll(event, ALERT_DESTINATION_TO_API);
-  }
-}

http://git-wip-us.apache.org/repos/asf/ambari/blob/9bda5e2d/ambari-server/src/main/java/org/apache/ambari/server/events/AlertDefinitionsUIUpdateEvent.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/events/AlertDefinitionsUIUpdateEvent.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/events/AlertDefinitionsUIUpdateEvent.java
new file mode 100644
index 0000000..e75b3a1
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/events/AlertDefinitionsUIUpdateEvent.java
@@ -0,0 +1,74 @@
+/*
+ * 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.events;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.ambari.server.agent.stomp.dto.AlertCluster;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class AlertDefinitionsUIUpdateEvent extends AmbariUpdateEvent {
+
+  private final Map<Long, AlertCluster> clusters;
+  private final AlertDefinitionEventType eventType;
+
+  protected AlertDefinitionsUIUpdateEvent(Type type, AlertDefinitionEventType 
eventType,
+                                          Map<Long, AlertCluster> clusters) {
+    super(type);
+    this.eventType = eventType;
+    this.clusters = clusters != null ? new HashMap<>(clusters) : null;
+  }
+
+  public AlertDefinitionsUIUpdateEvent(AlertDefinitionEventType eventType,
+                                       Map<Long, AlertCluster> clusters) {
+    this(Type.UI_ALERT_DEFINITIONS, eventType, clusters);
+  }
+
+  @JsonProperty("eventType")
+  public AlertDefinitionEventType getEventType() {
+    return eventType;
+  }
+
+  @JsonProperty("clusters")
+  public Map<Long, AlertCluster> getClusters() {
+    return clusters;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+
+    AlertDefinitionsUIUpdateEvent that = (AlertDefinitionsUIUpdateEvent) o;
+
+    if (clusters != null ? !clusters.equals(that.clusters) : that.clusters != 
null) return false;
+    return eventType == that.eventType;
+  }
+
+  @Override
+  public int hashCode() {
+    int result = clusters != null ? clusters.hashCode() : 0;
+    result = 31 * result + eventType.hashCode();
+    return result;
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/9bda5e2d/ambari-server/src/main/java/org/apache/ambari/server/events/AlertDefinitionsUpdateEvent.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/events/AlertDefinitionsUpdateEvent.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/events/AlertDefinitionsUpdateEvent.java
deleted file mode 100644
index 72adcc2..0000000
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/events/AlertDefinitionsUpdateEvent.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * 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.events;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
-
-import org.apache.ambari.server.agent.stomp.dto.AlertCluster;
-import org.apache.ambari.server.agent.stomp.dto.Hashable;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-/**
- * Contains info about alert definitions update. This update is specific to a 
single host.
- */
-@JsonInclude(JsonInclude.Include.NON_NULL)
-public class AlertDefinitionsUpdateEvent extends AmbariHostUpdateEvent 
implements Hashable {
-
-  private final Map<Long, AlertCluster> clusters;
-  private final EventType eventType;
-  private final String hostName;
-  private final Long hostId;
-  private String hash;
-
-  public static AlertDefinitionsUpdateEvent emptyEvent() {
-    return new AlertDefinitionsUpdateEvent(null, null, null, null);
-  }
-
-  public AlertDefinitionsUpdateEvent(EventType eventType, Map<Long, 
AlertCluster> clusters, String hostName, Long hostId) {
-    super(Type.ALERT_DEFINITIONS);
-    this.eventType = eventType;
-    this.clusters = clusters != null ? new HashMap<>(clusters) : null;
-    this.hostName = hostName;
-    this.hostId = hostId;
-  }
-
-  @Override
-  public String getHash() {
-    return hash;
-  }
-
-  @Override
-  @JsonProperty("hash")
-  public void setHash(String hash) {
-    this.hash = hash;
-  }
-
-  @JsonProperty("hostName")
-  public String getHostName() {
-    return hostName;
-  }
-
-  @JsonProperty("eventType")
-  public EventType getEventType() {
-    return eventType;
-  }
-
-  @JsonProperty("clusters")
-  public Map<Long, AlertCluster> getClusters() {
-    return clusters;
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) return true;
-    if (o == null || getClass() != o.getClass()) return false;
-
-    AlertDefinitionsUpdateEvent other = (AlertDefinitionsUpdateEvent) o;
-
-    return Objects.equals(eventType, other.eventType) &&
-      Objects.equals(clusters, other.clusters);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(eventType, clusters);
-  }
-
-  @Override
-  public Long getHostId() {
-    return hostId;
-  }
-
-  public enum EventType {
-    /** Full current alert definitions */
-    CREATE,
-    /** Remove existing alert definition */
-    DELETE,
-    /** Update existing alert definition, or add new one */
-    UPDATE,
-    ;
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/ambari/blob/9bda5e2d/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariUpdateEvent.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariUpdateEvent.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariUpdateEvent.java
index 579f8e0..cfd910b 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariUpdateEvent.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariUpdateEvent.java
@@ -56,7 +56,8 @@ public abstract class AmbariUpdateEvent {
     REQUEST("events.requests"),
     SERVICE("events.services"),
     HOST("events.hosts"),
-    ALERT_DEFINITIONS("events.alert_definitions"),
+    UI_ALERT_DEFINITIONS("events.alert_definitions"),
+    ALERT_DEFINITIONS("alert_definitions"),
     COMMAND("events.commands");
 
     /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/9bda5e2d/ambari-server/src/main/java/org/apache/ambari/server/events/DefaultMessageEmitter.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/events/DefaultMessageEmitter.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/events/DefaultMessageEmitter.java
index 2e0b98e..3ae5955 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/events/DefaultMessageEmitter.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/events/DefaultMessageEmitter.java
@@ -41,6 +41,8 @@ public class DefaultMessageEmitter extends MessageEmitter {
         put(AmbariUpdateEvent.Type.SERVICE, "/events/services");
         put(AmbariUpdateEvent.Type.HOST, "/events/hosts");
         put(AmbariUpdateEvent.Type.COMMAND, "/commands");
+        put(AmbariUpdateEvent.Type.ALERT_DEFINITIONS, "/alert_definitions");
+        put(AmbariUpdateEvent.Type.UI_ALERT_DEFINITIONS, 
"/events/alert_definitions");
   }});
 
   public DefaultMessageEmitter(AgentSessionManager agentSessionManager, 
SimpMessagingTemplate simpMessagingTemplate) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/9bda5e2d/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertDefinitionsUIUpdateListener.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertDefinitionsUIUpdateListener.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertDefinitionsUIUpdateListener.java
new file mode 100644
index 0000000..379ec4c
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertDefinitionsUIUpdateListener.java
@@ -0,0 +1,139 @@
+/*
+ * 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.events.listeners.alerts;
+
+import static org.apache.ambari.server.events.AlertDefinitionEventType.DELETE;
+import static org.apache.ambari.server.events.AlertDefinitionEventType.UPDATE;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
+import javax.inject.Provider;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.EagerSingleton;
+import org.apache.ambari.server.agent.stomp.AlertDefinitionsHolder;
+import org.apache.ambari.server.agent.stomp.dto.AlertCluster;
+import org.apache.ambari.server.events.AlertDefinitionChangedEvent;
+import org.apache.ambari.server.events.AlertDefinitionDeleteEvent;
+import org.apache.ambari.server.events.AlertDefinitionEventType;
+import org.apache.ambari.server.events.AlertDefinitionRegistrationEvent;
+import org.apache.ambari.server.events.AlertDefinitionsUIUpdateEvent;
+import org.apache.ambari.server.events.ServiceComponentInstalledEvent;
+import org.apache.ambari.server.events.ServiceComponentUninstalledEvent;
+import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
+import org.apache.ambari.server.events.publishers.StateUpdateEventPublisher;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.alert.AlertDefinition;
+import org.apache.ambari.server.state.alert.AlertDefinitionHash;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.eventbus.Subscribe;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+@Singleton
+@EagerSingleton
+public class AlertDefinitionsUIUpdateListener {
+
+  private static final Logger LOG = 
LoggerFactory.getLogger(AlertDefinitionsUIUpdateListener.class);
+
+  @Inject
+  private Provider<AlertDefinitionHash> helper;
+
+  @Inject
+  private Provider<Clusters> clusters;
+
+  @Inject
+  private StateUpdateEventPublisher stateUpdateEventPublisher;
+
+  @Inject
+  private AlertDefinitionsHolder alertDefinitionsHolder;
+
+  @Inject
+  public AlertDefinitionsUIUpdateListener(AmbariEventPublisher 
ambariEventPublisher) {
+    ambariEventPublisher.register(this);
+  }
+
+  @Subscribe
+  public void onAlertDefinitionRegistered(AlertDefinitionRegistrationEvent 
event) throws AmbariException {
+    handleSingleDefinitionChange(UPDATE, event.getDefinition());
+  }
+
+  @Subscribe
+  public void onAlertDefinitionChanged(AlertDefinitionChangedEvent event) 
throws AmbariException {
+    handleSingleDefinitionChange(UPDATE, event.getDefinition());
+  }
+
+  @Subscribe
+  public void onAlertDefinitionDeleted(AlertDefinitionDeleteEvent event) 
throws AmbariException {
+    handleSingleDefinitionChange(DELETE, event.getDefinition());
+  }
+
+  @Subscribe
+  public void onServiceComponentInstalled(ServiceComponentInstalledEvent 
event) throws AmbariException {
+    String hostName = event.getHostName();
+    String serviceName = event.getServiceName();
+    String componentName = event.getComponentName();
+
+    Map<Long, AlertDefinition> definitions = 
helper.get().findByServiceComponent(event.getClusterId(), serviceName, 
componentName);
+
+    if (event.isMasterComponent()) {
+      try {
+        Cluster cluster = clusters.get().getClusterById(event.getClusterId());
+        if 
(cluster.getService(serviceName).getServiceComponents().get(componentName).getServiceComponentHosts().containsKey(hostName))
 {
+          
definitions.putAll(helper.get().findByServiceMaster(event.getClusterId(), 
serviceName));
+        }
+      } catch (AmbariException e) {
+        String msg = String.format("Failed to get alert definitions for master 
component %s/%s", serviceName, componentName);
+        LOG.warn(msg, e);
+      }
+    }
+
+    alertDefinitionsHolder.provideAlertDefinitionAgentUpdateEvent(UPDATE, 
event.getClusterId(), definitions, hostName);
+    Map<Long, AlertCluster> map = 
Collections.singletonMap(event.getClusterId(), new AlertCluster(definitions, 
hostName));
+    stateUpdateEventPublisher.publish(new 
AlertDefinitionsUIUpdateEvent(UPDATE, map));
+  }
+
+  @Subscribe
+  public void onServiceComponentUninstalled(ServiceComponentUninstalledEvent 
event) throws AmbariException {
+    String hostName = event.getHostName();
+    Map<Long, AlertDefinition> definitions = 
helper.get().findByServiceComponent(event.getClusterId(), 
event.getServiceName(), event.getComponentName());
+    if (event.isMasterComponent()) {
+      
definitions.putAll(helper.get().findByServiceMaster(event.getClusterId(), 
event.getServiceName()));
+    }
+    alertDefinitionsHolder.provideAlertDefinitionAgentUpdateEvent(DELETE, 
event.getClusterId(), definitions, hostName);
+    Map<Long, AlertCluster> map = 
Collections.singletonMap(event.getClusterId(), new AlertCluster(definitions, 
hostName));
+    stateUpdateEventPublisher.publish(new 
AlertDefinitionsUIUpdateEvent(DELETE, map));
+  }
+
+  private void handleSingleDefinitionChange(AlertDefinitionEventType 
eventType, AlertDefinition alertDefinition) throws AmbariException {
+    LOG.info("{} alert definition '{}'", eventType, alertDefinition);
+    Set<String> hosts = helper.get().invalidateHosts(alertDefinition);
+    for (String hostName : hosts) {
+      alertDefinitionsHolder.provideAlertDefinitionAgentUpdateEvent(eventType, 
alertDefinition.getClusterId(),
+          Collections.singletonMap(alertDefinition.getDefinitionId(), 
alertDefinition), hostName);
+    }
+    Map<Long, AlertCluster> update = 
Collections.singletonMap(alertDefinition.getClusterId(), new 
AlertCluster(alertDefinition, null));
+    AlertDefinitionsUIUpdateEvent event = new 
AlertDefinitionsUIUpdateEvent(eventType, update);
+    stateUpdateEventPublisher.publish(event);
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/9bda5e2d/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/requests/StateUpdateListener.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/requests/StateUpdateListener.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/requests/StateUpdateListener.java
index 8425d77..07e7392 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/requests/StateUpdateListener.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/requests/StateUpdateListener.java
@@ -20,8 +20,6 @@ package org.apache.ambari.server.events.listeners.requests;
 
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.agent.AgentSessionManager;
-import org.apache.ambari.server.events.AlertDefinitionsMessageEmitter;
-import org.apache.ambari.server.events.AlertDefinitionsUpdateEvent;
 import org.apache.ambari.server.events.AmbariUpdateEvent;
 import org.apache.ambari.server.events.DefaultMessageEmitter;
 import org.apache.ambari.server.events.publishers.StateUpdateEventPublisher;
@@ -37,9 +35,6 @@ public class StateUpdateListener {
   @Autowired
   private DefaultMessageEmitter defaultMessageEmitter;
 
-  @Autowired
-  private AlertDefinitionsMessageEmitter alertDefinitionsMessageEmitter;
-
   public StateUpdateListener(Injector injector) {
     StateUpdateEventPublisher stateUpdateEventPublisher =
       injector.getInstance(StateUpdateEventPublisher.class);
@@ -50,9 +45,6 @@ public class StateUpdateListener {
   @Subscribe
   @AllowConcurrentEvents
   public void onUpdateEvent(AmbariUpdateEvent event) throws AmbariException {
-    if (event instanceof AlertDefinitionsUpdateEvent) {
-      alertDefinitionsMessageEmitter.emitMessage(event);
-    }
     defaultMessageEmitter.emitMessage(event);
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/9bda5e2d/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinition.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinition.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinition.java
index a872257..8acab5b 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinition.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinition.java
@@ -61,6 +61,12 @@ public class AlertDefinition {
   @SerializedName("help_url")
   private String helpURL = null;
 
+  @JsonProperty("repeat_tolerance")
+  private int repeatTolerance;
+
+  @JsonProperty("repeat_tolerance_enabled")
+  private Boolean repeatToleranceEnabled;
+
   /**
    * Gets the cluster ID for this definition.
    *
@@ -262,6 +268,22 @@ public class AlertDefinition {
     return uuid;
   }
 
+  public int getRepeatTolerance() {
+    return repeatTolerance;
+  }
+
+  public void setRepeatTolerance(int repeatTolerance) {
+    this.repeatTolerance = repeatTolerance;
+  }
+
+  public Boolean getRepeatToleranceEnabled() {
+    return repeatToleranceEnabled;
+  }
+
+  public void setRepeatToleranceEnabled(Boolean repeatToleranceEnabled) {
+    this.repeatToleranceEnabled = repeatToleranceEnabled;
+  }
+
   /**
    * Compares {@link #equals(Object)} of every field. This is used mainly for
    * reconciling the stack versus the database.

http://git-wip-us.apache.org/repos/asf/ambari/blob/9bda5e2d/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionFactory.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionFactory.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionFactory.java
index 2e309e5..b7208f9 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionFactory.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionFactory.java
@@ -190,6 +190,8 @@ public class AlertDefinitionFactory {
     definition.setHelpURL(entity.getHelpURL());
     definition.setDescription(entity.getDescription());
     definition.setUuid(entity.getHash());
+    definition.setRepeatTolerance(entity.getRepeatTolerance());
+    definition.setRepeatToleranceEnabled(entity.isRepeatToleranceEnabled());
 
     try{
       String sourceJson = entity.getSource();

Reply via email to