You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by jo...@apache.org on 2014/11/28 14:08:18 UTC
[2/2] ambari git commit: AMBARI-8460 - Alerts: AlertDefinition and
AlertGroup Automatic Creation On Startup (jonathanhurley)
AMBARI-8460 - Alerts: AlertDefinition and AlertGroup Automatic Creation On Startup (jonathanhurley)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/9159421b
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/9159421b
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/9159421b
Branch: refs/heads/trunk
Commit: 9159421b39c4ef677a0bdc9445afe2ca2bd545ee
Parents: 378cf13
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Wed Nov 26 15:32:04 2014 -0500
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Fri Nov 28 08:04:39 2014 -0500
----------------------------------------------------------------------
.../ambari/server/events/AmbariEvent.java | 5 +
.../ambari/server/events/HostAddedEvent.java | 51 ++++
.../server/events/HostRegisteredEvent.java | 44 +++
.../ambari/server/events/HostRemovedEvent.java | 2 +-
.../alerts/AlertHashInvalidationListener.java | 3 +-
.../listeners/alerts/AlertHostListener.java | 119 +++++++-
.../alerts/AlertServiceStateListener.java | 12 +-
.../server/orm/dao/AlertDefinitionDAO.java | 31 ++-
.../ambari/server/orm/dao/AlertDispatchDAO.java | 77 +++++-
.../apache/ambari/server/orm/dao/AlertsDAO.java | 3 +-
.../server/orm/dao/ClusterServiceDAO.java | 21 +-
.../dao/ServiceComponentDesiredStateDAO.java | 21 +-
.../orm/entities/AlertDefinitionEntity.java | 18 ++
.../server/orm/entities/AlertGroupEntity.java | 17 +-
.../server/orm/entities/AlertHistoryEntity.java | 17 ++
.../server/orm/entities/AlertTargetEntity.java | 13 +
.../server/state/alert/AlertDefinitionHash.java | 66 +++--
.../server/state/cluster/ClustersImpl.java | 15 +-
.../apache/ambari/server/orm/OrmTestHelper.java | 146 +++++++++-
.../server/orm/dao/AlertDispatchDAOTest.java | 276 ++++++++++++-------
.../ambari/server/orm/dao/AlertsDAOTest.java | 259 +++++++----------
.../state/alerts/AlertReceivedListenerTest.java | 194 ++++++-------
.../state/cluster/AlertDataManagerTest.java | 185 ++++++++-----
23 files changed, 1043 insertions(+), 552 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/9159421b/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariEvent.java
index de9b6dc..e708473 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariEvent.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariEvent.java
@@ -68,6 +68,11 @@ public abstract class AmbariEvent {
ALERT_DEFINITION_DISABLED,
/**
+ * A host was registered with the server.
+ */
+ HOST_REGISTERED,
+
+ /**
* A host was added to the cluster.
*/
HOST_ADDED,
http://git-wip-us.apache.org/repos/asf/ambari/blob/9159421b/ambari-server/src/main/java/org/apache/ambari/server/events/HostAddedEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/HostAddedEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/HostAddedEvent.java
new file mode 100644
index 0000000..7832c16
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/HostAddedEvent.java
@@ -0,0 +1,51 @@
+/**
+ * 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;
+
+/**
+ * The {@link HostAddedEvent} is fired when a host is added to a cluster.
+ */
+public class HostAddedEvent extends ClusterEvent {
+
+ /**
+ * The host's name.
+ */
+ protected final String m_hostName;
+
+ /**
+ * Constructor.
+ *
+ * @param clusterId
+ * the ID of the cluster.
+ * @param hostName
+ * the name of the host.
+ */
+ public HostAddedEvent(long clusterId, String hostName) {
+ super(AmbariEventType.HOST_ADDED, clusterId);
+ m_hostName = hostName;
+ }
+
+ /**
+ * Gets the host's name that the event belongs to.
+ *
+ * @return the hostName
+ */
+ public String getHostName() {
+ return m_hostName;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/9159421b/ambari-server/src/main/java/org/apache/ambari/server/events/HostRegisteredEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/HostRegisteredEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/HostRegisteredEvent.java
new file mode 100644
index 0000000..07ff526
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/HostRegisteredEvent.java
@@ -0,0 +1,44 @@
+/**
+ * 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;
+
+/**
+ * The {@link HostRegisteredEvent} class is fired when a host registered with
+ * the server.
+ */
+public class HostRegisteredEvent extends HostEvent {
+ /**
+ * Constructor.
+ *
+ * @param hostName
+ */
+ public HostRegisteredEvent(String hostName) {
+ super(AmbariEventType.HOST_REGISTERED, hostName);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ StringBuilder buffer = new StringBuilder("HostRegistered{ ");
+ buffer.append("hostName=").append(m_hostName);
+ buffer.append("}");
+ return buffer.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/9159421b/ambari-server/src/main/java/org/apache/ambari/server/events/HostRemovedEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/HostRemovedEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/HostRemovedEvent.java
index a0aae66..e005754 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/HostRemovedEvent.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/HostRemovedEvent.java
@@ -28,7 +28,7 @@ public class HostRemovedEvent extends HostEvent {
* @param hostName
*/
public HostRemovedEvent(String hostName) {
- super(AmbariEventType.HOST_ADDED, hostName);
+ super(AmbariEventType.HOST_REMOVED, hostName);
}
/**
http://git-wip-us.apache.org/repos/asf/ambari/blob/9159421b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertHashInvalidationListener.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertHashInvalidationListener.java b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertHashInvalidationListener.java
index 0accaf9..655352f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertHashInvalidationListener.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertHashInvalidationListener.java
@@ -91,7 +91,8 @@ public class AlertHashInvalidationListener {
return;
}
- m_alertDefinitionHash.get().enqueueAgentCommands(clusterId, hosts);
+ AlertDefinitionHash hash = m_alertDefinitionHash.get();
+ hash.enqueueAgentCommands(clusterId, hosts);
}
/**
http://git-wip-us.apache.org/repos/asf/ambari/blob/9159421b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertHostListener.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertHostListener.java b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertHostListener.java
index 51e5e67..d478bf5 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertHostListener.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertHostListener.java
@@ -17,13 +17,26 @@
*/
package org.apache.ambari.server.events.listeners.alerts;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.EagerSingleton;
+import org.apache.ambari.server.events.AlertHashInvalidationEvent;
+import org.apache.ambari.server.events.HostAddedEvent;
import org.apache.ambari.server.events.HostRemovedEvent;
import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
+import org.apache.ambari.server.metadata.AgentAlertDefinitions;
+import org.apache.ambari.server.orm.dao.AlertDefinitionDAO;
import org.apache.ambari.server.orm.dao.AlertsDAO;
import org.apache.ambari.server.orm.entities.AlertCurrentEntity;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
+import org.apache.ambari.server.state.alert.AlertDefinition;
+import org.apache.ambari.server.state.alert.AlertDefinitionFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.google.common.eventbus.AllowConcurrentEvents;
import com.google.common.eventbus.Subscribe;
@@ -31,8 +44,9 @@ import com.google.inject.Inject;
import com.google.inject.Singleton;
/**
- * The {@link AlertHostListener} class handles {@link HostRemovedEvent} and
- * ensures that {@link AlertCurrentEntity} instances are properly cleaned up
+ * The {@link AlertHostListener} class handles {@link HostAddedEvent} and
+ * {@link HostRemovedEvent} and ensures that {@link AlertCurrentEntity}
+ * instances are properly cleaned up
*/
@Singleton
@EagerSingleton
@@ -40,7 +54,7 @@ public class AlertHostListener {
/**
* Logger.
*/
- private static Log LOG = LogFactory.getLog(AlertHostListener.class);
+ private final static Logger LOG = LoggerFactory.getLogger(AlertHostListener.class);
/**
* Used for removing current alerts when a service is removed.
@@ -49,6 +63,37 @@ public class AlertHostListener {
private AlertsDAO m_alertsDao;
/**
+ * Used for checking to see if definitions already exist for a cluster.
+ */
+ @Inject
+ private AlertDefinitionDAO m_alertDefinitionDao;
+
+ /**
+ * Used to publish events when an alert definition has a lifecycle event.
+ */
+ @Inject
+ private AmbariEventPublisher m_eventPublisher;
+
+ /**
+ * All of the {@link AlertDefinition}s that are scoped for the agents.
+ */
+ @Inject
+ private AgentAlertDefinitions m_agentAlertDefinitions;
+
+ /**
+ * Used when a host is added to a cluster to coerce an {@link AlertDefinition}
+ * into an {@link AlertDefinitionEntity}.
+ */
+ @Inject
+ private AlertDefinitionFactory m_alertDefinitionFactory;
+
+ /**
+ * Used to prevent multiple threads from trying to create host alerts
+ * simultaneously.
+ */
+ private Lock m_hostAlertLock = new ReentrantLock();
+
+ /**
* Constructor.
*
* @param publisher
@@ -59,15 +104,69 @@ public class AlertHostListener {
}
/**
- * Removes any current alerts associated with the specified host.
- *
- * @param event
- * the published event being handled (not {@code null}).
+ * Handles the {@link HostAddedEvent} by performing the following actions:
+ * <ul>
+ * <li>Ensures that all host-level alerts are loaded for the cluster. This is
+ * especially useful when creating a cluster and no alerts were loaded on
+ * Ambari startup</li>
+ * <li>Broadcasts the {@link AlertHashInvalidationEvent} in order to push host
+ * alert definitions</li>
+ * </ul>
+ */
+ @Subscribe
+ @AllowConcurrentEvents
+ public void onAmbariEvent(HostAddedEvent event) {
+ LOG.debug("Received event {}", event);
+
+ long clusterId = event.getClusterId();
+
+ // load the host-only alert definitions
+ List<AlertDefinition> agentDefinitions = m_agentAlertDefinitions.getDefinitions();
+
+ // lock to prevent multiple threads from trying to create alert
+ // definitions at the same time
+ m_hostAlertLock.lock();
+
+ try {
+ for (AlertDefinition agentDefinition : agentDefinitions) {
+ AlertDefinitionEntity definition = m_alertDefinitionDao.findByName(
+ clusterId, agentDefinition.getName());
+
+ // this host definition does not exist, add it
+ if (null == definition) {
+ definition = m_alertDefinitionFactory.coerce(clusterId,
+ agentDefinition);
+
+ try {
+ m_alertDefinitionDao.create(definition);
+ } catch (AmbariException ambariException) {
+ LOG.error(
+ "Unable to create a host alert definition name {} in cluster {}",
+ definition.getDefinitionName(), definition.getClusterId(),
+ ambariException);
+ }
+ }
+ }
+ } finally {
+ m_hostAlertLock.unlock();
+ }
+
+ AlertHashInvalidationEvent invalidationEvent = new AlertHashInvalidationEvent(
+ event.getClusterId(), Collections.singletonList(event.getHostName()));
+
+ m_eventPublisher.publish(invalidationEvent);
+ }
+
+ /**
+ * Handles the {@link HostRemovedEvent} by performing the following actions:
+ * <ul>
+ * <li>Removes all {@link AlertCurrentEntity} for the removed host</li>
+ * </ul>
*/
@Subscribe
@AllowConcurrentEvents
public void onAmbariEvent(HostRemovedEvent event) {
- LOG.debug(event);
+ LOG.debug("Received event {}", event);
// remove any current alerts for the removed host
m_alertsDao.removeCurrentByHost(event.getHostName());
http://git-wip-us.apache.org/repos/asf/ambari/blob/9159421b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertServiceStateListener.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertServiceStateListener.java b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertServiceStateListener.java
index b56f23d..fd7035d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertServiceStateListener.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertServiceStateListener.java
@@ -126,13 +126,11 @@ public class AlertServiceStateListener {
// create the default alert group for the new service; this MUST be done
// before adding definitions so that they are properly added to the
// default group
- AlertGroupEntity serviceAlertGroup = new AlertGroupEntity();
- serviceAlertGroup.setClusterId(clusterId);
- serviceAlertGroup.setDefault(true);
- serviceAlertGroup.setGroupName(serviceName);
- serviceAlertGroup.setServiceName(serviceName);
-
- m_alertDispatchDao.create(serviceAlertGroup);
+ try {
+ m_alertDispatchDao.createDefaultGroup(clusterId, serviceName);
+ } catch (AmbariException ambariException) {
+ LOG.error(ambariException);
+ }
// populate alert definitions for the new service from the database, but
// don't worry about sending down commands to the agents; the host
http://git-wip-us.apache.org/repos/asf/ambari/blob/9159421b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java
index 8e8c808..23de17e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java
@@ -24,6 +24,7 @@ import java.util.Set;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
+import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.controller.RootServiceResponseFactory;
import org.apache.ambari.server.events.AlertDefinitionDeleteEvent;
import org.apache.ambari.server.events.AlertDefinitionRegistrationEvent;
@@ -56,25 +57,25 @@ public class AlertDefinitionDAO {
* JPA entity manager
*/
@Inject
- Provider<EntityManager> entityManagerProvider;
+ private Provider<EntityManager> entityManagerProvider;
/**
* DAO utilities for dealing mostly with {@link TypedQuery} results.
*/
@Inject
- DaoUtils daoUtils;
+ private DaoUtils daoUtils;
/**
* Alert history DAO.
*/
@Inject
- AlertsDAO alertsDao;
+ private AlertsDAO alertsDao;
/**
* Alert dispatch DAO.
*/
@Inject
- AlertDispatchDAO dispatchDao;
+ private AlertDispatchDAO dispatchDao;
/**
* Publishes the following events:
@@ -284,16 +285,25 @@ public class AlertDefinitionDAO {
* the definition to persist (not {@code null}).
*/
@Transactional
- public void create(AlertDefinitionEntity alertDefinition) {
+ public void create(AlertDefinitionEntity alertDefinition)
+ throws AmbariException {
entityManagerProvider.get().persist(alertDefinition);
- AlertGroupEntity group = dispatchDao.findDefaultServiceGroup(alertDefinition.getServiceName());
+ AlertGroupEntity group = dispatchDao.findDefaultServiceGroup(
+ alertDefinition.getClusterId(), alertDefinition.getServiceName());
- if (null != group) {
- group.addAlertDefinition(alertDefinition);
- dispatchDao.merge(group);
+ if (null == group) {
+ // create the default alert group for the new service; this MUST be done
+ // before adding definitions so that they are properly added to the
+ // default group
+ String serviceName = alertDefinition.getServiceName();
+ group = dispatchDao.createDefaultGroup(alertDefinition.getClusterId(),
+ serviceName);
}
+ group.addAlertDefinition(alertDefinition);
+ dispatchDao.merge(group);
+
// publish the alert definition registration
AlertDefinition coerced = alertDefinitionFactory.coerce(alertDefinition);
if (null != coerced) {
@@ -339,7 +349,8 @@ public class AlertDefinitionDAO {
* @param alertDefinition
* the definition to create or update (not {@code null}).
*/
- public void createOrUpdate(AlertDefinitionEntity alertDefinition) {
+ public void createOrUpdate(AlertDefinitionEntity alertDefinition)
+ throws AmbariException {
if (null == alertDefinition.getDefinitionId()) {
create(alertDefinition);
} else {
http://git-wip-us.apache.org/repos/asf/ambari/blob/9159421b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDispatchDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDispatchDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDispatchDAO.java
index b6c1e90..3a3ad15 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDispatchDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDispatchDAO.java
@@ -17,7 +17,11 @@
*/
package org.apache.ambari.server.orm.dao;
+import java.text.MessageFormat;
import java.util.List;
+import java.util.Map;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
@@ -25,9 +29,11 @@ import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Order;
import javax.persistence.metamodel.SingularAttribute;
+import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.api.query.JpaPredicateVisitor;
import org.apache.ambari.server.api.query.JpaSortBuilder;
import org.apache.ambari.server.controller.AlertNoticeRequest;
+import org.apache.ambari.server.controller.RootServiceResponseFactory.Services;
import org.apache.ambari.server.controller.spi.Predicate;
import org.apache.ambari.server.controller.utilities.PredicateHelper;
import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
@@ -35,7 +41,10 @@ import org.apache.ambari.server.orm.entities.AlertGroupEntity;
import org.apache.ambari.server.orm.entities.AlertNoticeEntity;
import org.apache.ambari.server.orm.entities.AlertNoticeEntity_;
import org.apache.ambari.server.orm.entities.AlertTargetEntity;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Clusters;
import org.apache.ambari.server.state.NotificationState;
+import org.apache.ambari.server.state.Service;
import org.apache.ambari.server.state.alert.AlertGroup;
import com.google.inject.Inject;
@@ -53,13 +62,26 @@ public class AlertDispatchDAO {
* JPA entity manager
*/
@Inject
- Provider<EntityManager> entityManagerProvider;
+ private Provider<EntityManager> entityManagerProvider;
/**
* DAO utilities for dealing mostly with {@link TypedQuery} results.
*/
@Inject
- DaoUtils daoUtils;
+ private DaoUtils daoUtils;
+
+ /**
+ * Used to retrieve a cluster and its services when creating a default
+ * {@link AlertGroupEntity} for a service.
+ */
+ @Inject
+ private Provider<Clusters> m_clusters;
+
+ /**
+ * A lock that ensures that group writes are protected. This is useful since
+ * groups can be created through different events/threads in the system.
+ */
+ private final Lock m_groupLock = new ReentrantLock();
/**
* Gets an alert group with the specified ID.
@@ -256,18 +278,22 @@ public class AlertDispatchDAO {
}
/**
- * Gets the default group for the specified service.
+ * Gets the default group for the specified cluster and service.
*
+ * @param clusterId
+ * the cluster that the group belongs to
* @param serviceName
* the name of the service (not {@code null}).
* @return the default group, or {@code null} if the service name is not valid
* for an installed service; otherwise {@code null} should not be
* possible.
*/
- public AlertGroupEntity findDefaultServiceGroup(String serviceName) {
+ public AlertGroupEntity findDefaultServiceGroup(long clusterId,
+ String serviceName) {
TypedQuery<AlertGroupEntity> query = entityManagerProvider.get().createNamedQuery(
"AlertGroupEntity.findServiceDefaultGroup", AlertGroupEntity.class);
+ query.setParameter("clusterId", clusterId);
query.setParameter("serviceName", serviceName);
return daoUtils.selectSingle(query);
}
@@ -364,6 +390,49 @@ public class AlertDispatchDAO {
}
/**
+ * Creates a default group in the specified cluster and service. If the
+ * service is not valid, then this will throw an {@link AmbariException}.
+ *
+ * @param clusterId
+ * the cluster that the group is in.
+ * @param serviceName
+ * the name of the group which is also the service name.
+ */
+ public AlertGroupEntity createDefaultGroup(long clusterId, String serviceName)
+ throws AmbariException {
+ // AMBARI is a special service that we let through, otherwise we need to
+ // verify that the service exists before we create the default group
+ String ambariServiceName = Services.AMBARI.name();
+ if (!ambariServiceName.equals(serviceName)) {
+ Cluster cluster = m_clusters.get().getClusterById(clusterId);
+ Map<String, Service> services = cluster.getServices();
+
+ if (!services.containsKey(serviceName)) {
+ String message = MessageFormat.format(
+ "Unable to create a default alert group for unknown service {0} in cluster {1}",
+ serviceName, cluster.getClusterName());
+ throw new AmbariException(message);
+ }
+ }
+
+ AlertGroupEntity group = new AlertGroupEntity();
+
+ m_groupLock.lock();
+ try {
+ group.setClusterId(clusterId);
+ group.setDefault(true);
+ group.setGroupName(serviceName);
+ group.setServiceName(serviceName);
+
+ create(group);
+ } finally {
+ m_groupLock.unlock();
+ }
+
+ return group;
+ }
+
+ /**
* Refresh the state of the alert group from the database.
*
* @param alertGroup
http://git-wip-us.apache.org/repos/asf/ambari/blob/9159421b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java
index 1127dd1..4908eea 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java
@@ -503,8 +503,7 @@ public class AlertsDAO {
*/
@Transactional
public int removeCurrentByServiceComponentHost(String serviceName,
- String componentName,
- String hostName) {
+ String componentName, String hostName) {
TypedQuery<AlertCurrentEntity> query = entityManagerProvider.get().createNamedQuery(
"AlertCurrentEntity.removeByHostComponent", AlertCurrentEntity.class);
http://git-wip-us.apache.org/repos/asf/ambari/blob/9159421b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterServiceDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterServiceDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterServiceDAO.java
index dcad56e..1306c6c 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterServiceDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterServiceDAO.java
@@ -18,18 +18,20 @@
package org.apache.ambari.server.orm.dao;
-import com.google.inject.Inject;
-import com.google.inject.Provider;
-import com.google.inject.Singleton;
-import com.google.inject.persist.Transactional;
-import org.apache.ambari.server.orm.RequiresSession;
-import org.apache.ambari.server.orm.entities.ClusterServiceEntity;
-import org.apache.ambari.server.orm.entities.ClusterServiceEntityPK;
+import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.TypedQuery;
-import java.util.List;
+
+import org.apache.ambari.server.orm.RequiresSession;
+import org.apache.ambari.server.orm.entities.ClusterServiceEntity;
+import org.apache.ambari.server.orm.entities.ClusterServiceEntityPK;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
+import com.google.inject.persist.Transactional;
@Singleton
public class ClusterServiceDAO {
@@ -84,7 +86,8 @@ public class ClusterServiceDAO {
@Transactional
public void removeByPK(ClusterServiceEntityPK clusterServiceEntityPK) {
- remove(findByPK(clusterServiceEntityPK));
+ ClusterServiceEntity entity = findByPK(clusterServiceEntityPK);
+ entityManagerProvider.get().remove(entity);
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/9159421b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ServiceComponentDesiredStateDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ServiceComponentDesiredStateDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ServiceComponentDesiredStateDAO.java
index 8cf7ec3..341d1fd 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ServiceComponentDesiredStateDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ServiceComponentDesiredStateDAO.java
@@ -18,18 +18,20 @@
package org.apache.ambari.server.orm.dao;
-import com.google.inject.Inject;
-import com.google.inject.Provider;
-import com.google.inject.Singleton;
-import com.google.inject.persist.Transactional;
-import org.apache.ambari.server.orm.RequiresSession;
-import org.apache.ambari.server.orm.entities.ServiceComponentDesiredStateEntityPK;
-import org.apache.ambari.server.orm.entities.ServiceComponentDesiredStateEntity;
+import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.TypedQuery;
-import java.util.List;
+
+import org.apache.ambari.server.orm.RequiresSession;
+import org.apache.ambari.server.orm.entities.ServiceComponentDesiredStateEntity;
+import org.apache.ambari.server.orm.entities.ServiceComponentDesiredStateEntityPK;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
+import com.google.inject.persist.Transactional;
@Singleton
public class ServiceComponentDesiredStateDAO {
@@ -75,6 +77,7 @@ public class ServiceComponentDesiredStateDAO {
@Transactional
public void removeByPK(ServiceComponentDesiredStateEntityPK primaryKey) {
- remove(findByPK(primaryKey));
+ ServiceComponentDesiredStateEntity entity = findByPK(primaryKey);
+ entityManagerProvider.get().remove(entity);
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/9159421b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertDefinitionEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertDefinitionEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertDefinitionEntity.java
index a330c90..81fb133 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertDefinitionEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertDefinitionEntity.java
@@ -536,4 +536,22 @@ public class AlertDefinitionEntity {
int result = null != definitionId ? definitionId.hashCode() : 0;
return result;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ StringBuilder buffer = new StringBuilder();
+ buffer.append(getClass().getSimpleName());
+ buffer.append("{");
+ buffer.append("id=").append(definitionId);
+ buffer.append(", name=").append(definitionName);
+ buffer.append(", serviceName=").append(serviceName);
+ buffer.append(", componentName=").append(componentName);
+ buffer.append(", enabled=").append(enabled);
+ buffer.append(", hash=").append(hash);
+ buffer.append("}");
+ return buffer.toString();
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/9159421b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertGroupEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertGroupEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertGroupEntity.java
index ac3586d..6607fb0 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertGroupEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertGroupEntity.java
@@ -51,7 +51,7 @@ import javax.persistence.UniqueConstraint;
@NamedQuery(name = "AlertGroupEntity.findByName", query = "SELECT alertGroup FROM AlertGroupEntity alertGroup WHERE alertGroup.groupName = :groupName"),
@NamedQuery(name = "AlertGroupEntity.findByNameInCluster", query = "SELECT alertGroup FROM AlertGroupEntity alertGroup WHERE alertGroup.groupName = :groupName AND alertGroup.clusterId = :clusterId"),
@NamedQuery(name = "AlertGroupEntity.findByAssociatedDefinition", query = "SELECT alertGroup FROM AlertGroupEntity alertGroup WHERE :alertDefinition MEMBER OF alertGroup.alertDefinitions"),
- @NamedQuery(name = "AlertGroupEntity.findServiceDefaultGroup", query = "SELECT alertGroup FROM AlertGroupEntity alertGroup WHERE alertGroup.serviceName = :serviceName AND alertGroup.isDefault = 1") })
+ @NamedQuery(name = "AlertGroupEntity.findServiceDefaultGroup", query = "SELECT alertGroup FROM AlertGroupEntity alertGroup WHERE alertGroup.clusterId = :clusterId AND alertGroup.serviceName = :serviceName AND alertGroup.isDefault = 1") })
public class AlertGroupEntity {
@Id
@@ -353,4 +353,19 @@ public class AlertGroupEntity {
int result = null != groupId ? groupId.hashCode() : 0;
return result;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ StringBuilder buffer = new StringBuilder();
+ buffer.append(getClass().getSimpleName());
+ buffer.append("{");
+ buffer.append("id=").append(groupId);
+ buffer.append(", name=").append(groupName);
+ buffer.append(", default=").append(isDefault);
+ buffer.append("}");
+ return buffer.toString();
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/9159421b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertHistoryEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertHistoryEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertHistoryEntity.java
index a671ae1..8e96aca 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertHistoryEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertHistoryEntity.java
@@ -355,4 +355,21 @@ public class AlertHistoryEntity {
return result;
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ StringBuilder buffer = new StringBuilder();
+ buffer.append(getClass().getSimpleName());
+ buffer.append("{");
+ buffer.append("id=").append(alertId);
+ buffer.append(", serviceName=").append(serviceName);
+ buffer.append(", componentName=").append(componentName);
+ buffer.append(", state=").append(alertState);
+ buffer.append(", label=").append(alertLabel);
+ buffer.append("}");
+ return buffer.toString();
+ }
+
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/9159421b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertTargetEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertTargetEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertTargetEntity.java
index d18ec68..9f24dc3 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertTargetEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertTargetEntity.java
@@ -295,4 +295,17 @@ public class AlertTargetEntity {
return result;
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ StringBuilder buffer = new StringBuilder();
+ buffer.append(getClass().getSimpleName());
+ buffer.append("{");
+ buffer.append("id=").append(targetId);
+ buffer.append(", name=").append(targetName);
+ buffer.append("}");
+ return buffer.toString();
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/9159421b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionHash.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionHash.java b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionHash.java
index abffa5d..c8b78a0 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionHash.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionHash.java
@@ -584,8 +584,8 @@ public class AlertDefinitionHash {
* {@code null}).
*/
private Set<AlertDefinitionEntity> getAlertDefinitionEntities(
- String clusterName,
- String hostName) {
+ String clusterName, String hostName) {
+
Set<AlertDefinitionEntity> definitions = new HashSet<AlertDefinitionEntity>();
try {
@@ -598,45 +598,41 @@ public class AlertDefinitionHash {
}
long clusterId = cluster.getClusterId();
- List<ServiceComponentHost> serviceComponents = cluster.getServiceComponentHosts(hostName);
- if (null == serviceComponents || serviceComponents.size() == 0) {
- LOG.warn(
- "Unable to get alert definitions for {} since there are no service components defined",
- hostName);
-
- return Collections.emptySet();
- }
-
- for (ServiceComponentHost serviceComponent : serviceComponents) {
- String serviceName = serviceComponent.getServiceName();
- String componentName = serviceComponent.getServiceComponentName();
- // add all alerts for this service/component pair
- definitions.addAll(m_definitionDao.findByServiceComponent(
- clusterId, serviceName, componentName));
- }
+ // services and components
+ List<ServiceComponentHost> serviceComponents = cluster.getServiceComponentHosts(hostName);
+ if (null == serviceComponents || !serviceComponents.isEmpty()) {
+ for (ServiceComponentHost serviceComponent : serviceComponents) {
+ String serviceName = serviceComponent.getServiceName();
+ String componentName = serviceComponent.getServiceComponentName();
+
+ // add all alerts for this service/component pair
+ definitions.addAll(m_definitionDao.findByServiceComponent(clusterId,
+ serviceName, componentName));
+ }
- // for every service, get the master components and see if the host
- // is a master
- Set<String> services = new HashSet<String>();
- for (Entry<String, Service> entry : cluster.getServices().entrySet()) {
- Service service = entry.getValue();
- Map<String, ServiceComponent> components = service.getServiceComponents();
- for (Entry<String, ServiceComponent> component : components.entrySet()) {
- if (component.getValue().isMasterComponent()) {
- Map<String, ServiceComponentHost> hosts = component.getValue().getServiceComponentHosts();
-
- if( hosts.containsKey( hostName ) ){
- services.add(service.getName());
+ // for every service, get the master components and see if the host
+ // is a master
+ Set<String> services = new HashSet<String>();
+ for (Entry<String, Service> entry : cluster.getServices().entrySet()) {
+ Service service = entry.getValue();
+ Map<String, ServiceComponent> components = service.getServiceComponents();
+ for (Entry<String, ServiceComponent> component : components.entrySet()) {
+ if (component.getValue().isMasterComponent()) {
+ Map<String, ServiceComponentHost> hosts = component.getValue().getServiceComponentHosts();
+
+ if (hosts.containsKey(hostName)) {
+ services.add(service.getName());
+ }
}
}
}
- }
- // add all service scoped alerts
- if( services.size() > 0 ){
- definitions.addAll(m_definitionDao.findByServiceMaster(clusterId,
- services));
+ // add all service scoped alerts
+ if (services.size() > 0) {
+ definitions.addAll(m_definitionDao.findByServiceMaster(clusterId,
+ services));
+ }
}
// add any alerts not bound to a service (host level alerts)
http://git-wip-us.apache.org/repos/asf/ambari/blob/9159421b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClustersImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClustersImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClustersImpl.java
index 991d289..d2c7428 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClustersImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClustersImpl.java
@@ -39,11 +39,12 @@ import org.apache.ambari.server.HostNotFoundException;
import org.apache.ambari.server.agent.DiskInfo;
import org.apache.ambari.server.api.services.AmbariMetaInfo;
import org.apache.ambari.server.configuration.Configuration;
+import org.apache.ambari.server.events.HostAddedEvent;
+import org.apache.ambari.server.events.HostRegisteredEvent;
import org.apache.ambari.server.events.HostRemovedEvent;
import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
import org.apache.ambari.server.orm.dao.ClusterDAO;
import org.apache.ambari.server.orm.dao.ClusterVersionDAO;
-import org.apache.ambari.server.orm.dao.ConfigGroupHostMappingDAO;
import org.apache.ambari.server.orm.dao.HostDAO;
import org.apache.ambari.server.orm.dao.HostVersionDAO;
import org.apache.ambari.server.orm.dao.ResourceDAO;
@@ -121,8 +122,6 @@ public class ClustersImpl implements Clusters {
@Inject
Gson gson;
@Inject
- private ConfigGroupHostMappingDAO configGroupHostMappingDAO;
- @Inject
private SecurityHelper securityHelper;
/**
@@ -341,12 +340,14 @@ public class ClustersImpl implements Clusters {
@Override
public void addHost(String hostname) throws AmbariException {
checkLoaded();
+
String duplicateMessage = "Duplicate entry for Host"
+ ", hostName= " + hostname;
if (hosts.containsKey(hostname)) {
throw new AmbariException(duplicateMessage);
}
+
r.lock();
try {
@@ -371,6 +372,10 @@ public class ClustersImpl implements Clusters {
} finally {
r.unlock();
}
+
+ // publish the event
+ HostRegisteredEvent event = new HostRegisteredEvent(hostname);
+ eventPublisher.publish(event);
}
private boolean isOsSupportedByClusterStack(Cluster c, Host h) throws AmbariException {
@@ -558,6 +563,10 @@ public class ClustersImpl implements Clusters {
clusterDAO.merge(clusterEntity);
hostDAO.merge(hostEntity);
+
+ // publish the event for adding a host to a cluster
+ HostAddedEvent event = new HostAddedEvent(clusterId, hostName);
+ eventPublisher.publish(event);
}
@Override
http://git-wip-us.apache.org/repos/asf/ambari/blob/9159421b/ambari-server/src/test/java/org/apache/ambari/server/orm/OrmTestHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/OrmTestHelper.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/OrmTestHelper.java
index dc71862..0c93ec2 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/OrmTestHelper.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/OrmTestHelper.java
@@ -20,12 +20,15 @@ package org.apache.ambari.server.orm;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import java.util.UUID;
@@ -59,11 +62,22 @@ import org.apache.ambari.server.orm.entities.ResourceEntity;
import org.apache.ambari.server.orm.entities.ResourceTypeEntity;
import org.apache.ambari.server.orm.entities.StageEntity;
import org.apache.ambari.server.orm.entities.UserEntity;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.Host;
import org.apache.ambari.server.state.HostState;
+import org.apache.ambari.server.state.RepositoryVersionState;
+import org.apache.ambari.server.state.Service;
+import org.apache.ambari.server.state.ServiceComponent;
+import org.apache.ambari.server.state.ServiceComponentFactory;
+import org.apache.ambari.server.state.ServiceComponentHost;
+import org.apache.ambari.server.state.ServiceComponentHostFactory;
+import org.apache.ambari.server.state.ServiceFactory;
+import org.apache.ambari.server.state.StackId;
+import org.apache.ambari.server.state.State;
import org.apache.ambari.server.state.alert.Scope;
import org.apache.ambari.server.state.alert.SourceType;
import org.springframework.security.crypto.password.PasswordEncoder;
-import org.springframework.util.Assert;
import com.google.inject.Inject;
import com.google.inject.Injector;
@@ -289,11 +303,131 @@ public class OrmTestHelper {
clusterDAO.create(clusterEntity);
clusterEntity = clusterDAO.findByName(clusterEntity.getClusterName());
- Assert.notNull(clusterEntity);
- Assert.isTrue(clusterEntity.getClusterId() > 0);
+ assertNotNull(clusterEntity);
+ assertTrue(clusterEntity.getClusterId() > 0);
return clusterEntity.getClusterId();
}
+ public Cluster buildNewCluster(Clusters clusters,
+ ServiceFactory serviceFactory, ServiceComponentFactory componentFactory,
+ ServiceComponentHostFactory schFactory, String hostName) throws Exception {
+ String clusterName = "cluster-" + System.currentTimeMillis();
+ clusters.addCluster(clusterName);
+ Cluster cluster = clusters.getCluster(clusterName);
+ cluster = initializeClusterWithStack(cluster);
+
+ addHost(clusters, cluster, hostName);
+
+ installHdfsService(cluster, serviceFactory, componentFactory, schFactory, hostName);
+ installYarnService(cluster, serviceFactory, componentFactory, schFactory,
+ hostName);
+ return cluster;
+ }
+
+ public Cluster initializeClusterWithStack(Cluster cluster) throws Exception {
+ StackId stackId = new StackId("HDP", "2.0.6");
+ cluster.setDesiredStackVersion(stackId);
+ cluster.createClusterVersion(stackId.getStackName(),
+ stackId.getStackVersion(), "admin", RepositoryVersionState.CURRENT);
+ return cluster;
+ }
+
+ /**
+ * @throws Exception
+ */
+ public void addHost(Clusters clusters, Cluster cluster, String hostName)
+ throws Exception {
+ clusters.addHost(hostName);
+
+ Host host = clusters.getHost(hostName);
+ Map<String, String> hostAttributes = new HashMap<String, String>();
+ hostAttributes.put("os_family", "redhat");
+ hostAttributes.put("os_release_version", "6.4");
+ host.setHostAttributes(hostAttributes);
+ host.setState(HostState.HEALTHY);
+ host.persist();
+
+ clusters.mapHostToCluster(hostName, cluster.getClusterName());
+ }
+
+ /**
+ * Calls {@link Service#persist()} to mock a service install along with
+ * creating a single {@link Host} and {@link ServiceComponentHost}.
+ */
+ public void installHdfsService(Cluster cluster,
+ ServiceFactory serviceFactory, ServiceComponentFactory componentFactory,
+ ServiceComponentHostFactory schFactory, String hostName) throws Exception {
+ String serviceName = "HDFS";
+ Service service = serviceFactory.createNew(cluster, serviceName);
+ cluster.addService(service);
+ service.persist();
+ service = cluster.getService(serviceName);
+ assertNotNull(service);
+
+ ServiceComponent datanode = componentFactory.createNew(service, "DATANODE");
+
+ service.addServiceComponent(datanode);
+ datanode.setDesiredState(State.INSTALLED);
+ datanode.persist();
+
+ ServiceComponentHost sch = schFactory.createNew(datanode, hostName);
+
+ datanode.addServiceComponentHost(sch);
+ sch.setDesiredState(State.INSTALLED);
+ sch.setState(State.INSTALLED);
+ sch.setDesiredStackVersion(new StackId("HDP-2.0.6"));
+ sch.setStackVersion(new StackId("HDP-2.0.6"));
+
+ sch.persist();
+
+ ServiceComponent namenode = componentFactory.createNew(service, "NAMENODE");
+
+ service.addServiceComponent(namenode);
+ namenode.setDesiredState(State.INSTALLED);
+ namenode.persist();
+
+ sch = schFactory.createNew(namenode, hostName);
+ namenode.addServiceComponentHost(sch);
+ sch.setDesiredState(State.INSTALLED);
+ sch.setState(State.INSTALLED);
+ sch.setDesiredStackVersion(new StackId("HDP-2.0.6"));
+ sch.setStackVersion(new StackId("HDP-2.0.6"));
+
+ sch.persist();
+ }
+
+ /**
+ * Calls {@link Service#persist()} to mock a service install along with
+ * creating a single {@link Host} and {@link ServiceComponentHost}.
+ */
+ public void installYarnService(Cluster cluster,
+ ServiceFactory serviceFactory, ServiceComponentFactory componentFactory,
+ ServiceComponentHostFactory schFactory, String hostName) throws Exception {
+ String serviceName = "YARN";
+ Service service = serviceFactory.createNew(cluster, serviceName);
+ cluster.addService(service);
+ service.persist();
+ service = cluster.getService(serviceName);
+ assertNotNull(service);
+
+ ServiceComponent resourceManager = componentFactory.createNew(service,
+ "RESOURCEMANAGER");
+
+ service.addServiceComponent(resourceManager);
+ resourceManager.setDesiredState(State.INSTALLED);
+ resourceManager.persist();
+
+ ServiceComponentHost sch = schFactory.createNew(resourceManager, hostName);
+
+ resourceManager.addServiceComponentHost(sch);
+ sch.setDesiredState(State.INSTALLED);
+ sch.setState(State.INSTALLED);
+ sch.setDesiredStackVersion(new StackId("HDP-2.0.6"));
+ sch.setStackVersion(new StackId("HDP-2.0.6"));
+
+ sch.persist();
+ }
+
/**
* Creates an alert target.
*
@@ -324,7 +458,7 @@ public class OrmTestHelper {
AlertDefinitionEntity definition = new AlertDefinitionEntity();
definition.setDefinitionName("Alert Definition "
+ System.currentTimeMillis());
- definition.setServiceName("Service " + System.currentTimeMillis());
+ definition.setServiceName("AMBARI");
definition.setComponentName(null);
definition.setClusterId(clusterId);
definition.setHash(UUID.randomUUID().toString());
@@ -385,8 +519,8 @@ public class OrmTestHelper {
List<AlertGroupEntity> defaultGroups = alertDispatchDAO.findAllGroups(clusterId);
assertEquals(2, defaultGroups.size());
- assertNotNull(alertDispatchDAO.findDefaultServiceGroup("HDFS"));
- assertNotNull(alertDispatchDAO.findDefaultServiceGroup("OOZIE"));
+ assertNotNull(alertDispatchDAO.findDefaultServiceGroup(clusterId, "HDFS"));
+ assertNotNull(alertDispatchDAO.findDefaultServiceGroup(clusterId, "OOZIE"));
return defaultGroups;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/9159421b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDispatchDAOTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDispatchDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDispatchDAOTest.java
index 0d2d305..3d8f898 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDispatchDAOTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDispatchDAOTest.java
@@ -19,21 +19,20 @@
package org.apache.ambari.server.orm.dao;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import java.lang.reflect.Field;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import java.util.UUID;
-import junit.framework.Assert;
-
+import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.controller.AlertNoticeRequest;
import org.apache.ambari.server.controller.internal.AlertNoticeResourceProvider;
import org.apache.ambari.server.controller.internal.PageRequestImpl;
@@ -44,6 +43,8 @@ import org.apache.ambari.server.controller.spi.SortRequest;
import org.apache.ambari.server.controller.spi.SortRequest.Order;
import org.apache.ambari.server.controller.spi.SortRequestProperty;
import org.apache.ambari.server.controller.utilities.PredicateBuilder;
+import org.apache.ambari.server.events.listeners.alerts.AlertServiceStateListener;
+import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
import org.apache.ambari.server.orm.AlertDaoHelper;
import org.apache.ambari.server.orm.GuiceJpaInitializer;
import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
@@ -55,25 +56,18 @@ import org.apache.ambari.server.orm.entities.AlertNoticeEntity;
import org.apache.ambari.server.orm.entities.AlertTargetEntity;
import org.apache.ambari.server.state.AlertState;
import org.apache.ambari.server.state.Cluster;
-import org.apache.ambari.server.state.RepositoryVersionState;
import org.apache.ambari.server.state.Clusters;
-import org.apache.ambari.server.state.Host;
-import org.apache.ambari.server.state.HostState;
import org.apache.ambari.server.state.NotificationState;
-import org.apache.ambari.server.state.Service;
-import org.apache.ambari.server.state.ServiceComponent;
import org.apache.ambari.server.state.ServiceComponentFactory;
-import org.apache.ambari.server.state.ServiceComponentHost;
import org.apache.ambari.server.state.ServiceComponentHostFactory;
import org.apache.ambari.server.state.ServiceFactory;
-import org.apache.ambari.server.state.StackId;
-import org.apache.ambari.server.state.State;
import org.apache.ambari.server.state.alert.Scope;
import org.apache.ambari.server.state.alert.SourceType;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import com.google.common.eventbus.EventBus;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.persist.PersistService;
@@ -86,7 +80,7 @@ public class AlertDispatchDAOTest {
private final static String HOSTNAME = "c6401.ambari.apache.org";
private Clusters m_clusters;
- private Long m_clusterId;
+ private Cluster m_cluster;
private Injector m_injector;
private AlertDispatchDAO m_dao;
private AlertDefinitionDAO m_definitionDao;
@@ -97,6 +91,8 @@ public class AlertDispatchDAOTest {
private ServiceComponentFactory m_componentFactory;
private ServiceComponentHostFactory m_schFactory;
private AlertDaoHelper m_alertHelper;
+ private AmbariEventPublisher m_eventPublisher;
+ private EventBus m_synchronizedBus;
/**
*
@@ -114,15 +110,24 @@ public class AlertDispatchDAOTest {
m_schFactory = m_injector.getInstance(ServiceComponentHostFactory.class);
m_clusters = m_injector.getInstance(Clusters.class);
m_alertHelper = m_injector.getInstance(AlertDaoHelper.class);
+ m_eventPublisher = m_injector.getInstance(AmbariEventPublisher.class);
+
+ // !!! need a synchronous op for testing
+ m_synchronizedBus = new EventBus();
+ Field field = AmbariEventPublisher.class.getDeclaredField("m_eventBus");
+ field.setAccessible(true);
+ field.set(m_eventPublisher, m_synchronizedBus);
+
+ m_cluster = m_clusters.getClusterById(m_helper.createCluster());
+ m_helper.initializeClusterWithStack(m_cluster);
- m_clusterId = m_helper.createCluster();
Set<AlertTargetEntity> targets = createTargets();
for (int i = 0; i < 10; i++) {
AlertGroupEntity group = new AlertGroupEntity();
group.setDefault(false);
group.setGroupName("Group Name " + i);
- group.setClusterId(m_clusterId);
+ group.setClusterId(m_cluster.getClusterId());
for (AlertTargetEntity alertTarget : targets) {
group.addAlertTarget(alertTarget);
}
@@ -214,7 +219,8 @@ public class AlertDispatchDAOTest {
Set<AlertTargetEntity> targets = new HashSet<AlertTargetEntity>();
targets.add(target);
- AlertGroupEntity group = m_helper.createAlertGroup(m_clusterId, targets);
+ AlertGroupEntity group = m_helper.createAlertGroup(
+ m_cluster.getClusterId(), targets);
AlertGroupEntity actual = m_dao.findGroupById(group.getGroupId());
assertNotNull(group);
@@ -231,7 +237,8 @@ public class AlertDispatchDAOTest {
public void testGroupDefinitions() throws Exception {
List<AlertDefinitionEntity> definitions = createDefinitions();
- AlertGroupEntity group = m_helper.createAlertGroup(m_clusterId, null);
+ AlertGroupEntity group = m_helper.createAlertGroup(
+ m_cluster.getClusterId(), null);
group = m_dao.findGroupById(group.getGroupId());
assertNotNull(group);
@@ -272,7 +279,8 @@ public class AlertDispatchDAOTest {
Set<AlertTargetEntity> targets = new HashSet<AlertTargetEntity>();
targets.add(target);
- AlertGroupEntity group = m_helper.createAlertGroup(m_clusterId, targets);
+ AlertGroupEntity group = m_helper.createAlertGroup(
+ m_cluster.getClusterId(), targets);
AlertTargetEntity actual = m_dao.findTargetById(target.getTargetId());
assertNotNull(actual);
@@ -297,7 +305,8 @@ public class AlertDispatchDAOTest {
public void testDeleteGroup() throws Exception {
int targetCount = m_dao.findAllTargets().size();
- AlertGroupEntity group = m_helper.createAlertGroup(m_clusterId, null);
+ AlertGroupEntity group = m_helper.createAlertGroup(
+ m_cluster.getClusterId(), null);
AlertTargetEntity target = m_helper.createAlertTarget();
assertEquals(targetCount + 1, m_dao.findAllTargets().size());
@@ -347,7 +356,8 @@ public class AlertDispatchDAOTest {
Set<AlertTargetEntity> targets = new HashSet<AlertTargetEntity>();
targets.add(target);
- AlertGroupEntity group = m_helper.createAlertGroup(m_clusterId, targets);
+ AlertGroupEntity group = m_helper.createAlertGroup(
+ m_cluster.getClusterId(), targets);
assertEquals(1, group.getAlertTargets().size());
target = m_dao.findTargetById(target.getTargetId());
@@ -377,7 +387,8 @@ public class AlertDispatchDAOTest {
String groupName = "Group Name " + System.currentTimeMillis();
- AlertGroupEntity group = m_helper.createAlertGroup(m_clusterId, null);
+ AlertGroupEntity group = m_helper.createAlertGroup(
+ m_cluster.getClusterId(), null);
group = m_dao.findGroupById(group.getGroupId());
group.setGroupName(groupName + "FOO");
@@ -406,7 +417,8 @@ public class AlertDispatchDAOTest {
@Test
public void testFindGroupsByDefinition() throws Exception {
List<AlertDefinitionEntity> definitions = createDefinitions();
- AlertGroupEntity group = m_helper.createAlertGroup(m_clusterId, null);
+ AlertGroupEntity group = m_helper.createAlertGroup(
+ m_cluster.getClusterId(), null);
group = m_dao.findGroupById(group.getGroupId());
assertNotNull(group);
@@ -420,10 +432,11 @@ public class AlertDispatchDAOTest {
group = m_dao.findGroupByName(group.getGroupName());
assertEquals(definitions.size(), group.getAlertDefinitions().size());
+ // assert that the definition is now part of 2 groups (the default group
+ // and the newly associated group from above)
for (AlertDefinitionEntity definition : definitions) {
List<AlertGroupEntity> groups = m_dao.findGroupsByDefinition(definition);
- assertEquals(1, groups.size());
- assertEquals(group.getGroupId(), groups.get(0).getGroupId());
+ assertEquals(2, groups.size());
}
}
@@ -437,7 +450,7 @@ public class AlertDispatchDAOTest {
AlertHistoryEntity history = new AlertHistoryEntity();
history.setServiceName(definition.getServiceName());
- history.setClusterId(m_clusterId);
+ history.setClusterId(m_cluster.getClusterId());
history.setAlertDefinition(definition);
history.setAlertLabel("Label");
history.setAlertState(AlertState.OK);
@@ -468,7 +481,9 @@ public class AlertDispatchDAOTest {
*/
@Test
public void testAlertNoticePredicate() throws Exception {
- Cluster cluster = initializeNewCluster();
+ Cluster cluster = m_helper.buildNewCluster(m_clusters, m_serviceFactory,
+ m_componentFactory, m_schFactory, HOSTNAME);
+
m_alertHelper.populateData(cluster);
Predicate clusterPredicate = null;
@@ -544,7 +559,9 @@ public class AlertDispatchDAOTest {
*/
@Test
public void testAlertNoticePagination() throws Exception {
- Cluster cluster = initializeNewCluster();
+ Cluster cluster = m_helper.buildNewCluster(m_clusters, m_serviceFactory,
+ m_componentFactory, m_schFactory, HOSTNAME);
+
m_alertHelper.populateData(cluster);
AlertNoticeRequest request = new AlertNoticeRequest();
@@ -583,7 +600,9 @@ public class AlertDispatchDAOTest {
*/
@Test
public void testAlertNoticeSorting() throws Exception {
- Cluster cluster = initializeNewCluster();
+ Cluster cluster = m_helper.buildNewCluster(m_clusters, m_serviceFactory,
+ m_componentFactory, m_schFactory, HOSTNAME);
+
m_alertHelper.populateData(cluster);
List<SortRequestProperty> sortProperties = new ArrayList<SortRequestProperty>();
@@ -640,15 +659,135 @@ public class AlertDispatchDAOTest {
}
/**
+ *
+ */
+ @Test
+ public void testFindDefaultGroup() throws Exception {
+ m_synchronizedBus.register(m_injector.getInstance(AlertServiceStateListener.class));
+
+ List<AlertGroupEntity> groups = m_dao.findAllGroups();
+ assertNotNull(groups);
+ assertEquals(10, groups.size());
+
+ for (AlertGroupEntity group : groups) {
+ assertFalse(group.isDefault());
+ }
+
+ Cluster cluster = m_helper.buildNewCluster(m_clusters, m_serviceFactory,
+ m_componentFactory, m_schFactory, HOSTNAME);
+
+ AlertGroupEntity hdfsGroup = m_dao.findDefaultServiceGroup(
+ cluster.getClusterId(), "HDFS");
+
+ assertNotNull(hdfsGroup);
+ assertTrue(hdfsGroup.isDefault());
+ }
+
+ /**
+ * Tests that when creating a new {@link AlertDefinitionEntity}, if the group
+ * for its service does not exist, then it will be created.
+ */
+ @Test
+ public void testDefaultGroupAutomaticCreation() throws Exception {
+ m_synchronizedBus.register(m_injector.getInstance(AlertServiceStateListener.class));
+
+ List<AlertGroupEntity> groups = m_dao.findAllGroups();
+ assertNotNull(groups);
+ assertEquals(10, groups.size());
+
+ for (AlertGroupEntity group : groups) {
+ assertFalse(group.isDefault());
+ }
+
+ Cluster cluster = m_helper.buildNewCluster(m_clusters, m_serviceFactory,
+ m_componentFactory, m_schFactory, HOSTNAME);
+
+ AlertGroupEntity hdfsGroup = m_dao.findDefaultServiceGroup(
+ cluster.getClusterId(), "HDFS");
+
+ // remove the HDFS default group
+ m_dao.remove(hdfsGroup);
+ hdfsGroup = m_dao.findDefaultServiceGroup(cluster.getClusterId(), "HDFS");
+ assertNull(hdfsGroup);
+
+ AlertDefinitionEntity datanodeProcess = new AlertDefinitionEntity();
+ datanodeProcess.setClusterId(cluster.getClusterId());
+ datanodeProcess.setDefinitionName("datanode_process");
+ datanodeProcess.setServiceName("HDFS");
+ datanodeProcess.setComponentName("DATANODE");
+ datanodeProcess.setHash(UUID.randomUUID().toString());
+ datanodeProcess.setScheduleInterval(60);
+ datanodeProcess.setScope(Scope.SERVICE);
+ datanodeProcess.setSource("{\"type\" : \"SCRIPT\"}");
+ datanodeProcess.setSourceType(SourceType.SCRIPT);
+ m_definitionDao.create(datanodeProcess);
+
+ // the group should be created and should be default
+ hdfsGroup = m_dao.findDefaultServiceGroup(cluster.getClusterId(), "HDFS");
+ assertNotNull(hdfsGroup);
+ assertTrue(hdfsGroup.isDefault());
+ }
+
+ /**
+ * Tests that when creating a new {@link AlertDefinitionEntity}, if the group
+ * for its service does not exist, then it will not be created if the service
+ * is invalid.
+ */
+ @Test(expected = AmbariException.class)
+ public void testDefaultGroupInvalidServiceNoCreation() throws Exception {
+ m_synchronizedBus.register(m_injector.getInstance(AlertServiceStateListener.class));
+
+ List<AlertGroupEntity> groups = m_dao.findAllGroups();
+ assertNotNull(groups);
+ assertEquals(10, groups.size());
+
+ for (AlertGroupEntity group : groups) {
+ assertFalse(group.isDefault());
+ }
+
+ Cluster cluster = m_helper.buildNewCluster(m_clusters, m_serviceFactory,
+ m_componentFactory, m_schFactory, HOSTNAME);
+
+ assertEquals(12, m_dao.findAllGroups().size());
+
+ // create a definition with an invalid service
+ AlertDefinitionEntity datanodeProcess = new AlertDefinitionEntity();
+ datanodeProcess.setClusterId(cluster.getClusterId());
+ datanodeProcess.setDefinitionName("datanode_process");
+ datanodeProcess.setServiceName("INVALID");
+ datanodeProcess.setComponentName("DATANODE");
+ datanodeProcess.setHash(UUID.randomUUID().toString());
+ datanodeProcess.setScheduleInterval(60);
+ datanodeProcess.setScope(Scope.SERVICE);
+ datanodeProcess.setSource("{\"type\" : \"SCRIPT\"}");
+ datanodeProcess.setSourceType(SourceType.SCRIPT);
+
+ try {
+ m_definitionDao.create(datanodeProcess);
+ } finally {
+ // assert no group was added
+ assertEquals(12, m_dao.findAllGroups().size());
+ }
+ }
+
+ /**
* @return
*/
private List<AlertDefinitionEntity> createDefinitions() throws Exception {
+ // add a host to the cluster
+ m_helper.addHost(m_clusters, m_cluster, HOSTNAME);
+
+ // install YARN (which doesn't have any alerts defined in the test JSON)
+ // so that the definitions get created correctly
+ m_helper.installYarnService(m_cluster, m_serviceFactory,
+ m_componentFactory, m_schFactory, HOSTNAME);
+
for (int i = 0; i < 8; i++) {
AlertDefinitionEntity definition = new AlertDefinitionEntity();
definition.setDefinitionName("Alert Definition " + i);
- definition.setServiceName("HDFS");
+ definition.setServiceName("YARN");
definition.setComponentName(null);
- definition.setClusterId(m_clusterId);
+ definition.setClusterId(m_cluster.getClusterId());
definition.setHash(UUID.randomUUID().toString());
definition.setScheduleInterval(60);
definition.setScope(Scope.SERVICE);
@@ -680,81 +819,4 @@ public class AlertDispatchDAOTest {
return targets;
}
-
- private Cluster initializeNewCluster() throws Exception {
- String clusterName = "cluster-" + System.currentTimeMillis();
- m_clusters.addCluster(clusterName);
-
- Cluster cluster = m_clusters.getCluster(clusterName);
- StackId stackId = new StackId("HDP", "2.0.6");
- cluster.setDesiredStackVersion(stackId);
- cluster.createClusterVersion(stackId.getStackName(), stackId.getStackVersion(), "admin", RepositoryVersionState.CURRENT);
-
- addHost();
- m_clusters.mapHostToCluster(HOSTNAME, cluster.getClusterName());
-
- installHdfsService(cluster);
- return cluster;
- }
-
- /**
- * @throws Exception
- */
- private void addHost() throws Exception {
- m_clusters.addHost(HOSTNAME);
-
- Host host = m_clusters.getHost(HOSTNAME);
- Map<String, String> hostAttributes = new HashMap<String, String>();
- hostAttributes.put("os_family", "redhat");
- hostAttributes.put("os_release_version", "6.4");
- host.setHostAttributes(hostAttributes);
- host.setState(HostState.HEALTHY);
- host.persist();
- }
-
- /**
- * Calls {@link Service#persist()} to mock a service install along with
- * creating a single {@link Host} and {@link ServiceComponentHost}.
- */
- private void installHdfsService(Cluster cluster) throws Exception {
- String serviceName = "HDFS";
- Service service = m_serviceFactory.createNew(cluster, serviceName);
- cluster.addService(service);
- service.persist();
- service = cluster.getService(serviceName);
- Assert.assertNotNull(service);
-
- ServiceComponent datanode = m_componentFactory.createNew(service,
- "DATANODE");
-
- service.addServiceComponent(datanode);
- datanode.setDesiredState(State.INSTALLED);
- datanode.persist();
-
- ServiceComponentHost sch = m_schFactory.createNew(datanode, HOSTNAME);
-
- datanode.addServiceComponentHost(sch);
- sch.setDesiredState(State.INSTALLED);
- sch.setState(State.INSTALLED);
- sch.setDesiredStackVersion(new StackId("HDP-2.0.6"));
- sch.setStackVersion(new StackId("HDP-2.0.6"));
-
- sch.persist();
-
- ServiceComponent namenode = m_componentFactory.createNew(service,
- "NAMENODE");
-
- service.addServiceComponent(namenode);
- namenode.setDesiredState(State.INSTALLED);
- namenode.persist();
-
- sch = m_schFactory.createNew(namenode, HOSTNAME);
- namenode.addServiceComponentHost(sch);
- sch.setDesiredState(State.INSTALLED);
- sch.setState(State.INSTALLED);
- sch.setDesiredStackVersion(new StackId("HDP-2.0.6"));
- sch.setStackVersion(new StackId("HDP-2.0.6"));
-
- sch.persist();
- }
}