/***************************************************************************** * * Copyright (C) Zenoss, Inc. 2010, all rights reserved. * * This content is made available according to terms specified in * License.zenoss under the directory where your Zenoss product is installed. * ****************************************************************************/ package org.zenoss.zep.impl; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests; import org.zenoss.protobufs.zep.Zep.Event; import org.zenoss.protobufs.zep.Zep.EventSummary; import org.zenoss.zep.ZepException; import org.zenoss.zep.plugins.EventPostIndexContext; import org.zenoss.zep.plugins.EventPostIndexPlugin; import org.zenoss.zep.plugins.EventPreCreateContext; import org.zenoss.zep.plugins.EventPreCreatePlugin; import org.zenoss.zep.plugins.exceptions.DependencyCycleException; import org.zenoss.zep.plugins.exceptions.MissingDependencyException; import java.io.IOException; import java.io.InputStream; 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.Properties; import java.util.Set; import static org.junit.Assert.*; @ContextConfiguration("classpath:zep-test-plugins.xml") public class PluginServiceImplTest extends AbstractJUnit4SpringContextTests { @Autowired public PluginServiceImpl pluginService; @Test public void testInit() throws IOException { Properties properties = new Properties(); InputStream is = null; try { is = getClass().getResourceAsStream("/test-zeneventserver.conf"); properties.load(is); } finally { if (is != null) { is.close(); } } pluginService.initializePlugins(); List<EventPreCreatePlugin> prePlugins = pluginService.getPluginsByType(EventPreCreatePlugin.class); assertEquals(3, prePlugins.size()); List<EventPostIndexPlugin> postPlugins = pluginService.getPluginsByType(EventPostIndexPlugin.class); assertEquals(2, postPlugins.size()); /* Verify order */ assertEquals("MyPrePlugin3", prePlugins.get(0).getId()); assertEquals("MyPrePlugin2", prePlugins.get(1).getId()); assertEquals(properties.getProperty("plugin.MyPrePlugin2.prop2"), prePlugins.get(1).getProperties().get("prop2")); assertEquals("MyPrePlugin1", prePlugins.get(2).getId()); assertEquals("MyPostPlugin2", postPlugins.get(0).getId()); assertEquals("MyPostPlugin1", postPlugins.get(1).getId()); assertEquals(properties.getProperty("plugin.MyPostPlugin1.myprop.name"), postPlugins.get(1).getProperties().get("myprop.name")); } @Test public void testCycleDetection() throws MissingDependencyException { EventPreCreatePlugin plugin1 = new EventPreCreatePlugin() { @Override public String getId() { return "Plugin1"; } @Override public Set<String> getDependencies() { return Collections.singleton("Plugin2"); } @Override public Event processEvent(Event event, EventPreCreateContext ctx) throws ZepException { return event; } }; EventPreCreatePlugin plugin2 = new EventPreCreatePlugin() { @Override public String getId() { return "Plugin2"; } @Override public Set<String> getDependencies() { return Collections.singleton("Plugin3"); } @Override public Event processEvent(Event event, EventPreCreateContext ctx) throws ZepException { return event; } }; EventPreCreatePlugin plugin3 = new EventPreCreatePlugin() { @Override public String getId() { return "Plugin3"; } @Override public Set<String> getDependencies() { return Collections.singleton("Plugin1"); } @Override public Event processEvent(Event event, EventPreCreateContext ctx) throws ZepException { return event; } }; Map<String, EventPreCreatePlugin> plugins = new HashMap<String, EventPreCreatePlugin>(); plugins.put(plugin1.getId(), plugin1); plugins.put(plugin2.getId(), plugin2); plugins.put(plugin3.getId(), plugin3); try { PluginServiceImpl.detectCycles(plugins, Collections.<String> emptySet()); fail("Expected to fail with a cycle exception"); } catch (DependencyCycleException e) { /* Expected */ } } @Test public void testMissingDependency() throws DependencyCycleException, MissingDependencyException { EventPreCreatePlugin plugin1 = new EventPreCreatePlugin() { @Override public String getId() { return "Plugin1"; } @Override public Set<String> getDependencies() { return Collections.singleton("PluginNotFound"); } @Override public Event processEvent(Event event, EventPreCreateContext ctx) throws ZepException { return event; } }; try { PluginServiceImpl.detectCycles(Collections .<String, EventPreCreatePlugin> singletonMap( plugin1.getId(), plugin1), Collections .<String> emptySet()); fail("Expected MissingDependencyException"); } catch (MissingDependencyException e) { assertEquals(plugin1.getId(), e.getPluginId()); assertEquals(plugin1.getDependencies().iterator().next(), e.getDependencyId()); } /* * Verify if we pass in the plug-in as an existing dependency no error * is thrown. */ PluginServiceImpl.detectCycles(Collections .<String, EventPreCreatePlugin> singletonMap( plugin1.getId(), plugin1), Collections.<String> singleton(plugin1.getDependencies() .iterator().next())); } public static final class MyPrePlugin1 extends EventPreCreatePlugin { @Override public String getId() { return getClass().getSimpleName(); } @Override public Event processEvent(Event event, EventPreCreateContext ctx) throws ZepException { return event; } @Override public Set<String> getDependencies() { return Collections.singleton("MyPrePlugin2"); } @Override public String toString() { return getClass().getSimpleName() + "[" + this.properties + "]"; } } public static final class MyPrePlugin2 extends EventPreCreatePlugin { @Override public String getId() { return getClass().getSimpleName(); } @Override public Event processEvent(Event event, EventPreCreateContext ctx) throws ZepException { return event; } @Override public Set<String> getDependencies() { return Collections.singleton("MyPrePlugin3"); } @Override public String toString() { return getClass().getSimpleName() + "[" + this.properties + "]"; } } public static final class MyPrePlugin3 extends EventPreCreatePlugin { @Override public Event processEvent(Event event, EventPreCreateContext ctx) throws ZepException { return event; } } public static final class MyPostPlugin1 extends EventPostIndexPlugin { @Override public Set<String> getDependencies() { return new HashSet<String>(Arrays.asList("MyPrePlugin1", "MyPostPlugin2")); } @Override public void processEvent(EventSummary eventSummary, EventPostIndexContext context) throws ZepException { } } public static final class MyPostPlugin2 extends EventPostIndexPlugin { @Override public void processEvent(EventSummary eventSummary, EventPostIndexContext context) throws ZepException { } } }