/* * RHQ Management Platform * Copyright 2013, Red Hat Middleware LLC, and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.rhq.enterprise.server.alert; import static org.rhq.core.domain.measurement.DataType.MEASUREMENT; import static org.rhq.core.domain.measurement.NumericType.DYNAMIC; import java.util.LinkedList; import java.util.List; import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.testng.annotations.Test; import org.rhq.core.domain.alert.AlertCondition; import org.rhq.core.domain.alert.AlertConditionCategory; import org.rhq.core.domain.alert.AlertDampening; import org.rhq.core.domain.alert.AlertDefinition; import org.rhq.core.domain.alert.AlertPriority; import org.rhq.core.domain.alert.BooleanExpression; import org.rhq.core.domain.auth.Subject; import org.rhq.core.domain.authz.Permission; import org.rhq.core.domain.authz.Role; import org.rhq.core.domain.criteria.AlertDefinitionCriteria; import org.rhq.core.domain.measurement.MeasurementDefinition; import org.rhq.core.domain.resource.Resource; import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.domain.resource.group.ResourceGroup; import org.rhq.core.domain.util.collection.ArrayUtils; import org.rhq.enterprise.server.auth.SubjectManagerLocal; import org.rhq.enterprise.server.authz.RoleManagerLocal; import org.rhq.enterprise.server.resource.group.ResourceGroupManagerLocal; import org.rhq.enterprise.server.test.AbstractEJB3Test; import org.rhq.enterprise.server.test.TransactionCallback; import org.rhq.enterprise.server.test.TransactionCallbackReturnable; import org.rhq.enterprise.server.util.LookupUtil; import org.rhq.enterprise.server.util.ResourceTreeHelper; import org.rhq.enterprise.server.util.SessionTestHelper; /** * @author Thomas Segismont */ public class AlertDefinitionManagerBeanTest extends AbstractEJB3Test { private static final Log LOG = LogFactory.getLog(AlertDefinitionManagerBeanTest.class); final private String prefix = this.getClass().getSimpleName() + "_"; final private String subjectName = prefix + "subject"; final private String roleName = prefix + "role"; final private String groupName = prefix + "group"; final private String resourceName = prefix + "resource"; final private String measurementDefName = prefix + "measurement"; private AlertDefinitionManagerLocal alertDefinitionManager; private ResourceGroupManagerLocal resourceGroupManager; private RoleManagerLocal roleManager; private SubjectManagerLocal subjectManager; private TestData testData; @Override protected void beforeMethod() throws Exception { alertDefinitionManager = LookupUtil.getAlertDefinitionManager(); subjectManager = LookupUtil.getSubjectManager(); resourceGroupManager = LookupUtil.getResourceGroupManager(); roleManager = LookupUtil.getRoleManager(); createTestData(); prepareScheduler(); } private void createTestData() { testData = executeInTransaction(false, new TransactionCallbackReturnable<TestData>() { @Override public TestData execute() throws Exception { TestData newTestData = new TestData(); Subject subject = SessionTestHelper.createNewSubject(em, subjectName); newTestData.setSubject(subject); Role role = SessionTestHelper.createNewRoleForSubject(em, subject, roleName, Permission.MANAGE_ALERTS); newTestData.setRole(role); ResourceType resourceType = SessionTestHelper.createNewResourceType(em); // To test bug 949048 we need a metric on the type MeasurementDefinition dynamicMeasuremenDef = new MeasurementDefinition(resourceType, measurementDefName); dynamicMeasuremenDef.setDefaultOn(true); dynamicMeasuremenDef.setDataType(MEASUREMENT); dynamicMeasuremenDef.setMeasurementType(DYNAMIC); em.persist(dynamicMeasuremenDef); newTestData.setResourceType(resourceType); ResourceGroup resourceGroup = new ResourceGroup(groupName, resourceType); resourceGroup = resourceGroupManager.createPrivateResourceGroup(subject, resourceGroup); newTestData.setResourceGroup(resourceGroup); roleManager.setAssignedResourceGroups(subjectManager.getOverlord(), role.getId(), new int[] { resourceGroup.getId() }); Resource resource = SessionTestHelper.createNewResourceForGroup(em, resourceGroup, resourceName); newTestData.setResource(resource); return newTestData; } }); } @Override protected void afterMethod() throws Exception { try { deleteTestData(); } finally { unprepareScheduler(); } } private void deleteTestData() throws Exception { if (testData != null) { // use the SLSB here, not just EM resourceGroupManager.deleteResourceGroup(subjectManager.getOverlord(), testData.getResourceGroup().getId()); for (Integer alertDefinitionId : testData.getAlertDefinitionIds()) { removeEntity(AlertDefinition.class, alertDefinitionId); } removeEntity(Resource.class, testData.getResource().getId()); removeEntity(ResourceType.class, testData.getResourceType().getId()); subjectManager.deleteSubjects(subjectManager.getOverlord(), new int[] { testData.getSubject().getId() }); roleManager.deleteRoles(subjectManager.getOverlord(), new int[] { testData.getRole().getId() }); testData = null; } } private void removeEntity(final Class<?> entityClass, final Object entityId) { try { executeInTransaction(false, new TransactionCallback() { @Override public void execute() throws Exception { Object object = em.find(entityClass, entityId); if (object instanceof Resource) { ResourceTreeHelper.deleteResource(em, (Resource) object); } else { em.remove(object); em.flush(); } } }); } catch (Exception e) { LOG.error("Failed to delete object from database: " + entityClass + "[id=" + entityId + "]", e); } } @Test public void testEnableAlertDefinitions() { executeInTransaction(new TransactionCallback() { @Override public void execute() throws Exception { List<Integer> alertDefinitionIds = new LinkedList<Integer>(); for (int i = 0; i < 50; i++) { alertDefinitionIds.add(createAlertDefinitionAndGetId(prefix + "alertdef_" + String.valueOf(i), false)); } List<Integer> alertDefinitionToEnableIds = alertDefinitionIds.subList(12, 37); int enabledCount = alertDefinitionManager.enableAlertDefinitions(testData.getSubject(), ArrayUtils.unwrapCollection(alertDefinitionToEnableIds)); assertEquals(alertDefinitionToEnableIds.size(), enabledCount); } }); } @Test public void testDisableAlertDefinitions() { executeInTransaction(new TransactionCallback() { @Override public void execute() throws Exception { List<Integer> alertDefinitionIds = new LinkedList<Integer>(); for (int i = 0; i < 50; i++) { alertDefinitionIds .add(createAlertDefinitionAndGetId(prefix + "alertdef_" + String.valueOf(i), true)); } List<Integer> alertDefinitionToDisableIds = alertDefinitionIds.subList(17, 48); int disabledCount = alertDefinitionManager.disableAlertDefinitions(testData.getSubject(), ArrayUtils.unwrapCollection(alertDefinitionToDisableIds)); assertEquals(alertDefinitionToDisableIds.size(), disabledCount); } }); } @Test public void testIsResourceOrGroupAlertDefinition() { executeInTransaction(new TransactionCallback() { @Override public void execute() throws Exception { int resourceAlertDefinitionId = createAlertDefinitionAndGetId(prefix + "resource_Alertdef", true); int groupAlertDefinitionId = createGroupAlertDefinitionAndGetId(prefix + "group_Alertdef"); assertTrue("Failed to detect a group alert definition", alertDefinitionManager.isGroupAlertDefinition(groupAlertDefinitionId)); assertFalse("Should not have detected a group alert definition", alertDefinitionManager.isGroupAlertDefinition(resourceAlertDefinitionId)); assertTrue("Failed to detect a resource alert definition", alertDefinitionManager.isResourceAlertDefinition(resourceAlertDefinitionId)); assertFalse("Should not have detected a resource alert definition", alertDefinitionManager.isResourceAlertDefinition(groupAlertDefinitionId)); } }); } @Test void testBug846451() { executeInTransaction(new TransactionCallback() { @Override public void execute() throws Exception { String name = prefix + "group_Alertdef"; int groupAlertDefinitionId = createGroupAlertDefinitionAndGetId(name); AlertDefinitionCriteria criteria = new AlertDefinitionCriteria(); criteria.addFilterResourceGroupIds(testData.getResourceGroup().getId()); // tests the reported bug List<AlertDefinition> result = alertDefinitionManager.findAlertDefinitionsByCriteria( testData.getSubject(), criteria); assertNotNull(result); assertEquals(1, result.size()); assertEquals(name, result.get(0).getName()); } }); } @Test void testAddRemoveGroupMembers() throws Exception { Resource resource2 = null; Resource resource3 = null; try { // creating alert definitions is performed in a new transaction. So, any involved entities must already be // committed. Commit the additional test entities here. This stuff will get cleaned up in afterMethod startTransaction(); String name = prefix + "group_Alertdef"; int groupAlertDefinitionId = createGroupAlertDefinitionAndGetId(name); String resource2Name = resourceName + "_2"; String resource3Name = resourceName + "_3"; resource2 = SessionTestHelper.createNewResource(em, resource2Name, testData.getResourceType()); resource3 = SessionTestHelper.createNewResource(em, resource3Name, testData.getResourceType()); commitTransaction(); // add new members and ensure the resource-level alert defs gets applied. Make sure to use the SLSB to add it LookupUtil.getResourceGroupManager().addResourcesToGroup(subjectManager.getOverlord(), testData.getResourceGroup().getId(), new int[] { resource2.getId() }); LookupUtil.getResourceGroupManager().addResourcesToGroup(subjectManager.getOverlord(), testData.getResourceGroup().getId(), new int[] { resource3.getId() }); int[] ids = new int[] { resource2.getId(), resource3.getId() }; AlertDefinitionCriteria criteria = new AlertDefinitionCriteria(); criteria.fetchConditions(true); criteria.addFilterResourceIds(ids[0], ids[1]); List<AlertDefinition> result = alertDefinitionManager.findAlertDefinitionsByCriteria(testData.getSubject(), criteria); assertNotNull(result); assertEquals(2, result.size()); assertEquals(name, result.get(0).getName()); assertEquals(name, result.get(1).getName()); assertTrue(result.get(0).getId() != result.get(1).getId()); assertEquals(1, result.get(0).getConditions().size()); assertEquals(1, result.get(1).getConditions().size()); // remove one member and ensure the alert def gets removed and no other members are affected (bug 949062) LookupUtil.getResourceGroupManager().removeResourcesFromGroup(subjectManager.getOverlord(), testData.getResourceGroup().getId(), new int[] { resource2.getId() }); result = alertDefinitionManager.findAlertDefinitionsByCriteria(testData.getSubject(), criteria); assertNotNull(result); assertEquals(1, result.size()); // now the other one LookupUtil.getResourceGroupManager().removeResourcesFromGroup(subjectManager.getOverlord(), testData.getResourceGroup().getId(), new int[] { resource3.getId() }); result = alertDefinitionManager.findAlertDefinitionsByCriteria(testData.getSubject(), criteria); assertNotNull(result); assertEquals(0, result.size()); } finally { Resource[] resources = new Resource[] { resource2, resource3 }; try { startTransaction(); for (Resource r : resources) { if (null != r) { r = em.find(Resource.class, r.getId()); Set<AlertDefinition> ads = r.getAlertDefinitions(); for (AlertDefinition ad : ads) { em.remove(ad); } ResourceTreeHelper.deleteResource(em, r); } } commitTransaction(); } catch (Exception e) { rollbackTransaction(); } } } private int createAlertDefinitionAndGetId(String name, boolean enabled) { AlertDefinition alertDefinition = new AlertDefinition(); alertDefinition.setName(name); alertDefinition.setPriority(AlertPriority.MEDIUM); alertDefinition.setAlertDampening(new AlertDampening(AlertDampening.Category.NONE)); alertDefinition.setConditionExpression(BooleanExpression.ANY); alertDefinition.setRecoveryId(0); alertDefinition.setEnabled(enabled); alertDefinition = alertDefinitionManager.createAlertDefinitionInNewTransaction(testData.getSubject(), alertDefinition, testData.getResource().getId(), true); testData.getAlertDefinitionIds().add(alertDefinition.getId()); return alertDefinition.getId(); } private int createGroupAlertDefinitionAndGetId(String name) { AlertDefinition alertDefinition = new AlertDefinition(); alertDefinition.setName(name); alertDefinition.setPriority(AlertPriority.MEDIUM); alertDefinition.setAlertDampening(new AlertDampening(AlertDampening.Category.NONE)); alertDefinition.setConditionExpression(BooleanExpression.ANY); alertDefinition.setRecoveryId(0); alertDefinition.setGroup(testData.getResourceGroup()); alertDefinition.setEnabled(true); // We need a threshold alert condition to recreate the issue in bug 949048 AlertCondition ac = new AlertCondition(); ac.setCategory(AlertConditionCategory.THRESHOLD); ac.setMeasurementDefinition(testData.getMeasurementDef()); ac.setComparator("<"); ac.setThreshold(0.5); alertDefinition.addCondition(ac); AlertDefinition newAlertDefinition = alertDefinitionManager.createAlertDefinitionInNewTransaction( testData.getSubject(), alertDefinition, null, true); testData.getAlertDefinitionIds().add(newAlertDefinition.getId()); return newAlertDefinition.getId(); } private static final class TestData { private Subject subject; private Role role; private ResourceType resourceType; private MeasurementDefinition measurementDef; private ResourceGroup resourceGroup; private Resource resource; private List<Integer> alertDefinitionIds = new LinkedList<Integer>(); public Subject getSubject() { return subject; } public void setSubject(Subject subject) { this.subject = subject; } public Role getRole() { return role; } public void setRole(Role role) { this.role = role; } public ResourceType getResourceType() { return resourceType; } public void setResourceType(ResourceType resourceType) { this.resourceType = resourceType; } public MeasurementDefinition getMeasurementDef() { return measurementDef; } public void setMeasurementDef(MeasurementDefinition measurementDef) { this.measurementDef = measurementDef; } public ResourceGroup getResourceGroup() { return resourceGroup; } public void setResourceGroup(ResourceGroup resourceGroup) { this.resourceGroup = resourceGroup; } public Resource getResource() { return resource; } public void setResource(Resource resource) { this.resource = resource; } public List<Integer> getAlertDefinitionIds() { return alertDefinitionIds; } } }