View Javadoc

1   /**
2    * Copyright 2005-2013 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.kew.plugin;
17  
18  import static org.junit.Assert.assertEquals;
19  import static org.junit.Assert.assertFalse;
20  import static org.junit.Assert.assertNotNull;
21  import static org.junit.Assert.assertTrue;
22  
23  import java.io.File;
24  
25  import javax.xml.namespace.QName;
26  
27  import org.apache.commons.io.FileUtils;
28  import org.junit.Test;
29  import org.kuali.rice.core.api.config.CoreConfigHelper;
30  import org.kuali.rice.kew.test.KEWTestCase;
31  import org.kuali.rice.kew.test.TestUtilities;
32  
33  
34  /**
35   * Tests the HotDeployer and Reloader which handle hot deployment and hot reloading
36   * of Plugins.
37   *
38   * @author Kuali Rice Team (rice.collab@kuali.org)
39   */
40  public class HotDeployTest extends KEWTestCase {
41  
42  	private File pluginDir;
43  	
44  	@Override
45  	public void setUp() throws Exception {
46          super.setUp();
47  		TestUtilities.initializePluginDirectories();
48  		this.pluginDir = TestUtilities.getPluginsDirectory(); 
49  	}
50  		
51  	@Override
52  	public void tearDown() throws Exception {
53  		super.tearDown();
54  		TestUtilities.cleanupPluginDirectories();
55  	}
56  
57  	@Test public void testHotDeploy() throws Exception {
58  		// Grab the ServerPluginRegistry
59  		PluginRegistry theRegistry = PluginUtils.getPluginRegistry();
60  		assertNotNull("PluginRegistry should exist.", theRegistry);
61  		assertTrue(theRegistry instanceof ServerPluginRegistry);
62  		ServerPluginRegistry registry = (ServerPluginRegistry)theRegistry; 
63  		
64  		// Let's shut down the asynchronous reloader and hot deployer because we want to do this synchronously.
65  		HotDeployer hotDeployer = registry.getHotDeployer();
66  		Reloader reloader = registry.getReloader();
67  		registry.stopHotDeployer();
68  		registry.stopReloader();
69  		
70  		// Assert that there are currently no plugins
71  		assertEquals("There should be no plugins.", 0, registry.getPluginEnvironments().size());
72  		assertEquals("Resource loader should have no children.", 0, registry.getResourceLoaders().size());
73  		
74  		// query the hot deployer directly about it's added and removed plugins
75  		assertEquals("There should be no plugins added.", 0, hotDeployer.getAddedPlugins().size());
76  		assertEquals("There should be no plugins removed.", 0, hotDeployer.getRemovedPlugins().size());
77  		hotDeployer.run();
78  		assertEquals("There should still be no plugins.", 0, registry.getPluginEnvironments().size());
79  		
80  		// now let's copy a plugin over and run the hot deployer
81          String pluginZipFileLocation = getBaseDir() + "/src/test/resources/org/kuali/rice/kew/plugin/ziptest.zip";
82  		File pluginZipFile = new File(pluginZipFileLocation);
83  		assertTrue("Plugin file '" + pluginZipFileLocation + "' should exist", pluginZipFile.exists());
84  		assertTrue("Plugin file '" + pluginZipFileLocation + "' should be a file", pluginZipFile.isFile());
85  		FileUtils.copyFileToDirectory(pluginZipFile, pluginDir);
86  			
87  		assertEquals("There should be one plugin added.", 1, hotDeployer.getAddedPlugins().size());
88  		assertEquals("There should be no plugins removed.", 0, hotDeployer.getRemovedPlugins().size());
89  			
90  		hotDeployer.run();
91  			
92  		// the plugin should have been hot deployed
93  		assertEquals("Plugin should have been hot deployed.", 1, registry.getPluginEnvironments().size());
94  		
95  		// check added plugins again, it should now indicate no new added plugins
96  		assertEquals("There should be no plugins added.", 0, hotDeployer.getAddedPlugins().size());
97  		assertEquals("There should be no plugins removed.", 0, hotDeployer.getRemovedPlugins().size());
98  		
99  		// verify that the resource loading and the registry are sane and properly set up with the new plugin
100 		assertEquals("Resource loader should have 1 plugin child.", 1, registry.getResourceLoaders().size());
101 		Plugin plugin = (Plugin)registry.getResourceLoaders().get(0);
102 		assertEquals("Plugin has wrong name.", new QName(CoreConfigHelper.getApplicationId(), "ziptest"), plugin.getName());
103 		assertTrue("Plugin should be started.", plugin.isStarted());
104 		assertEquals("Plugin in resource loader and environment should be the same.", plugin, registry.getPluginEnvironment(plugin.getName().getLocalPart()).getPlugin());
105 		
106 		// The reloader should have a reference to the environment
107 		assertEquals("Reloader should have a reference to environment.", 1, reloader.getReloadables().size());
108 		
109 		// now remove the plugin and ensure that it goes away
110 		FileUtils.forceDelete(new File(pluginDir, "ziptest.zip"));
111 		assertEquals("There should be no plugins added.", 0, hotDeployer.getAddedPlugins().size());
112 		assertEquals("There should be one plugin removed.", 1, hotDeployer.getRemovedPlugins().size());
113 		hotDeployer.run();
114 		
115 		// verify that the resource loading and the registry no longer contain the plugin
116 		assertEquals("No plugins should be deployed.", 0, registry.getPluginEnvironments().size());
117 		assertEquals("Resource loader should have 0 plugin children.", 0, registry.getResourceLoaders().size());
118 		
119 		// also assert that the reloader no longer has a reference to the environment
120 		assertEquals("Reloader should no longer have reference to environment.", 0, reloader.getReloadables().size());
121 				
122 	}
123 	
124 	@Test public void testReloader() throws Exception {
125 		// Grab the ServerPluginRegistry
126 		PluginRegistry theRegistry = PluginUtils.getPluginRegistry();
127 		assertNotNull("PluginRegistry should exist.", theRegistry);
128 		assertTrue(theRegistry instanceof ServerPluginRegistry);
129 		ServerPluginRegistry registry = (ServerPluginRegistry)theRegistry; 
130 		
131 		// Let's shut down the asynchronous reloader and hot deployer because we want to do this synchronously.
132 		HotDeployer hotDeployer = registry.getHotDeployer();
133 		Reloader reloader = registry.getReloader();
134 		registry.stopHotDeployer();
135 		registry.stopReloader();
136 		
137 		// Assert that there are currently no plugins
138 		assertEquals("There should be no plugins.", 0, registry.getPluginEnvironments().size());
139 		assertEquals("Resource loader should have no children.", 0, registry.getResourceLoaders().size());
140 				
141         // now let's copy a plugin over and run the hot deployer
142         String pluginZipFileLocation = getBaseDir() + "/src/test/resources/org/kuali/rice/kew/plugin/ziptest.zip";
143         File pluginZipFile = new File(pluginZipFileLocation);
144         assertTrue("Plugin file '" + pluginZipFileLocation + "' should exist", pluginZipFile.exists());
145         assertTrue("Plugin file '" + pluginZipFileLocation + "' should be a file", pluginZipFile.isFile());
146         FileUtils.copyFileToDirectory(pluginZipFile, pluginDir);
147 		
148 		// update pluginZipFile to point to the copy
149 		pluginZipFile = new File(pluginDir, pluginZipFile.getName());
150 		assertTrue(pluginZipFile.exists());
151 		
152 		// execute a hot deploy
153 		hotDeployer.run();
154 			
155 		// the plugin should have been hot deployed
156 		assertEquals("Plugin should have been hot deployed.", 1, registry.getPluginEnvironments().size());
157 		assertEquals("Resource loader should have 1 plugin child.", 1, registry.getResourceLoaders().size());
158 		PluginEnvironment environment = registry.getPluginEnvironments().get(0);
159 		Plugin plugin = environment.getPlugin();
160 		assertTrue(environment.isReloadable());
161 		assertFalse(environment.isReloadNeeded());
162 		
163 		// let's attempt to execute a Reload
164 		reloader.run();
165 		
166 		// a reload should not have occurred here since nothing was updated
167 		assertTrue("Original plugin should still be running.", plugin.isStarted());
168 		assertEquals("Plugin should not have changed.", plugin, registry.getPluginEnvironments().get(0).getPlugin());
169 		
170 		// touch the plugin file and then reload
171 		FileUtils.touch(pluginZipFile);
172 		assertTrue("A reload should be needed now.", environment.isReloadNeeded());
173 		reloader.run();
174 		
175 		// the original plugin should now be stopped
176 		assertTrue("original plugin should be stopped.", !plugin.isStarted());
177 		assertEquals("There should only be one Plugin.", 1, registry.getResourceLoaders().size());
178 		
179 		PluginEnvironment newPluginEnvironment = registry.getPluginEnvironments().get(0);
180 		Plugin newPlugin = newPluginEnvironment.getPlugin();
181 		assertEquals("There should still only be one environment.", 1, registry.getPluginEnvironments().size());
182 		assertEquals("The plugin environments should still be the same.", environment, registry.getPluginEnvironments().get(0));
183 		
184 		assertFalse("The old and new plugins should be different.", newPlugin.equals(plugin));
185 		
186 		// verify that the resource loader was updated
187 		assertEquals("The resource loaders should have been updated with the new plugin.", newPlugin, registry.getResourceLoaders().get(0));
188 		
189 	}
190 
191 	
192 }