1 /* 2 * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. 3 * 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * The contents of this file are subject to the terms of either the Universal Permissive License 7 * v 1.0 as shown at http://oss.oracle.com/licenses/upl 8 * 9 * or the following license: 10 * 11 * Redistribution and use in source and binary forms, with or without modification, are permitted 12 * provided that the following conditions are met: 13 * 14 * 1. Redistributions of source code must retain the above copyright notice, this list of conditions 15 * and the following disclaimer. 16 * 17 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of 18 * conditions and the following disclaimer in the documentation and/or other materials provided with 19 * the distribution. 20 * 21 * 3. Neither the name of the copyright holder nor the names of its contributors may be used to 22 * endorse or promote products derived from this software without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 26 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 30 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY 31 * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 package org.openjdk.jmc.rjmx.test.triggers; 34 35 import static org.junit.Assert.assertEquals; 36 import static org.junit.Assert.assertNotNull; 37 import static org.junit.Assert.assertTrue; 38 import static org.junit.Assert.fail; 39 40 import java.io.IOException; 41 import java.util.UUID; 42 43 import javax.management.JMException; 44 import javax.security.auth.login.FailedLoginException; 45 46 import org.junit.Before; 47 import org.junit.Test; 48 49 import org.openjdk.jmc.common.unit.IUnit; 50 import org.openjdk.jmc.common.unit.UnitLookup; 51 import org.openjdk.jmc.rjmx.ConnectionToolkit; 52 import org.openjdk.jmc.rjmx.subscription.IMRIMetadata; 53 import org.openjdk.jmc.rjmx.subscription.MRI; 54 import org.openjdk.jmc.rjmx.subscription.MRI.Type; 55 import org.openjdk.jmc.rjmx.test.RjmxTestCase; 56 import org.openjdk.jmc.rjmx.test.testutil.TestToolkit; 57 import org.openjdk.jmc.rjmx.test.triggers.NotificationActionCallback.NotificationActionCallbackReceiver; 58 import org.openjdk.jmc.rjmx.triggers.TriggerEvent; 59 import org.openjdk.jmc.rjmx.triggers.TriggerRule; 60 import org.openjdk.jmc.rjmx.triggers.internal.NotificationRegistry; 61 import org.openjdk.jmc.rjmx.triggers.internal.NotificationTrigger; 62 import org.openjdk.jmc.rjmx.triggers.internal.ValueEvaluatorBoolean; 63 import org.openjdk.jmc.rjmx.triggers.internal.ValueEvaluatorNumberMax; 64 65 /** 66 * Tests for the notification framework. 67 */ 68 public class NotificationTriggerAndRuleTest extends RjmxTestCase 69 implements NotificationActionCallback.NotificationActionCallbackReceiver { 70 /** For code coverage */ 71 72 public final static int TIMEOUT = 9000; 73 public static final Class<?>[] COVERED_CLASSES = new Class[] { 74 // NotificationRule.class, 75 NotificationTrigger.class}; 76 77 private TriggerEvent m_lastEvent; 78 private final Object m_notifObj = new Object(); 79 private NotificationRegistry m_notificationRegistry; 80 81 /** 82 * Tests registering and unregistering a rule. 83 * 84 * @throws IOException 85 * @throws FailedLoginException 86 */ 87 @Test 88 public void testUnregisterRule() throws FailedLoginException, IOException { 89 TriggerRule rule = createTestNotificationRule( 90 new MRI(Type.ATTRIBUTE, "java.lang:type=OperatingSystem", "SystemCpuLoad")); 91 String serverGuid = UUID.randomUUID().toString(); 92 m_notificationRegistry.registerRule(rule, serverGuid); 93 m_notificationRegistry.unregisterRule(rule, serverGuid); 94 assertEquals("Failed to remove rule!", m_notificationRegistry.getRegisteredRules(serverGuid).size(), 0); 95 } 96 97 /** 98 * Tests that a notification rule triggers correctly. 99 * 100 * @throws JMException 101 * @throws IOException 102 * @throws InterruptedException 103 */ 104 @Test 105 public void testTriggerNotification() throws Exception { 106 assertNull(m_lastEvent); 107 TriggerRule rule = createRule(); 108 String serverGuid = m_connectionHandle.getServerDescriptor().getGUID(); 109 m_notificationRegistry.activateTriggersFor(m_connectionHandle); 110 m_notificationRegistry.registerRule(rule, serverGuid); 111 assertEquals("Didn't register rule!", 1, m_notificationRegistry.getRegisteredRules(serverGuid).size()); 112 synchronized (m_notifObj) { 113 114 try { 115 m_notifObj.wait(TIMEOUT); 116 } catch (InterruptedException e) { 117 fail("Timedout while waiting for notification!"); 118 } 119 } 120 m_notificationRegistry.unregisterRule(rule, serverGuid); 121 assertNotNull("Never received any notification!", m_lastEvent); 122 } 123 124 /** 125 * Tests creating a rule and that it is setup correctly. 126 * 127 * @throws IOException 128 * @throws FailedLoginException 129 */ 130 @Test 131 public void testRuleCreation() throws FailedLoginException, IOException { 132 TriggerRule aRule = new TriggerRule(); 133 assertNotNull(aRule); 134 assertTrue(!aRule.hasAction()); 135 assertTrue(!aRule.hasTrigger()); 136 assertTrue(!aRule.isComplete()); 137 138 TriggerRule anotherRule = createTestNotificationRule( 139 new MRI(Type.ATTRIBUTE, "java.lang:type=OperatingSystem", "SystemCpuLoad")); 140 assertTrue(anotherRule.hasAction()); 141 assertTrue(!anotherRule.hasConstraints()); 142 assertTrue(anotherRule.hasTrigger()); 143 assertTrue(anotherRule.isComplete()); 144 assertEquals("TestRule", anotherRule.toString()); 145 assertEquals("TestRule", anotherRule.getName()); 146 147 aRule.setName("Abrakadabra"); 148 // Test sorting 149 assertTrue(aRule.compareTo(anotherRule) < 0); 150 } 151 152 private TriggerRule createTestNotificationRule(MRI descriptor) { 153 NotificationTrigger trigger = new NotificationTrigger(descriptor, new ValueEvaluatorBoolean()); 154 return new TriggerRule("TestRule", trigger, new NotificationActionCallback(this)); 155 } 156 157 /** 158 * @see NotificationActionCallbackReceiver#callback(TriggerEvent) 159 */ 160 @Override 161 public void onNotificationAction(TriggerEvent e) { 162 synchronized (m_notifObj) { 163 TestToolkit.println("Got a callback: " + e); 164 m_lastEvent = e; 165 m_notifObj.notify(); 166 } 167 } 168 169 /** 170 * Registers a rule used by the test. 171 * 172 * @return the new rule 173 * @throws JMException 174 * @throws IOException 175 */ 176 protected TriggerRule createRule() throws Exception { 177 MRI uptimeDescriptor = new MRI(Type.ATTRIBUTE, "java.lang:type=Runtime", 178 "Uptime"); 179 long uptime = ConnectionToolkit.getRuntimeBean(getMBeanServerConnection()).getUptime(); 180 IMRIMetadata metadata = getMRIMetadataService().getMetadata(uptimeDescriptor); 181 IUnit unit = UnitLookup.getUnitOrDefault(metadata.getUnitString()); 182 TriggerRule rule = createTestNotificationRule(uptimeDescriptor); 183 ValueEvaluatorNumberMax eval = new ValueEvaluatorNumberMax(); 184 eval.setMax(unit.quantity(uptime)); 185 rule.setTrigger(new NotificationTrigger(uptimeDescriptor, eval)); 186 return rule; 187 } 188 189 @Before 190 public void setUp() throws Exception { 191 m_notificationRegistry = new NotificationRegistry(); 192 } 193 }