Repository: ambari Updated Branches: refs/heads/branch-alerts-dev ae8f1e77e -> 76fc94ec1
AMBARI-7051 - Alerts: Expose Creation and Updating of Group Targets & Definitions (jonathanhurley) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/76fc94ec Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/76fc94ec Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/76fc94ec Branch: refs/heads/branch-alerts-dev Commit: 76fc94ec1ab6ee904e0efa254c19521a201c06d4 Parents: ae8f1e7 Author: Jonathan Hurley <jhur...@hortonworks.com> Authored: Wed Aug 27 21:07:43 2014 -0400 Committer: Jonathan Hurley <jhur...@hortonworks.com> Committed: Thu Aug 28 09:38:28 2014 -0400 ---------------------------------------------------------------------- .../python/ambari_agent/alerts/base_alert.py | 45 ++- .../python/ambari_agent/alerts/port_alert.py | 42 +-- .../server/api/services/AlertGroupService.java | 10 + .../controller/AlertDefinitionResponse.java | 143 +++++++++ .../internal/AlertGroupResourceProvider.java | 144 ++++++++- .../server/orm/dao/AlertDefinitionDAO.java | 16 + .../ambari/server/orm/dao/AlertDispatchDAO.java | 18 +- .../orm/entities/AlertDefinitionEntity.java | 37 ++- .../server/orm/entities/AlertGroupEntity.java | 56 +++- .../server/orm/entities/AlertTargetEntity.java | 3 +- .../ambari/server/state/alert/AlertTarget.java | 37 ++- .../AlertGroupResourceProviderTest.java | 295 +++++++++++++++---- .../AlertTargetResourceProviderTest.java | 2 +- .../server/orm/dao/AlertDefinitionDAOTest.java | 18 +- .../server/orm/dao/AlertDispatchDAOTest.java | 53 ++-- 15 files changed, 773 insertions(+), 146 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/76fc94ec/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py ---------------------------------------------------------------------- diff --git a/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py b/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py index 88c7f92..bf8ada6 100644 --- a/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py +++ b/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py @@ -34,7 +34,7 @@ class BaseAlert(object): self.alert_meta = alert_meta self.alert_source_meta = alert_source_meta self.cluster = '' - self.hostName = '' + self.host_name = '' self._lookup_keys = [] @@ -54,7 +54,7 @@ class BaseAlert(object): def set_cluster(self, cluster, host): ''' sets cluster information for the alert ''' self.cluster = cluster - self.hostName = host + self.host_name = host def collect(self): ''' method used for collection. defers to _collect() ''' @@ -123,4 +123,43 @@ class BaseAlert(object): res[0] = the result code res[1] = the list of arguments supplied to the reporting text for the result code ''' - raise NotImplementedError \ No newline at end of file + raise NotImplementedError + + ''' + See RFC3986, Appendix B + Tested on the following cases: + "192.168.54.1" + "192.168.54.2:7661 + "hdfs://192.168.54.3/foo/bar" + "ftp://192.168.54.4:7842/foo/bar" + + Returns None if only a port is passsed in + ''' + @staticmethod + def get_host_from_url(uri): + # RFC3986, Appendix B + parts = re.findall('^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?', uri) + + # index of parts + # scheme = 1 + # authority = 3 + # path = 4 + # query = 6 + # fragment = 8 + + host_and_port = uri + if 0 == len(parts[0][1]): + host_and_port = parts[0][4] + elif 0 == len(parts[0][2]): + host_and_port = parts[0][1] + elif parts[0][2].startswith("//"): + host_and_port = parts[0][3] + + if -1 == host_and_port.find(':'): + # if no : then it might only be a port; if it's a port, return this host + if host_and_port.isdigit(): + return None + + return host_and_port + else: + return host_and_port.split(':')[0] http://git-wip-us.apache.org/repos/asf/ambari/blob/76fc94ec/ambari-agent/src/main/python/ambari_agent/alerts/port_alert.py ---------------------------------------------------------------------- diff --git a/ambari-agent/src/main/python/ambari_agent/alerts/port_alert.py b/ambari-agent/src/main/python/ambari_agent/alerts/port_alert.py index eaf744a..1d34410 100644 --- a/ambari-agent/src/main/python/ambari_agent/alerts/port_alert.py +++ b/ambari-agent/src/main/python/ambari_agent/alerts/port_alert.py @@ -39,9 +39,11 @@ class PortAlert(BaseAlert): def _collect(self): urivalue = self._lookup_property_value(self.uri) - host = get_host_from_url(self, urivalue) port = self.port - + host = BaseAlert.get_host_from_url(urivalue) + if host is None: + host = self.host_name + try: port = int(get_port_from_url(urivalue)) except: @@ -67,39 +69,3 @@ class PortAlert(BaseAlert): except: pass -''' -See RFC3986, Appendix B -Tested on the following cases: - "192.168.54.1" - "192.168.54.2:7661 - "hdfs://192.168.54.3/foo/bar" - "ftp://192.168.54.4:7842/foo/bar" -''' -def get_host_from_url(self, uri): - # RFC3986, Appendix B - parts = re.findall('^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?', uri) - - # index of parts - # scheme = 1 - # authority = 3 - # path = 4 - # query = 6 - # fragment = 8 - - host_and_port = uri - if 0 == len(parts[0][1]): - host_and_port = parts[0][4] - elif 0 == len(parts[0][2]): - host_and_port = parts[0][1] - elif parts[0][2].startswith("//"): - host_and_port = parts[0][3] - - if -1 == host_and_port.find(':'): - # if no : then it might only be a port; if it's a port, return this host - if host_and_port.isdigit(): - return self.hostName - - return host_and_port - else: - return host_and_port.split(':')[0] - http://git-wip-us.apache.org/repos/asf/ambari/blob/76fc94ec/ambari-server/src/main/java/org/apache/ambari/server/api/services/AlertGroupService.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AlertGroupService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AlertGroupService.java index c2e5048..12cdb70 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AlertGroupService.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AlertGroupService.java @@ -23,6 +23,7 @@ import java.util.Map; import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.POST; +import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; @@ -80,6 +81,15 @@ public class AlertGroupService extends BaseService { createAlertGroupResource(m_clusterName, null)); } + @PUT + @Produces("text/plain") + @Path("{groupId}") + public Response updateGroup(String body, @Context HttpHeaders headers, + @Context UriInfo ui, @PathParam("groupId") Long groupId) { + return handleRequest(headers, body, ui, Request.Type.PUT, + createAlertGroupResource(m_clusterName, groupId)); + } + @DELETE @Produces("text/plain") @Path("{groupId}") http://git-wip-us.apache.org/repos/asf/ambari/blob/76fc94ec/ambari-server/src/main/java/org/apache/ambari/server/controller/AlertDefinitionResponse.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AlertDefinitionResponse.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AlertDefinitionResponse.java new file mode 100644 index 0000000..26e2f24 --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AlertDefinitionResponse.java @@ -0,0 +1,143 @@ +/** +® * 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.controller; + +import org.apache.ambari.server.orm.entities.AlertDefinitionEntity; +import org.codehaus.jackson.annotate.JsonProperty; + + +/** + * The {@link AlertDefinitionResponse} encapsulates the definition information + * that should be serialized and returned in REST requests for alerts, groups, + * and targets. + */ +public class AlertDefinitionResponse { + + private String serviceName = null; + private String componentName = null; + private String name = null; + private String label = null; + private Long definitionId; + + /** + * @return the definitionId + */ + @JsonProperty("id") + public Long getDefinitionId() { + return definitionId; + } + + /** + * @param definitionId + * the definitionId to set + */ + public void setDefinitionId(Long definitionId) { + this.definitionId = definitionId; + } + + /** + * @return the service name + */ + @JsonProperty("service_name") + public String getServiceName() { + return serviceName; + } + + /** + * @param name the service name + */ + public void setServiceName(String name) { + serviceName = name; + } + + /** + * @return the component name + */ + @JsonProperty("component_name") + public String getComponentName() { + return componentName; + } + + /** + * + * @param name the component name + */ + public void setComponentName(String name) { + componentName = name; + } + + /** + * @return the name + */ + @JsonProperty("name") + public String getName() { + return name; + } + + /** + * @param definitionName + * the definition name. + */ + public void setName(String definitionName) { + name = definitionName; + } + + /** + * @return the label for the definition or {@code null} if none. + */ + @JsonProperty("label") + public String getLabel() { + return label; + } + + /** + * Sets the label for this definition. + * + * @param definitionLabel + */ + public void setLabel(String definitionLabel) { + label = definitionLabel; + } + + @Override + public String toString() { + return name; + } + + /** + * Gets an {@link AlertDefinitionResponse} from the supplied entity. + * + * @param entity + * the entity (not {@code null}). + * @return the response. + */ + public static AlertDefinitionResponse coerce(AlertDefinitionEntity entity) { + if (null == entity) { + return null; + } + + AlertDefinitionResponse response = new AlertDefinitionResponse(); + response.setDefinitionId(entity.getDefinitionId()); + response.setComponentName(entity.getComponentName()); + response.setLabel(entity.getLabel()); + response.setName(entity.getDefinitionName()); + response.setServiceName(entity.getServiceName()); + + return response; + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/76fc94ec/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProvider.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProvider.java index f14e76f..fc51ddd 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProvider.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProvider.java @@ -17,14 +17,17 @@ */ package org.apache.ambari.server.controller.internal; +import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.ambari.server.AmbariException; +import org.apache.ambari.server.controller.AlertDefinitionResponse; import org.apache.ambari.server.controller.AmbariManagementController; import org.apache.ambari.server.controller.spi.NoSuchParentResourceException; import org.apache.ambari.server.controller.spi.NoSuchResourceException; @@ -36,11 +39,14 @@ import org.apache.ambari.server.controller.spi.Resource.Type; import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException; import org.apache.ambari.server.controller.spi.SystemException; import org.apache.ambari.server.controller.spi.UnsupportedPropertyException; +import org.apache.ambari.server.orm.dao.AlertDefinitionDAO; import org.apache.ambari.server.orm.dao.AlertDispatchDAO; +import org.apache.ambari.server.orm.entities.AlertDefinitionEntity; import org.apache.ambari.server.orm.entities.AlertGroupEntity; import org.apache.ambari.server.orm.entities.AlertTargetEntity; import org.apache.ambari.server.state.Cluster; import org.apache.ambari.server.state.alert.AlertGroup; +import org.apache.ambari.server.state.alert.AlertTarget; import org.apache.commons.lang.StringUtils; import com.google.inject.Inject; @@ -66,12 +72,16 @@ public class AlertGroupResourceProvider extends Arrays.asList(ALERT_GROUP_ID, ALERT_GROUP_CLUSTER_NAME)); /** - * Group DAO + * Group/Target DAO */ - @Inject private static AlertDispatchDAO s_dao; /** + * Definitions DAO + */ + private static AlertDefinitionDAO s_definitionDao; + + /** * Initializes the injectable members of this class with the specified * injector. * @@ -81,6 +91,7 @@ public class AlertGroupResourceProvider extends @Inject public static void init(Injector injector) { s_dao = injector.getInstance(AlertDispatchDAO.class); + s_definitionDao = injector.getInstance(AlertDefinitionDAO.class); } /** @@ -156,11 +167,21 @@ public class AlertGroupResourceProvider extends } @Override - public RequestStatus updateResources(Request request, Predicate predicate) + public RequestStatus updateResources(final Request request, + Predicate predicate) throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException { - throw new UnsupportedOperationException(); + modifyResources(new Command<Void>() { + @Override + public Void invoke() throws AmbariException { + updateAlertGroups(request.getProperties()); + return null; + } + }); + + notifyUpdate(Resource.Type.AlertGroup, request, predicate); + return getRequestStatus(null); } @Override @@ -207,6 +228,7 @@ public class AlertGroupResourceProvider extends * @param requestMaps * @throws AmbariException */ + @SuppressWarnings("unchecked") private void createAlertGroups(Set<Map<String, Object>> requestMaps) throws AmbariException { @@ -231,9 +253,27 @@ public class AlertGroupResourceProvider extends clusterName); entity.setClusterId(cluster.getClusterId()); - entity.setDefault(false); entity.setGroupName(name); + // groups created through the provider are not default service groups + entity.setDefault(false); + + // targets are not required on creation + if (requestMap.containsKey(ALERT_GROUP_TARGETS)) { + List<Long> targetIds = (List<Long>) requestMap.get(ALERT_GROUP_TARGETS); + Set<AlertTargetEntity> targets = new HashSet<AlertTargetEntity>(); + targets.addAll(s_dao.findTargetsById(targetIds)); + entity.setAlertTargets(targets); + } + + // definitions are not required on creation + if (requestMap.containsKey(ALERT_GROUP_DEFINITIONS)) { + List<Long> definitionIds = (List<Long>) requestMap.get(ALERT_GROUP_DEFINITIONS); + Set<AlertDefinitionEntity> definitions = new HashSet<AlertDefinitionEntity>(); + definitions.addAll(s_definitionDao.findByIds(definitionIds)); + entity.setAlertDefinitions(definitions); + } + entities.add(entity); } @@ -241,6 +281,74 @@ public class AlertGroupResourceProvider extends } /** + * Updates existing {@link AlertGroupEntity}s with the specified properties. + * + * @param requestMaps + * a set of property maps, one map for each entity. + * @throws AmbariException + * if the entity could not be found. + */ + @SuppressWarnings("unchecked") + private void updateAlertGroups(Set<Map<String, Object>> requestMaps) + throws AmbariException { + + for (Map<String, Object> requestMap : requestMaps) { + String stringId = (String) requestMap.get(ALERT_GROUP_ID); + + if( StringUtils.isEmpty(stringId)){ + throw new IllegalArgumentException("The ID of the alert group is required when updating an existing group"); + } + + long id = Long.parseLong(stringId); + AlertGroupEntity entity = s_dao.findGroupById(id); + + if( null == entity ){ + String message = MessageFormat.format("The alert group with ID {0} could not be found", id); + throw new AmbariException(message); + } + + String name = (String) requestMap.get(ALERT_GROUP_NAME); + + // empty arrays are deserialized as HashSet while populated arrays + // are deserialized as ArrayList; use Collection for safety + Collection<Long> targetIds = (Collection<Long>) requestMap.get(ALERT_GROUP_TARGETS); + Collection<Long> definitionIds = (Collection<Long>) requestMap.get(ALERT_GROUP_DEFINITIONS); + + if (!StringUtils.isBlank(name)) { + entity.setGroupName(name); + } + + // if targets were supplied, replace existing + Set<AlertTargetEntity> targets = new HashSet<AlertTargetEntity>(); + if (null != targetIds && targetIds.size() > 0) { + List<Long> ids = new ArrayList<Long>(targetIds.size()); + ids.addAll(targetIds); + targets.addAll(s_dao.findTargetsById(ids)); + + entity.setAlertTargets(targets); + } else if (targetIds.size() == 0) { + // empty array supplied, clear out existing targets + entity.setAlertTargets(targets); + } + + // if definitions were supplied, replace existing + Set<AlertDefinitionEntity> definitions = new HashSet<AlertDefinitionEntity>(); + if (null != definitionIds && definitionIds.size() > 0) { + List<Long> ids = new ArrayList<Long>(definitionIds.size()); + ids.addAll(definitionIds); + definitions.addAll(s_definitionDao.findByIds(ids)); + + entity.setAlertDefinitions(definitions); + } else if (definitionIds.size() == 0) { + // empty array supplied, clear out existing definitions + entity.setAlertDefinitions(definitions); + } + + s_dao.merge(entity); + } + } + + /** * Convert the given {@link AlertGroupEntity} to a {@link Resource}. * * @param isCollection @@ -259,9 +367,31 @@ public class AlertGroupResourceProvider extends resource.setProperty(ALERT_GROUP_ID, entity.getGroupId()); resource.setProperty(ALERT_GROUP_NAME, entity.getGroupName()); resource.setProperty(ALERT_GROUP_CLUSTER_NAME, clusterName); + resource.setProperty(ALERT_GROUP_DEFAULT, entity.isDefault()); + + if( !isCollection ){ + Set<AlertTargetEntity> targetEntities = entity.getAlertTargets(); + Set<AlertDefinitionEntity> definitions = entity.getAlertDefinitions(); + + List<AlertTarget> targets = new ArrayList<AlertTarget>( + targetEntities.size()); - setResourceProperty(resource, ALERT_GROUP_DEFAULT, - entity.isDefault(), requestedIds); + List<AlertDefinitionResponse> definitionList = new ArrayList<AlertDefinitionResponse>( + definitions.size()); + + for (AlertTargetEntity targetEntity : targetEntities) { + AlertTarget target = AlertTarget.coerce(targetEntity); + targets.add(target); + } + + for (AlertDefinitionEntity definition : definitions) { + AlertDefinitionResponse response = AlertDefinitionResponse.coerce(definition); + definitionList.add(response); + } + + resource.setProperty(ALERT_GROUP_DEFINITIONS, definitionList); + resource.setProperty(ALERT_GROUP_TARGETS, targets); + } return resource; } http://git-wip-us.apache.org/repos/asf/ambari/blob/76fc94ec/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 4a8fe12..f410c39 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 @@ -124,6 +124,22 @@ public class AlertDefinitionDAO { } /** + * Gets all of the alert definitions for the list of IDs given. + * + * @param definitionIds + * the IDs of the definitions to retrieve. + * @return the definition or an empty list (never {@code null}). + */ + public List<AlertDefinitionEntity> findByIds(List<Long> definitionIds) { + TypedQuery<AlertDefinitionEntity> query = entityManagerProvider.get().createNamedQuery( + "AlertDefinitionEntity.findByIds", AlertDefinitionEntity.class); + + query.setParameter("definitionIds", definitionIds); + + return daoUtils.selectList(query); + } + + /** * Gets all alert definitions for the given service in the specified cluster. * * @param clusterId http://git-wip-us.apache.org/repos/asf/ambari/blob/76fc94ec/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 dfbe747..e08c948 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 @@ -72,6 +72,22 @@ public class AlertDispatchDAO { } /** + * Gets all of the alert targets for the list of IDs given. + * + * @param targetIds + * the IDs of the targets to retrieve. + * @return the targets or an empty list (never {@code null}). + */ + public List<AlertTargetEntity> findTargetsById(List<Long> targetIds) { + TypedQuery<AlertTargetEntity> query = entityManagerProvider.get().createNamedQuery( + "AlertTargetEntity.findByIds", AlertTargetEntity.class); + + query.setParameter("targetIds", targetIds); + + return daoUtils.selectList(query); + } + + /** * Gets a notification with the specified ID. * * @param noticeId @@ -207,7 +223,7 @@ public class AlertDispatchDAO { /** * Persists a new alert group. - * + * * @param alertGroup * the group to persist (not {@code null}). */ http://git-wip-us.apache.org/repos/asf/ambari/blob/76fc94ec/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 299467c..b4b8a44 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 @@ -17,6 +17,7 @@ */ package org.apache.ambari.server.orm.entities; +import java.util.HashSet; import java.util.Set; import javax.persistence.Basic; @@ -58,7 +59,8 @@ import org.apache.ambari.server.state.alert.Scope; @NamedQuery(name = "AlertDefinitionEntity.findByName", query = "SELECT ad FROM AlertDefinitionEntity ad WHERE ad.definitionName = :definitionName AND ad.clusterId = :clusterId"), @NamedQuery(name = "AlertDefinitionEntity.findByService", query = "SELECT ad FROM AlertDefinitionEntity ad WHERE ad.serviceName = :serviceName AND ad.clusterId = :clusterId"), @NamedQuery(name = "AlertDefinitionEntity.findByServiceAndComponent", query = "SELECT ad FROM AlertDefinitionEntity ad WHERE ad.serviceName = :serviceName AND ad.componentName = :componentName AND ad.clusterId = :clusterId"), - @NamedQuery(name = "AlertDefinitionEntity.findByServiceMaster", query = "SELECT ad FROM AlertDefinitionEntity ad WHERE ad.serviceName IN :services AND ad.scope = :scope AND ad.clusterId = :clusterId") }) + @NamedQuery(name = "AlertDefinitionEntity.findByServiceMaster", query = "SELECT ad FROM AlertDefinitionEntity ad WHERE ad.serviceName IN :services AND ad.scope = :scope AND ad.clusterId = :clusterId"), + @NamedQuery(name = "AlertDefinitionEntity.findByIds", query = "SELECT ad FROM AlertDefinitionEntity ad WHERE ad.definitionId IN :definitionIds") }) public class AlertDefinitionEntity { @Id @@ -394,6 +396,34 @@ public class AlertDefinitionEntity { } /** + * Adds the specified alert group to the groups that this definition is + * associated with. This is used to complement the JPA bidirectional + * association. + * + * @param alertGroup + */ + protected void addAlertGroup(AlertGroupEntity alertGroup) { + if (null == alertGroups) { + alertGroups = new HashSet<AlertGroupEntity>(); + } + + alertGroups.add(alertGroup); + } + + /** + * Removes the specified alert group to the groups that this definition is + * associated with. This is used to complement the JPA bidirectional + * association. + * + * @param alertGroup + */ + protected void removeAlertGroup(AlertGroupEntity alertGroup) { + if (null != alertGroups) { + alertGroups.remove(alertGroup); + } + } + + /** * Called before {@link EntityManager#remove(Object)} for this entity, removes * the non-owning relationship between definitions and groups. */ @@ -405,10 +435,7 @@ public class AlertDefinitionEntity { } for (AlertGroupEntity group : groups) { - Set<AlertDefinitionEntity> definitions = group.getAlertDefinitions(); - if (null != definitions) { - definitions.remove(this); - } + group.removeAlertDefinition(this); } } http://git-wip-us.apache.org/repos/asf/ambari/blob/76fc94ec/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 1ca592c..f97a0eb 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 @@ -177,7 +177,7 @@ public class AlertGroupEntity { /** * Set the service name. This is only applicable when {@link #isDefault()} is * {@code true}. - * + * * @param serviceName * the service that this is the default group for, or {@code null} if * this is not a default group. @@ -189,10 +189,14 @@ public class AlertGroupEntity { /** * Gets all of the alert definitions that are a part of this grouping. * - * @return the alert definitions or {@code null} if none. + * @return the alert definitions or an empty set if none (never {@code null). */ public Set<AlertDefinitionEntity> getAlertDefinitions() { - return alertDefinitions; + if (null == alertDefinitions) { + alertDefinitions = new HashSet<AlertDefinitionEntity>(); + } + + return Collections.unmodifiableSet(alertDefinitions); } /** @@ -202,14 +206,58 @@ public class AlertGroupEntity { * the definitions, or {@code null} for none. */ public void setAlertDefinitions(Set<AlertDefinitionEntity> alertDefinitions) { + if (null != this.alertDefinitions) { + for (AlertDefinitionEntity definition : this.alertDefinitions) { + definition.removeAlertGroup(this); + } + } + this.alertDefinitions = alertDefinitions; + + if (null != alertDefinitions) { + for (AlertDefinitionEntity definition : alertDefinitions) { + definition.addAlertGroup(this); + } + } + } + + /** + * Adds the specified definition to the definitions that this group will + * dispatch to. + * + * @param definition + * the definition to add (not {@code null}). + */ + public void addAlertDefinition(AlertDefinitionEntity definition) { + if (null == alertDefinitions) { + alertDefinitions = new HashSet<AlertDefinitionEntity>(); + } + + alertDefinitions.add(definition); + definition.addAlertGroup(this); + } + + /** + * Removes the specified definition from the definitions that this group will + * dispatch to. + * + * @param definition + * the definition to remove (not {@code null}). + */ + public void removeAlertDefinition(AlertDefinitionEntity definition) { + if (null != alertDefinitions) { + alertDefinitions.remove(definition); + } + + definition.removeAlertGroup(this); } /** * Gets an immutable set of the targets that will receive notifications for * alert definitions in this group. * - * @return the targets, or {@code null} if there are none. + * @return the targets that will be dispatch to for alerts in this group, or + * an empty set if there are none (never {@code null}). */ public Set<AlertTargetEntity> getAlertTargets() { if( null == alertTargets ) { http://git-wip-us.apache.org/repos/asf/ambari/blob/76fc94ec/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 89728e5..12c394d 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 @@ -46,7 +46,8 @@ import javax.persistence.TableGenerator; @TableGenerator(name = "alert_target_id_generator", table = "ambari_sequences", pkColumnName = "sequence_name", valueColumnName = "sequence_value", pkColumnValue = "alert_target_id_seq", initialValue = 0, allocationSize = 1) @NamedQueries({ @NamedQuery(name = "AlertTargetEntity.findAll", query = "SELECT alertTarget FROM AlertTargetEntity alertTarget"), - @NamedQuery(name = "AlertTargetEntity.findByName", query = "SELECT alertTarget FROM AlertTargetEntity alertTarget WHERE alertTarget.targetName = :targetName"), }) + @NamedQuery(name = "AlertTargetEntity.findByName", query = "SELECT alertTarget FROM AlertTargetEntity alertTarget WHERE alertTarget.targetName = :targetName"), + @NamedQuery(name = "AlertTargetEntity.findByIds", query = "SELECT alertTarget FROM AlertTargetEntity alertTarget WHERE alertTarget.targetId IN :targetIds") }) public class AlertTargetEntity { @Id http://git-wip-us.apache.org/repos/asf/ambari/blob/76fc94ec/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertTarget.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertTarget.java b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertTarget.java index 21e83d9..f495787 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertTarget.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertTarget.java @@ -17,24 +17,27 @@ */ package org.apache.ambari.server.state.alert; -import java.util.List; +import org.apache.ambari.server.orm.entities.AlertTargetEntity; +import org.codehaus.jackson.annotate.JsonProperty; + /** * The {@link AlertTarget} class represents a dispatch mechanism and audience * that will receive information about alerts int he system. */ public class AlertTarget { - private String m_id; + + private Long m_id; private String m_name; private String m_description; private String m_notificationType; private String m_properties; - private List<AlertGroup> m_groups; /** * @return the id */ - public String getId() { + @JsonProperty("id") + public Long getId() { return m_id; } @@ -42,13 +45,14 @@ public class AlertTarget { * @param id * the id to set */ - public void setId(String id) { + public void setId(Long id) { m_id = id; } /** * @return the name */ + @JsonProperty("name") public String getName() { return m_name; } @@ -64,6 +68,7 @@ public class AlertTarget { /** * @return the description */ + @JsonProperty("description") public String getDescription() { return m_description; } @@ -79,6 +84,7 @@ public class AlertTarget { /** * @return the notificationType */ + @JsonProperty("notification_type") public String getNotificationType() { return m_notificationType; } @@ -94,6 +100,7 @@ public class AlertTarget { /** * @return the properties */ + @JsonProperty("properties") public String getProperties() { return m_properties; } @@ -107,17 +114,17 @@ public class AlertTarget { } /** - * @return the groups + * @param entity + * @return */ - public List<AlertGroup> getGroups() { - return m_groups; - } + public static AlertTarget coerce(AlertTargetEntity entity) { + AlertTarget target = new AlertTarget(); + target.setId(entity.getTargetId()); + target.setDescription(entity.getDescription()); + target.setName(entity.getTargetName()); + target.setNotificationType(entity.getNotificationType()); + target.setProperties(entity.getProperties()); - /** - * @param groups - * the groups to set - */ - public void setGroups(List<AlertGroup> groups) { - m_groups = groups; + return target; } } http://git-wip-us.apache.org/repos/asf/ambari/blob/76fc94ec/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProviderTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProviderTest.java index c9428b7..ddfc75a 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProviderTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProviderTest.java @@ -17,24 +17,30 @@ */ package org.apache.ambari.server.controller.internal; +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertNotNull; +import static junit.framework.Assert.assertNull; +import static junit.framework.Assert.assertTrue; import static org.easymock.EasyMock.anyObject; import static org.easymock.EasyMock.capture; import static org.easymock.EasyMock.createMock; -import static org.easymock.EasyMock.createStrictMock; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.expectLastCall; import static org.easymock.EasyMock.replay; import static org.easymock.EasyMock.resetToStrict; import static org.easymock.EasyMock.verify; -import static org.junit.Assert.assertEquals; +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; +import org.apache.ambari.server.controller.AlertDefinitionResponse; import org.apache.ambari.server.controller.AmbariManagementController; import org.apache.ambari.server.controller.spi.Predicate; import org.apache.ambari.server.controller.spi.Request; @@ -43,13 +49,18 @@ import org.apache.ambari.server.controller.utilities.PredicateBuilder; import org.apache.ambari.server.controller.utilities.PropertyHelper; import org.apache.ambari.server.metadata.ActionMetadata; import org.apache.ambari.server.orm.InMemoryDefaultTestModule; +import org.apache.ambari.server.orm.dao.AlertDefinitionDAO; import org.apache.ambari.server.orm.dao.AlertDispatchDAO; +import org.apache.ambari.server.orm.entities.AlertDefinitionEntity; import org.apache.ambari.server.orm.entities.AlertGroupEntity; +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.alert.AlertTarget; +import org.apache.ambari.server.state.alert.SourceType; +import org.apache.ambari.server.state.alert.TargetType; import org.easymock.Capture; import org.easymock.EasyMock; -import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -69,17 +80,42 @@ public class AlertGroupResourceProviderTest { private static final long ALERT_GROUP_CLUSTER_ID = 1L; private static final String ALERT_GROUP_CLUSTER_NAME = "c1"; + private static final Long ALERT_TARGET_ID = Long.valueOf(28); + private static final String ALERT_TARGET_NAME = "The Administrators"; + private static final String ALERT_TARGET_DESC = "Admins and Others"; + private static final String ALERT_TARGET_TYPE = TargetType.EMAIL.name(); + + private static final Long ALERT_DEF_ID = Long.valueOf(10); + private static final String ALERT_DEF_NAME = "Mock Definition"; + private static final String ALERT_DEF_LABEL = "Mock Label"; + + private static String DEFINITION_UUID = UUID.randomUUID().toString(); + private AlertDispatchDAO m_dao; + private AlertDefinitionDAO m_definitionDao; private Injector m_injector; + private AmbariManagementController m_amc; + private Clusters m_clusters; + private Cluster m_cluster; + @Before - public void before() { - m_dao = createStrictMock(AlertDispatchDAO.class); + public void before() throws Exception { + m_dao = createMock(AlertDispatchDAO.class); + m_definitionDao = createMock(AlertDefinitionDAO.class); + + m_amc = createMock(AmbariManagementController.class); + m_clusters = createMock(Clusters.class); + m_cluster = createMock(Cluster.class); m_injector = Guice.createInjector(Modules.override( new InMemoryDefaultTestModule()).with(new MockModule())); AlertGroupResourceProvider.init(m_injector); + + expect(m_amc.getClusters()).andReturn(m_clusters).atLeastOnce(); + expect(m_clusters.getCluster((String) anyObject())).andReturn(m_cluster).atLeastOnce(); + expect(m_cluster.getClusterId()).andReturn(Long.valueOf(1)).anyTimes(); } /** @@ -108,44 +144,41 @@ public class AlertGroupResourceProviderTest { AlertGroupResourceProvider.ALERT_GROUP_CLUSTER_NAME, AlertGroupResourceProvider.ALERT_GROUP_DEFAULT); - AmbariManagementController amc = createMock(AmbariManagementController.class); - Clusters clusters = createMock(Clusters.class); - Cluster cluster = createMock(Cluster.class); - expect(amc.getClusters()).andReturn(clusters).atLeastOnce(); - expect(clusters.getCluster((String) anyObject())).andReturn(cluster).atLeastOnce(); - expect(cluster.getClusterId()).andReturn(Long.valueOf(1)).anyTimes(); - Predicate predicate = new PredicateBuilder().property( AlertGroupResourceProvider.ALERT_GROUP_CLUSTER_NAME).equals("c1").toPredicate(); expect(m_dao.findAllGroups(ALERT_GROUP_CLUSTER_ID)).andReturn( getMockEntities()); - replay(amc, clusters, cluster, m_dao); + replay(m_amc, m_clusters, m_cluster, m_dao); - AlertGroupResourceProvider provider = createProvider(amc); + AlertGroupResourceProvider provider = createProvider(m_amc); Set<Resource> results = provider.getResources(request, predicate); assertEquals(1, results.size()); Resource r = results.iterator().next(); - Assert.assertEquals(ALERT_GROUP_NAME, + assertEquals(ALERT_GROUP_NAME, r.getPropertyValue(AlertGroupResourceProvider.ALERT_GROUP_NAME)); - Assert.assertEquals(ALERT_GROUP_ID, + assertEquals(ALERT_GROUP_ID, r.getPropertyValue(AlertGroupResourceProvider.ALERT_GROUP_ID)); - Assert.assertEquals(ALERT_GROUP_CLUSTER_NAME, + assertEquals(ALERT_GROUP_CLUSTER_NAME, r.getPropertyValue(AlertGroupResourceProvider.ALERT_GROUP_CLUSTER_NAME)); - verify(amc, clusters, cluster, m_dao); + // verify definitions do not come back in collections + assertNull(r.getPropertyValue(AlertGroupResourceProvider.ALERT_GROUP_DEFINITIONS)); + + verify(m_amc, m_clusters, m_cluster, m_dao); } /** * @throws Exception */ @Test + @SuppressWarnings("unchecked") public void testGetSingleResource() throws Exception { Request request = PropertyHelper.getReadRequest( AlertGroupResourceProvider.ALERT_GROUP_ID, @@ -173,15 +206,28 @@ public class AlertGroupResourceProviderTest { Resource r = results.iterator().next(); - Assert.assertEquals(ALERT_GROUP_NAME, + assertEquals(ALERT_GROUP_NAME, r.getPropertyValue(AlertGroupResourceProvider.ALERT_GROUP_NAME)); - Assert.assertEquals(ALERT_GROUP_ID, + assertEquals(ALERT_GROUP_ID, r.getPropertyValue(AlertGroupResourceProvider.ALERT_GROUP_ID)); - Assert.assertEquals(ALERT_GROUP_CLUSTER_NAME, + assertEquals(ALERT_GROUP_CLUSTER_NAME, r.getPropertyValue(AlertGroupResourceProvider.ALERT_GROUP_CLUSTER_NAME)); + // verify definitions and targets are returned on single instances + List<AlertDefinitionResponse> definitions = (List<AlertDefinitionResponse>) r.getPropertyValue(AlertGroupResourceProvider.ALERT_GROUP_DEFINITIONS); + List<AlertTarget> targets = (List<AlertTarget>) r.getPropertyValue(AlertGroupResourceProvider.ALERT_GROUP_TARGETS); + + assertNotNull(definitions); + assertNotNull(targets); + + assertEquals(1, definitions.size()); + assertEquals(ALERT_DEF_NAME, definitions.get(0).getName()); + + assertEquals(1, targets.size()); + assertEquals(ALERT_TARGET_NAME, targets.get(0).getName()); + verify(amc, m_dao); } @@ -190,21 +236,40 @@ public class AlertGroupResourceProviderTest { */ @Test public void testCreateResources() throws Exception { - AmbariManagementController amc = createMock(AmbariManagementController.class); - Clusters clusters = createMock(Clusters.class); - Cluster cluster = createMock(Cluster.class); - expect(amc.getClusters()).andReturn(clusters).atLeastOnce(); - expect(clusters.getCluster((String) anyObject())).andReturn(cluster).atLeastOnce(); - expect(cluster.getClusterId()).andReturn(Long.valueOf(1)).anyTimes(); - Capture<List<AlertGroupEntity>> listCapture = new Capture<List<AlertGroupEntity>>(); + // the definition IDs to associate with the group + List<Long> definitionIds = new ArrayList<Long>(); + definitionIds.add(ALERT_DEF_ID); + + // the target IDs to associate with the group + List<Long> targetIds = new ArrayList<Long>(); + targetIds.add(ALERT_TARGET_ID); + + // definition entities to return from DAO + List<AlertDefinitionEntity> definitionEntities = new ArrayList<AlertDefinitionEntity>(); + definitionEntities.addAll(getMockDefinitions()); + + // target entities to return from DAO + List<AlertTargetEntity> targetEntities = new ArrayList<AlertTargetEntity>(); + targetEntities.addAll(getMockTargets()); + + // expect create group m_dao.createGroups(capture(listCapture)); - expectLastCall(); + expectLastCall().once(); - replay(amc, clusters, cluster, m_dao); + // expect target entity lookup for association + expect(m_dao.findTargetsById(EasyMock.eq(targetIds))).andReturn( + targetEntities).times(1); + + // expect definition entity lookup for association + expect(m_definitionDao.findByIds(definitionIds)).andReturn( + definitionEntities).times(1); + + replay(m_amc, m_clusters, m_cluster, m_dao, m_definitionDao); + + AlertGroupResourceProvider provider = createProvider(m_amc); - AlertGroupResourceProvider provider = createProvider(amc); Map<String, Object> requestProps = new HashMap<String, Object>(); requestProps.put(AlertGroupResourceProvider.ALERT_GROUP_NAME, ALERT_GROUP_NAME); @@ -212,25 +277,109 @@ public class AlertGroupResourceProviderTest { requestProps.put(AlertGroupResourceProvider.ALERT_GROUP_CLUSTER_NAME, ALERT_GROUP_CLUSTER_NAME); + requestProps.put(AlertGroupResourceProvider.ALERT_GROUP_DEFINITIONS, + definitionIds); + + requestProps.put(AlertGroupResourceProvider.ALERT_GROUP_TARGETS, targetIds); + Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), null); provider.createResources(request); - Assert.assertTrue(listCapture.hasCaptured()); + assertTrue(listCapture.hasCaptured()); AlertGroupEntity entity = listCapture.getValue().get(0); - Assert.assertNotNull(entity); + assertNotNull(entity); - Assert.assertEquals(ALERT_GROUP_NAME, entity.getGroupName()); - Assert.assertEquals(ALERT_GROUP_CLUSTER_ID, + assertEquals(ALERT_GROUP_NAME, entity.getGroupName()); + assertEquals(ALERT_GROUP_CLUSTER_ID, entity.getClusterId().longValue()); - verify(amc, clusters, cluster, m_dao); + verify(m_amc, m_clusters, m_cluster, m_dao, m_definitionDao); } /** * @throws Exception */ @Test + @SuppressWarnings("unchecked") public void testUpdateResources() throws Exception { + Capture<AlertGroupEntity> entityCapture = new Capture<AlertGroupEntity>(); + + // the definition IDs to associate with the group + List<Long> definitionIds = new ArrayList<Long>(); + definitionIds.add(ALERT_DEF_ID); + + // the target IDs to associate with the group + List<Long> targetIds = new ArrayList<Long>(); + targetIds.add(ALERT_TARGET_ID); + + // definition entities to return from DAO + List<AlertDefinitionEntity> definitionEntities = new ArrayList<AlertDefinitionEntity>(); + definitionEntities.addAll(getMockDefinitions()); + + // target entities to return from DAO + List<AlertTargetEntity> targetEntities = new ArrayList<AlertTargetEntity>(); + targetEntities.addAll(getMockTargets()); + + m_dao.createGroups(EasyMock.anyObject(List.class)); + expectLastCall().times(1); + + AlertGroupEntity group = new AlertGroupEntity(); + expect(m_dao.findGroupById(ALERT_GROUP_ID)).andReturn( + group).times(1); + + expect(m_dao.merge(capture(entityCapture))).andReturn(group).once(); + + // expect target entity lookup for association + expect(m_dao.findTargetsById(EasyMock.eq(targetIds))).andReturn( + targetEntities).once(); + + // expect definition entity lookup for association + expect(m_definitionDao.findByIds(definitionIds)).andReturn( + definitionEntities).once(); + + replay(m_amc, m_clusters, m_cluster, m_dao, m_definitionDao); + + AlertGroupResourceProvider provider = createProvider(m_amc); + Map<String, Object> requestProps = new HashMap<String, Object>(); + requestProps.put(AlertGroupResourceProvider.ALERT_GROUP_NAME, + ALERT_GROUP_NAME); + + requestProps.put(AlertGroupResourceProvider.ALERT_GROUP_CLUSTER_NAME, + ALERT_GROUP_CLUSTER_NAME); + + Request request = PropertyHelper.getCreateRequest( + Collections.singleton(requestProps), null); + + provider.createResources(request); + + // create new properties, and include the ID since we're not going through + // a service layer which would add it for us automatically + requestProps = new HashMap<String, Object>(); + requestProps.put(AlertGroupResourceProvider.ALERT_GROUP_ID, + ALERT_GROUP_ID.toString()); + + String newName = ALERT_GROUP_NAME + " Foo"; + requestProps.put(AlertGroupResourceProvider.ALERT_GROUP_NAME, newName); + + requestProps.put(AlertGroupResourceProvider.ALERT_GROUP_DEFINITIONS, + definitionIds); + + requestProps.put(AlertGroupResourceProvider.ALERT_GROUP_TARGETS, targetIds); + + Predicate predicate = new PredicateBuilder().property( + AlertGroupResourceProvider.ALERT_GROUP_CLUSTER_NAME).equals( + ALERT_GROUP_CLUSTER_NAME).and().property( + AlertGroupResourceProvider.ALERT_GROUP_ID).equals( + ALERT_GROUP_ID.toString()).toPredicate(); + + request = PropertyHelper.getUpdateRequest(requestProps, null); + provider.updateResources(request, predicate); + + assertTrue(entityCapture.hasCaptured()); + + AlertGroupEntity entity = entityCapture.getValue(); + assertEquals(newName, entity.getGroupName()); + verify(m_amc, m_clusters, m_cluster, m_dao, m_definitionDao); } /** @@ -238,22 +387,15 @@ public class AlertGroupResourceProviderTest { */ @Test public void testDeleteResources() throws Exception { - AmbariManagementController amc = createMock(AmbariManagementController.class); - Clusters clusters = createMock(Clusters.class); - Cluster cluster = createMock(Cluster.class); - expect(amc.getClusters()).andReturn(clusters).atLeastOnce(); - expect(clusters.getCluster((String) anyObject())).andReturn(cluster).atLeastOnce(); - expect(cluster.getClusterId()).andReturn(Long.valueOf(1)).anyTimes(); - Capture<AlertGroupEntity> entityCapture = new Capture<AlertGroupEntity>(); Capture<List<AlertGroupEntity>> listCapture = new Capture<List<AlertGroupEntity>>(); m_dao.createGroups(capture(listCapture)); expectLastCall(); - replay(amc, clusters, cluster, m_dao); + replay(m_amc, m_clusters, m_cluster, m_dao); - AlertGroupResourceProvider provider = createProvider(amc); + AlertGroupResourceProvider provider = createProvider(m_amc); Map<String, Object> requestProps = new HashMap<String, Object>(); requestProps.put(AlertGroupResourceProvider.ALERT_GROUP_NAME, @@ -265,9 +407,9 @@ public class AlertGroupResourceProviderTest { Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), null); provider.createResources(request); - Assert.assertTrue(listCapture.hasCaptured()); + assertTrue(listCapture.hasCaptured()); AlertGroupEntity entity = listCapture.getValue().get(0); - Assert.assertNotNull(entity); + assertNotNull(entity); Predicate predicate = new PredicateBuilder().property( AlertGroupResourceProvider.ALERT_GROUP_CLUSTER_NAME).equals( @@ -287,9 +429,9 @@ public class AlertGroupResourceProviderTest { provider.deleteResources(predicate); AlertGroupEntity entity1 = entityCapture.getValue(); - Assert.assertEquals(ALERT_GROUP_ID, entity1.getGroupId()); + assertEquals(ALERT_GROUP_ID, entity1.getGroupId()); - verify(amc, clusters, cluster, m_dao); + verify(m_amc, m_clusters, m_cluster, m_dao); } /** @@ -298,6 +440,7 @@ public class AlertGroupResourceProviderTest { */ private AlertGroupResourceProvider createProvider( AmbariManagementController amc) { + return new AlertGroupResourceProvider( PropertyHelper.getPropertyIds(Resource.Type.AlertGroup), PropertyHelper.getKeyPropertyIds(Resource.Type.AlertGroup), amc); @@ -312,10 +455,57 @@ public class AlertGroupResourceProviderTest { entity.setGroupName(ALERT_GROUP_NAME); entity.setClusterId(ALERT_GROUP_CLUSTER_ID); entity.setDefault(false); + + entity.setAlertTargets(getMockTargets()); + entity.setAlertDefinitions(getMockDefinitions()); return Arrays.asList(entity); } /** + * Gets some mock {@link AlertDefinitionEntity} instances. + * + * @return + * @throws Exception + */ + private Set<AlertDefinitionEntity> getMockDefinitions() throws Exception { + AlertDefinitionEntity entity = new AlertDefinitionEntity(); + entity.setClusterId(Long.valueOf(1L)); + entity.setComponentName(null); + entity.setDefinitionId(ALERT_DEF_ID); + entity.setDefinitionName(ALERT_DEF_NAME); + entity.setLabel(ALERT_DEF_LABEL); + entity.setEnabled(true); + entity.setHash(DEFINITION_UUID); + entity.setScheduleInterval(Integer.valueOf(2)); + entity.setServiceName(null); + entity.setSourceType(SourceType.METRIC.name()); + entity.setSource(null); + + Set<AlertDefinitionEntity> definitions = new HashSet<AlertDefinitionEntity>(); + definitions.add(entity); + + return definitions; + } + + /** + * Gets some mock {@link AlertTargetEntity} instances. + * + * @return + */ + private Set<AlertTargetEntity> getMockTargets() throws Exception { + AlertTargetEntity entity = new AlertTargetEntity(); + entity.setTargetId(ALERT_TARGET_ID); + entity.setDescription(ALERT_TARGET_DESC); + entity.setTargetName(ALERT_TARGET_NAME); + entity.setNotificationType(ALERT_TARGET_TYPE); + + Set<AlertTargetEntity> targets = new HashSet<AlertTargetEntity>(); + targets.add(entity); + + return targets; + } + + /** * */ private class MockModule implements Module { @@ -325,10 +515,9 @@ public class AlertGroupResourceProviderTest { @Override public void configure(Binder binder) { binder.bind(AlertDispatchDAO.class).toInstance(m_dao); - binder.bind(Clusters.class).toInstance( - EasyMock.createNiceMock(Clusters.class)); - binder.bind(Cluster.class).toInstance( - EasyMock.createNiceMock(Cluster.class)); + binder.bind(AlertDefinitionDAO.class).toInstance(m_definitionDao); + binder.bind(Clusters.class).toInstance(m_clusters); + binder.bind(Cluster.class).toInstance(m_cluster); binder.bind(ActionMetadata.class); } } http://git-wip-us.apache.org/repos/asf/ambari/blob/76fc94ec/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProviderTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProviderTest.java index 982dd4b..6ca2035 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProviderTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProviderTest.java @@ -266,7 +266,7 @@ public class AlertTargetResourceProviderTest { entity.setTargetId(ALERT_TARGET_ID); entity.setDescription(ALERT_TARGET_DESC); entity.setTargetName(ALERT_TARGET_NAME); - entity.setNotificationType(TargetType.EMAIL.name()); + entity.setNotificationType(ALERT_TARGET_TYPE); return Arrays.asList(entity); } http://git-wip-us.apache.org/repos/asf/ambari/blob/76fc94ec/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java index a7ef513..a7cc066 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java @@ -22,6 +22,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; @@ -193,6 +194,21 @@ public class AlertDefinitionDAOTest { } /** + * + */ + @Test + public void testFindByIds() { + List<AlertDefinitionEntity> definitions = dao.findAll(); + List<Long> ids = new ArrayList<Long>(); + ids.add(definitions.get(0).getDefinitionId()); + ids.add(definitions.get(1).getDefinitionId()); + ids.add(99999L); + + definitions = dao.findByIds(ids); + assertEquals(2, definitions.size()); + } + + /** * */ @Test @@ -260,7 +276,7 @@ public class AlertDefinitionDAOTest { AlertDefinitionEntity definition = helper.createAlertDefinition(clusterId); AlertGroupEntity group = helper.createAlertGroup(clusterId, null); - group.getAlertDefinitions().add(definition); + group.addAlertDefinition(definition); dispatchDao.merge(group); AlertHistoryEntity history = new AlertHistoryEntity(); http://git-wip-us.apache.org/repos/asf/ambari/blob/76fc94ec/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 894f2c2..8451c9b 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 @@ -23,6 +23,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; @@ -56,7 +57,7 @@ public class AlertDispatchDAOTest { OrmTestHelper helper; /** - * + * */ @Before public void setup() throws Exception { @@ -92,7 +93,7 @@ public class AlertDispatchDAOTest { } /** - * + * */ @Test public void testFindAllTargets() throws Exception { @@ -102,7 +103,24 @@ public class AlertDispatchDAOTest { } /** - * + * @throws Exception + */ + public void testFindTargetsByIds() throws Exception { + List<AlertTargetEntity> targets = dao.findAllTargets(); + assertNotNull(targets); + assertEquals(5, targets.size()); + + List<Long> ids = new ArrayList<Long>(); + ids.add(targets.get(0).getTargetId()); + ids.add(targets.get(1).getTargetId()); + ids.add(99999L); + + targets = dao.findTargetsById(ids); + assertEquals(2, targets.size()); + } + + /** + * */ @Test public void testFindTargetByName() throws Exception { @@ -115,7 +133,7 @@ public class AlertDispatchDAOTest { } /** - * + * */ @Test public void testFindAllGroups() throws Exception { @@ -125,7 +143,7 @@ public class AlertDispatchDAOTest { } /** - * + * */ @Test public void testFindGroupByName() throws Exception { @@ -140,7 +158,7 @@ public class AlertDispatchDAOTest { } /** - * + * */ @Test public void testCreateGroup() throws Exception { @@ -159,7 +177,7 @@ public class AlertDispatchDAOTest { } /** - * + * */ @Test public void testGroupDefinitions() throws Exception { @@ -170,7 +188,10 @@ public class AlertDispatchDAOTest { group = dao.findGroupById(group.getGroupId()); assertNotNull(group); - group.getAlertDefinitions().addAll(definitions); + for (AlertDefinitionEntity definition : definitions) { + group.addAlertDefinition(definition); + } + dao.merge(group); group = dao.findGroupByName(group.getGroupName()); @@ -193,7 +214,7 @@ public class AlertDispatchDAOTest { } /** - * + * */ @Test public void testCreateTarget() throws Exception { @@ -222,12 +243,12 @@ public class AlertDispatchDAOTest { } /** - * + * */ @Test public void testDeleteGroup() throws Exception { - int targetCount = dao.findAllTargets().size(); - + int targetCount = dao.findAllTargets().size(); + AlertGroupEntity group = helper.createAlertGroup(clusterId, null); AlertTargetEntity target = helper.createAlertTarget(); assertEquals(targetCount + 1, dao.findAllTargets().size()); @@ -255,7 +276,7 @@ public class AlertDispatchDAOTest { } /** - * + * */ @Test public void testDeleteTarget() throws Exception { @@ -270,7 +291,7 @@ public class AlertDispatchDAOTest { } /** - * + * */ @Test public void testDeleteAssociatedTarget() throws Exception { @@ -298,7 +319,7 @@ public class AlertDispatchDAOTest { } /** - * + * */ @Test public void testUpdateGroup() throws Exception { @@ -319,8 +340,6 @@ public class AlertDispatchDAOTest { assertEquals(groupName + "FOO", group.getGroupName()); assertEquals(true, group.isDefault()); - assertNotNull(group.getAlertDefinitions()); - assertNotNull(group.getAlertTargets()); assertEquals(0, group.getAlertDefinitions().size()); assertEquals(0, group.getAlertTargets().size());