modules/enterprise/server/appserver/src/main/scripts/rhq-container.build.xml | 4 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/StartupBean.java | 2 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/concurrency/LatchedServiceCircularityException.java | 44 - modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/concurrency/LatchedServiceController.java | 340 ---------- modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/concurrency/LatchedServiceException.java | 44 - modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/ProductPluginDeployer.java | 75 +- modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/core/concurrency/LatchedServiceCircularDependenciesTest.java | 120 --- modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/core/concurrency/LatchedServiceDependenciesTest.java | 97 -- 8 files changed, 38 insertions(+), 688 deletions(-)
New commits: commit 1a595ef3ddf30727ae606b801d78eb70cf97fac4 Author: John Mazzitelli mazz@redhat.com Date: Mon Sep 17 16:03:53 2012 -0400
rip out the latched service stuff - we don't concurrently deploy plugins anyway.
diff --git a/modules/enterprise/server/appserver/src/main/scripts/rhq-container.build.xml b/modules/enterprise/server/appserver/src/main/scripts/rhq-container.build.xml index c878ef4..3a0eab8 100644 --- a/modules/enterprise/server/appserver/src/main/scripts/rhq-container.build.xml +++ b/modules/enterprise/server/appserver/src/main/scripts/rhq-container.build.xml @@ -380,10 +380,6 @@ rhq.server.startup.ajp.port=9009 rhq.server.startup.unifiedinvoker.port=5446 rhq.server.startup.aspectdeployer.bind-port=4873
-# The number of concurrent threads used to deploy plugins. -# Currently, it is not recommended to increase this value. -rhq.server.plugin-deployer-threads=1 - # RHQ Server's remote endpoint for agents to talk to # bind-address and bind-port are derived from the HA server definition, # if you set the address/port here, they will override the HA server definition found in the database diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/StartupBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/StartupBean.java index b697493..0c24dbf 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/StartupBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/StartupBean.java @@ -130,7 +130,7 @@ public class StartupBean { * @throws RuntimeException */ @PostConstruct - @TransactionAttribute(TransactionAttributeType.NEVER) + @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) public void init() throws RuntimeException { initialized = false;
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/concurrency/LatchedServiceCircularityException.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/concurrency/LatchedServiceCircularityException.java deleted file mode 100644 index e4a4df3..0000000 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/concurrency/LatchedServiceCircularityException.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 Red Hat, Inc. - * All rights reserved. - * - * 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.core.concurrency; - -/** - * @author Joseph Marques - */ -public class LatchedServiceCircularityException extends LatchedServiceException { - - private static final long serialVersionUID = 1L; - - public LatchedServiceCircularityException() { - super(); - } - - public LatchedServiceCircularityException(String message, Throwable cause) { - super(message, cause); - } - - public LatchedServiceCircularityException(String message) { - super(message); - } - - public LatchedServiceCircularityException(Throwable cause) { - super(cause); - } - -} diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/concurrency/LatchedServiceController.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/concurrency/LatchedServiceController.java deleted file mode 100644 index 9408228..0000000 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/concurrency/LatchedServiceController.java +++ /dev/null @@ -1,340 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 Red Hat, Inc. - * All rights reserved. - * - * 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.core.concurrency; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * @author Joseph Marques - * @author John Mazzitelli - */ -public class LatchedServiceController { - - private final Log log = LogFactory.getLog(LatchedServiceController.class); - - private final Collection<? extends LatchedService> latchedServices; - private final CountDownLatch serviceStartupLatch; - private final CountDownLatch serviceCompletionLatch; - private final Map<String, CountDownLatch> dependencyLatches; - - private int threadPoolSize; - - /** - * Creates the controller that will be responsible for launching the services in a thread pool. - * Note that you must ensure the order of the given services is in the order you want them submitted - * to the thread pool. N services will be executed concurrently (where N is the - * {@link #setThreadPoolSize(int) size of the thread pool}) but if there are dependencies among - * services, you must ensure services appear after their dependencies in the list. - * - * @param services list of services that will be invoked - */ - public LatchedServiceController(Collection<? extends LatchedService> services) { - this.serviceStartupLatch = new CountDownLatch(1); - this.serviceCompletionLatch = new CountDownLatch(services.size()); - this.dependencyLatches = new HashMap<String, CountDownLatch>(services.size()); - - this.latchedServices = services; - for (LatchedService nextService : this.latchedServices) { - this.dependencyLatches.put(nextService.getServiceName(), - new CountDownLatch(nextService.dependencies.size())); - nextService.controller = this; - } - - // When this latched service stuff was originally written, it was to help speed up - // plugin deployment by registering multiple plugins concurrently. However, it turns - // out that that causes problems today. Plugin registraton should not be done - // concurrently - each plugin must be registered one after the other serially. - // See BZ 616395 - try { - this.threadPoolSize = Integer.parseInt(System.getProperty("rhq.server.plugin-deployer-threads", "1")); - } catch (NumberFormatException e) { - this.threadPoolSize = 1; - log.warn("Invalid number of threads specified, defaulting to [" + this.threadPoolSize + "]: " + e); - } - } - - public int getThreadPoolSize() { - return threadPoolSize; - } - - public void setThreadPoolSize(int threadPoolSize) { - this.threadPoolSize = threadPoolSize; - } - - public void executeServices() throws LatchedServiceCircularityException { - checkForCircularDependencies(); - - ExecutorService threadPool = Executors.newFixedThreadPool(this.threadPoolSize); - log.debug("Will execute latched services with a concurrency of [" + this.threadPoolSize + "]"); - - // submit all latched services, but they'll block either in the thread pool queue or our startup latch - Map<String, Future<?>> threads = new HashMap<String, Future<?>>(); - for (LatchedService service : this.latchedServices) { - log.debug("Submitting [" + service.getServiceName() + "] to thread pool"); - Future<?> thread = threadPool.submit(service); - threads.put(service.getServiceName(), thread); - } - - // allow them to go - serviceStartupLatch.countDown(); - - try { - // and then wait for all of them to complete - int elapsedMinutes = 0; - final int MINUTES_BETWEEN_UPDATES = 3; - while (!this.serviceCompletionLatch.await(MINUTES_BETWEEN_UPDATES, TimeUnit.MINUTES)) { - elapsedMinutes += MINUTES_BETWEEN_UPDATES; - boolean stillRunning = false; - for (Map.Entry<String, Future<?>> thread : threads.entrySet()) { - if (!thread.getValue().isDone()) { - stillRunning = true; - log.warn("Still processing [" + thread.getKey() + "] after " + elapsedMinutes - + " minutes - is it hung?"); - } - } - if (!stillRunning) { - log.error("The controller is waiting for threads that are already dead, breaking deadlock now!"); - break; - } - } - } catch (InterruptedException ie) { - log.warn("Controller was interrupted; can not be sure if all services have begun"); - } finally { - threadPool.shutdownNow(); - } - - log.debug("All services have begun"); - } - - private void checkForCircularDependencies() throws LatchedServiceException { - Set<LatchedService> visited = new HashSet<LatchedService>(); - List<LatchedService> currentPath = new ArrayList<LatchedService>(); - for (LatchedService nextService : this.latchedServices) { - if (visited.contains(nextService)) { - // have already visited this service from a different path - continue; - } - visit(nextService, visited, currentPath); - } - } - - private void visit(LatchedService current, Set<LatchedService> visited, List<LatchedService> currentPath) - throws LatchedServiceException { - visited.add(current); - - if (currentPath.contains(current)) { - int firstOccurrence = currentPath.indexOf(current); - StringBuilder circularMessage = new StringBuilder(current.getServiceName()); - for (int i = firstOccurrence + 1; i < currentPath.size(); i++) { - circularMessage.append(" -> "); - circularMessage.append(currentPath.get(i).getServiceName()); - } - circularMessage.append(" -> "); - circularMessage.append(current.getServiceName()); - - throw new LatchedServiceCircularityException("Circular dependency detected in latched services: " - + circularMessage + "; " + "will not attempt to start any of them"); - } - - currentPath.add(current); - for (LatchedService dependency : current.dependencies) { - visit(dependency, visited, currentPath); - } - currentPath.remove(current); - } - - public static abstract class LatchedService implements Runnable { - - private LatchedServiceController controller; - private final String serviceName; - private final Set<LatchedService> dependencies; - private final Set<LatchedService> dependees; - private volatile boolean running = false; - private volatile boolean hasFailed = false; - - public LatchedService(String serviceName) { - this.serviceName = serviceName; - this.dependencies = new HashSet<LatchedService>(); - this.dependees = new HashSet<LatchedService>(); - } - - public String getServiceName() { - return this.serviceName; - } - - public void addDependency(LatchedService dependency) { - if (running) { - throw new IllegalArgumentException(serviceName - + " can't accept new dependencies; it is already started"); - } - - // dependencies are needed to correctly construct the dependencyLatch - this.dependencies.add(dependency); - - // dependees are needed for notification purposes after service start - dependency.dependees.add(this); - } - - public void notifyComplete(LatchedService finishedService, boolean didFail) { - if (!dependencies.contains(finishedService)) { - controller.log.error(finishedService + " is not a dependency of " + this); - return; - } - - /* - * if one of my dependencies has failed, I can't possibly succeed starting up; - * so set this bit so the run method can use it to fail early - */ - if (didFail) { - hasFailed = true; - } - - // one of our dependencies is done, decrement our countdown latch to indicate this - this.controller.dependencyLatches.get(this.serviceName).countDown(); - } - - public void run() { - running = true; - - String originalThreadName = Thread.currentThread().getName(); - Thread.currentThread().setName("Latched Service Processor: " + this.serviceName); - - try { - if (controller.log.isDebugEnabled()) { - controller.log.debug("Latched Service Processing [" + this.serviceName + "]; dependencies=[" - + this.dependencies + "]; dependees=[" + this.dependees + "]..."); - } - - if (controller == null) { - throw new IllegalStateException("LatchedServices must be started via some controller"); - } - - try { - /* - * wait until all services are ready to begin; this is - * imperative as it will ensure that their dependencyLatches - * have been properly constructed - */ - controller.serviceStartupLatch.await(); - } catch (InterruptedException ie) { - controller.log.info(serviceName + " will not be started; " - + "could not verify all dependent services in ready state"); - hasFailed = true; - return; - } - - try { - /* - * do not perform startup actions until all dependencies - * have performed their startup actions first - */ - controller.dependencyLatches.get(this.serviceName).await(); - } catch (InterruptedException ie) { - controller.log.info(serviceName + " will not be started; " - + "did not verify all dependent services successfully started"); - hasFailed = true; - return; - } - - if (hasFailed) { - controller.log.info(serviceName + " will not be started; " - + "some upstream dependency has failed to start"); - } else { - try { - // now perform your startup actions - executeService(); - controller.log.debug(serviceName + " successfully started!"); - } catch (LatchedServiceException lsse) { - controller.log.error(lsse); - } - } - - } finally { - // and notify dependees - try { - for (LatchedService dependee : dependees) { - dependee.notifyComplete(this, hasFailed); - } - } finally { - // and notify the controller as well - controller.serviceCompletionLatch.countDown(); - - controller.log.debug("Processed [" + this.serviceName + "]"); - Thread.currentThread().setName(originalThreadName); - } - } - } - - public abstract void executeService() throws LatchedServiceException; - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(getServiceName() + ":"); - boolean first = true; - for (LatchedService dep : dependencies) { - if (!first) { - builder.append("|"); - } else { - first = false; - } - builder.append(dep.getServiceName()); - } - return builder.toString(); - } - - @Override - public final int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((serviceName == null) ? 0 : serviceName.hashCode()); - return result; - } - - @Override - public final boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - final LatchedService other = (LatchedService) obj; - if (serviceName == null) { - if (other.serviceName != null) - return false; - } else if (!serviceName.equals(other.serviceName)) - return false; - return true; - } - } -} diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/concurrency/LatchedServiceException.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/concurrency/LatchedServiceException.java deleted file mode 100644 index a422212..0000000 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/concurrency/LatchedServiceException.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 Red Hat, Inc. - * All rights reserved. - * - * 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.core.concurrency; - -/** - * @author Joseph Marques - */ -public class LatchedServiceException extends RuntimeException { - - private static final long serialVersionUID = 1L; - - public LatchedServiceException() { - super(); - } - - public LatchedServiceException(String message) { - super(message); - } - - public LatchedServiceException(Throwable cause) { - super(cause); - } - - public LatchedServiceException(String message, Throwable cause) { - super(message, cause); - } - -} diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/ProductPluginDeployer.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/ProductPluginDeployer.java index 728b3f3..39ce392 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/ProductPluginDeployer.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/plugin/ProductPluginDeployer.java @@ -41,9 +41,6 @@ import org.rhq.core.clientapi.descriptor.plugin.PluginDescriptor; import org.rhq.core.domain.auth.Subject; import org.rhq.core.domain.plugin.Plugin; import org.rhq.core.util.MessageDigestGenerator; -import org.rhq.enterprise.server.core.concurrency.LatchedServiceCircularityException; -import org.rhq.enterprise.server.core.concurrency.LatchedServiceController; -import org.rhq.enterprise.server.core.concurrency.LatchedServiceException; import org.rhq.enterprise.server.resource.ResourceTypeManagerLocal; import org.rhq.enterprise.server.resource.metadata.PluginManagerLocal; import org.rhq.enterprise.server.system.SystemManagerLocal; @@ -344,19 +341,20 @@ public class ProductPluginDeployer {
private void registerPlugins(PluginDependencyGraph dependencyGraph, Set<String> pluginsToBeRegistered) { log.debug("Dependency graph deployment order: " + dependencyGraph.getDeploymentOrder()); - Map<String, LatchedPluginDeploymentService> latchedDependencyMap = new HashMap<String, LatchedPluginDeploymentService>(); + Map<String, DeploymentRunnable> dependencyRunnableMap = new HashMap<String, DeploymentRunnable>(); for (String pluginName : pluginsToBeRegistered) { - LatchedPluginDeploymentService service = getServiceIfExists(pluginName, latchedDependencyMap); + DeploymentRunnable service = getServiceIfExists(pluginName, dependencyRunnableMap); + if (service == null) { + log.warn("Cannot create the initial deployment runnable for plugin [" + pluginName + "]"); + } + // We need to register dependencies also even if they aren't new or updated. This is because // PluginMetadataManager requires dependency plugins to be loaded in its pluginsByParser map. // ResourceMetadataManagerBean.register() will be smart enough to pass these plugins to // PluginMetadataManager to be parsed, but not to unnecessarily merge their types into the DB. for (String dependencyPluginName : dependencyGraph.getPluginDependencies(pluginName)) { - LatchedPluginDeploymentService dependencyService = getServiceIfExists(dependencyPluginName, - latchedDependencyMap); - if (null != dependencyService) { - service.addDependency(dependencyService); - } else { + DeploymentRunnable dependencyService = getServiceIfExists(dependencyPluginName, dependencyRunnableMap); + if (null == dependencyService) { log.warn("Ignoring [" + pluginName + "] dependency on missing dependency plugin: " + dependencyPluginName); } @@ -366,11 +364,9 @@ public class ProductPluginDeployer { // in order to allow the dependents to refresh themselves and add any new child types that need to be registered. List<String> optionalDependents = dependencyGraph.getOptionalDependents(pluginName); for (String dependentPluginName : optionalDependents) { - LatchedPluginDeploymentService dependentService = getServiceIfExists(dependentPluginName, - latchedDependencyMap); + DeploymentRunnable dependentService = getServiceIfExists(dependentPluginName, dependencyRunnableMap); if (null != dependentService) { dependentService.setForceUpdate(true); // make sure it updates its types, even if plugin hasn't changed - dependentService.addDependency(service); } else { log.warn("Ignoring [" + pluginName + "] dependent on missing dependent plugin: " + dependentPluginName); @@ -378,22 +374,20 @@ public class ProductPluginDeployer { } }
- // submit them to the controller in the order they should be deployed - ArrayList<LatchedPluginDeploymentService> orderedLatchedServices = new ArrayList<LatchedPluginDeploymentService>(); + // get the order in which they should be deployed + ArrayList<DeploymentRunnable> orderedDeploymentRunnables = new ArrayList<DeploymentRunnable>(); List<String> pluginOrder = dependencyGraph.getDeploymentOrder(); for (String nextPlugin : pluginOrder) { - LatchedPluginDeploymentService nextService = latchedDependencyMap.get(nextPlugin); - if (nextService != null) { - orderedLatchedServices.add(nextService); + DeploymentRunnable nextRunnable = dependencyRunnableMap.get(nextPlugin); + if (nextRunnable != null) { + orderedDeploymentRunnables.add(nextRunnable); } }
+ // now do the actual deployments in the correct order long startDeployTime = System.currentTimeMillis(); - LatchedServiceController controller = new LatchedServiceController(orderedLatchedServices); - try { - controller.executeServices(); - } catch (LatchedServiceCircularityException lsce) { - log.error(lsce.getMessage()); + for (DeploymentRunnable currentRunnable : orderedDeploymentRunnables) { + currentRunnable.run(); } long endDeployTime = System.currentTimeMillis();
@@ -416,16 +410,24 @@ public class ProductPluginDeployer { } */
- private LatchedPluginDeploymentService getServiceIfExists(String pluginName, - Map<String, LatchedPluginDeploymentService> latchedServiceMap) { + /** + * This will return the deployment runnable for the associated plugin. + * This will create a DeploymentRunnable if one doesn't yet exist. + * If it can't create one, null is returned. + * + * @param pluginName + * @param runnableMap + * @return the deployment runnable that can be used to deploy the plugin; null if not able to create one + */ + private DeploymentRunnable getServiceIfExists(String pluginName, Map<String, DeploymentRunnable> runnableMap) {
- LatchedPluginDeploymentService result = latchedServiceMap.get(pluginName); + DeploymentRunnable result = runnableMap.get(pluginName); if (result == null) { DeploymentInfo deploymentInfo = this.deploymentInfos.get(pluginName); PluginDescriptor descriptor = this.metadataManager.getPluginDescriptor(pluginName); if ((null != deploymentInfo) && (null != descriptor)) { - result = new LatchedPluginDeploymentService(pluginName, deploymentInfo, descriptor); - latchedServiceMap.put(pluginName, result); + result = new DeploymentRunnable(pluginName, deploymentInfo, descriptor); + runnableMap.put(pluginName, result); } } return result; @@ -563,14 +565,14 @@ public class ProductPluginDeployer { return new File(di.url.getPath()).getName(); }
- class LatchedPluginDeploymentService extends LatchedServiceController.LatchedService { + class DeploymentRunnable implements Runnable { private final DeploymentInfo pluginDeploymentInfo; private final PluginDescriptor pluginDescriptor; + private final String pluginName; private boolean forceUpdate;
- public LatchedPluginDeploymentService(String pluginName, DeploymentInfo di, PluginDescriptor descriptor) { - - super(pluginName); + public DeploymentRunnable(String pluginName, DeploymentInfo di, PluginDescriptor descriptor) { + this.pluginName = pluginName; this.pluginDeploymentInfo = di; this.pluginDescriptor = descriptor; this.forceUpdate = false; @@ -581,12 +583,9 @@ public class ProductPluginDeployer { }
@Override - public void executeService() throws LatchedServiceException { - try { - registerPluginJar(this.pluginDescriptor, this.pluginDeploymentInfo, this.forceUpdate); - } catch (Throwable t) { - throw new LatchedServiceException(t); - } + public void run() { + log.debug("Being asked to deploy plugin [" + this.pluginName + "]..."); + registerPluginJar(this.pluginDescriptor, this.pluginDeploymentInfo, this.forceUpdate); } }
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/core/concurrency/LatchedServiceCircularDependenciesTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/core/concurrency/LatchedServiceCircularDependenciesTest.java deleted file mode 100644 index cf39e22..0000000 --- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/core/concurrency/LatchedServiceCircularDependenciesTest.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 Red Hat, Inc. - * All rights reserved. - * - * 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.core.concurrency; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.testng.annotations.Test; - -import org.rhq.enterprise.server.core.concurrency.LatchedServiceController.LatchedService; - -/** - * @author Joseph Marques - */ -@Test -public class LatchedServiceCircularDependenciesTest { - - private class DummyLatchedService extends LatchedService { - - public DummyLatchedService(String name) { - super(name); - } - - @Override - public void executeService() throws LatchedServiceException { - return; // no-op - } - - } - - private Collection<DummyLatchedService> getDummiesFromDependencyGraph(String dependencyGraph) { - Map<String, DummyLatchedService> knownServices = new HashMap<String, DummyLatchedService>(); - List<DummyLatchedService> orderedServices = new ArrayList<DummyLatchedService>(); - - String[] deps = dependencyGraph.replaceAll(" ", "").split(","); - for (String dep : deps) { - String[] parts = dep.split("-"); - - DummyLatchedService service = getDummyServiceByName(parts[0], knownServices); - if (parts.length > 1) { - DummyLatchedService dependency = getDummyServiceByName(parts[1], knownServices); - service.addDependency(dependency); - } - orderedServices.add(service); - } - - return orderedServices; - } - - private DummyLatchedService getDummyServiceByName(String name, Map<String, DummyLatchedService> dummies) { - DummyLatchedService result = dummies.get(name); - if (result == null) { - result = new DummyLatchedService(name); - dummies.put(name, result); - } - return result; - } - - @Test - public void testLongCircularDependencyGraph() { - testCircularDependency("1-2, 2-3, 3-4, 4-5, 5-1"); - } - - @Test - public void testShortCircularDependencyGraph() { - testCircularDependency("1-2, 2-3, 2-4, 2-5, 5-1"); - } - - @Test - public void testTwoElementCircularDependencyGraph() { - testCircularDependency("1-2, 2-1"); - } - - @Test - public void testSelfCircularDependencyGraph() { - testCircularDependency("1-1"); - } - - @Test - public void testNoCircularDependencyGraph() { - Collection<DummyLatchedService> dummies = getDummiesFromDependencyGraph("1,2,3,4,5,6,7,8,9,10"); - LatchedServiceController controller = new LatchedServiceController(dummies); - try { - controller.executeServices(); - } catch (LatchedServiceCircularityException lsce) { - assert false : "Should not have recieved a LatchedServiceCircularityException, but did: " + lsce; - } - } - - private void testCircularDependency(String dependencyGraph) { - Collection<DummyLatchedService> dummies = getDummiesFromDependencyGraph(dependencyGraph); - LatchedServiceController controller = new LatchedServiceController(dummies); - try { - controller.executeServices(); - assert false : "Should have recieved a LatchedServiceCircularityException, but didn't"; - } catch (LatchedServiceCircularityException lsce) { - assert true; - } - } - -} diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/core/concurrency/LatchedServiceDependenciesTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/core/concurrency/LatchedServiceDependenciesTest.java deleted file mode 100644 index 31761bd..0000000 --- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/core/concurrency/LatchedServiceDependenciesTest.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 Red Hat, Inc. - * All rights reserved. - * - * 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.core.concurrency; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.testng.annotations.Test; - -import org.rhq.enterprise.server.core.concurrency.LatchedServiceController.LatchedService; - -@Test -public class LatchedServiceDependenciesTest { - - public void testDependencies() throws Exception { - // 1 is a plugin that is a dependency of 2 - // 2 can't start because 1 takes up the entire thread pool - // Make sure this doesn't deadlock - 1 needs to be able to inform 2 that it is done, - // even though 2 isn't yet started in a thread - Collection<DummyLatchedService> dummies = getDummiesFromDependencyGraph("1,2-1"); - LatchedServiceController controller = new LatchedServiceController(dummies); - controller.setThreadPoolSize(1); - controller.executeServices(); - } - - public void testDependencies2() throws Exception { - Collection<DummyLatchedService> dummies = getDummiesFromDependencyGraph("1,6-1,2,7-2,3,8-3,4,9-4,5,10-5"); - LatchedServiceController controller = new LatchedServiceController(dummies); - controller.setThreadPoolSize(1); - controller.executeServices(); - } - - public void testDependencies3() throws Exception { - Collection<DummyLatchedService> dummies = getDummiesFromDependencyGraph("1,6-1,2,7-2,3,8-3,4,9-4,5,10-5"); - LatchedServiceController controller = new LatchedServiceController(dummies); - controller.setThreadPoolSize(5); - controller.executeServices(); - } - - private class DummyLatchedService extends LatchedService { - public DummyLatchedService(String name) { - super(name); - } - - @Override - public void executeService() throws LatchedServiceException { - return; - } - } - - private Collection<DummyLatchedService> getDummiesFromDependencyGraph(String dependencyGraph) { - Map<String, DummyLatchedService> knownServices = new HashMap<String, DummyLatchedService>(); - List<DummyLatchedService> orderedServices = new ArrayList<DummyLatchedService>(); - - String[] deps = dependencyGraph.replaceAll(" ", "").split(","); - for (String dep : deps) { - String[] parts = dep.split("-"); - - DummyLatchedService service = getDummyServiceByName(parts[0], knownServices); - if (parts.length > 1) { - DummyLatchedService dependency = getDummyServiceByName(parts[1], knownServices); - service.addDependency(dependency); - } - orderedServices.add(service); - } - - return orderedServices; - } - - private DummyLatchedService getDummyServiceByName(String name, Map<String, DummyLatchedService> dummies) { - DummyLatchedService result = dummies.get(name); - if (result == null) { - result = new DummyLatchedService(name); - dummies.put(name, result); - } - return result; - } -}
rhq-commits@lists.fedorahosted.org