Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 593489 Details for
Bug 783603
Support for asynchronous reporting of measurements
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
patch with conflicts resolved - apply to a5ef337f5921c5cc52fd6a96c084925c46b8f4a1
bz783603.patch (text/plain), 59.70 KB, created by
John Mazzitelli
on 2012-06-21 15:45:56 UTC
(
hide
)
Description:
patch with conflicts resolved - apply to a5ef337f5921c5cc52fd6a96c084925c46b8f4a1
Filename:
MIME Type:
Creator:
John Mazzitelli
Created:
2012-06-21 15:45:56 UTC
Size:
59.70 KB
patch
obsolete
>From 7386a9e54b32fc4383a5a47c421742d718e2edb4 Mon Sep 17 00:00:00 2001 >From: Elias Ross <elias_ross@apple.com> >Date: Fri, 20 Jan 2012 15:25:05 -0800 >Subject: [PATCH] Support for asynchronous operations > >Change the way availability checking is done; use a scheduled executor >Change the availability pool to be a generic collection pool >--- > .../core/domain/measurement/MeasurementReport.java | 31 +++- > .../AvailabilityCollectorRunnable.java | 53 +++---- > .../core/pluginapi/inventory/ResourceContext.java | 23 ++- > .../measurement/MeasurementCollectorRunnable.java | 188 ++++++++++++++++++++ > .../pluginapi/upgrade/ResourceUpgradeContext.java | 6 +- > .../pluginapi/inventory/ResourceContextTest.java | 12 +- > .../java/org/rhq/core/pc/CollectorThreadPool.java | 85 +++++++++ > .../AvailabilityCollectorThreadPool.java | 105 ----------- > .../pc/availability/AvailabilityContextImpl.java | 6 +- > .../rhq/core/pc/inventory/InventoryManager.java | 20 ++- > .../org/rhq/core/pc/CollectorThreadPoolTest.java | 140 +++++++++++++++ > .../pc/availability/AvailabilityCollectorTest.java | 88 --------- > .../org/rhq/core/pc/bundle/BundleManagerTest.java | 2 +- > .../plugins/ant/AntBundlePluginComponentTest.java | 3 +- > .../rhq/plugins/hardware/SmartDiskComponent.java | 2 +- > .../jbossas7/itest/nonpc/UploadAndDeployTest.java | 6 +- > .../org/rhq/plugins/snmptrapd/ComponentTest.java | 6 +- > 17 files changed, 519 insertions(+), 257 deletions(-) > create mode 100644 modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/measurement/MeasurementCollectorRunnable.java > create mode 100644 modules/core/plugin-container/src/main/java/org/rhq/core/pc/CollectorThreadPool.java > delete mode 100644 modules/core/plugin-container/src/main/java/org/rhq/core/pc/availability/AvailabilityCollectorThreadPool.java > create mode 100644 modules/core/plugin-container/src/test/java/org/rhq/core/pc/CollectorThreadPoolTest.java > delete mode 100644 modules/core/plugin-container/src/test/java/org/rhq/core/pc/availability/AvailabilityCollectorTest.java > >diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/measurement/MeasurementReport.java b/modules/core/domain/src/main/java/org/rhq/core/domain/measurement/MeasurementReport.java >index 1933139..50b2d23 100644 >--- a/modules/core/domain/src/main/java/org/rhq/core/domain/measurement/MeasurementReport.java >+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/measurement/MeasurementReport.java >@@ -125,15 +125,40 @@ public class MeasurementReport implements Serializable { > return this.measurementNumericData.size() + this.measurementTraitData.size() + this.callTimeData.size(); > } > >- public long getCollectionTime() { >+ public synchronized long getCollectionTime() { > return collectionTime; > } > >- public void setCollectionTime(long collectionTime) { >+ public synchronized void setCollectionTime(long collectionTime) { > this.collectionTime = collectionTime; > } > >- public void incrementCollectionTime(long collectionTime) { >+ public synchronized void incrementCollectionTime(long collectionTime) { > this.collectionTime += collectionTime; > } >+ >+ /** >+ * Adds measurement data from the given report and updates the collection time. >+ * The assumption is the given report is newer than this instance. >+ * >+ * @param report measurements to add >+ */ >+ public synchronized void add(MeasurementReport report) { >+ measurementNumericData.addAll(report.measurementNumericData); >+ measurementTraitData.addAll(report.measurementTraitData); >+ callTimeData.addAll(report.callTimeData); >+ setCollectionTime(report.collectionTime); >+ } >+ >+ /** >+ * Returns a debug string. >+ */ >+ @Override >+ public String toString() { >+ return "MeasurementReport [measurementNumericData=" >+ + measurementNumericData + ", measurementTraitData=" >+ + measurementTraitData + ", callTimeData=" + callTimeData >+ + ", collectionTime=" + collectionTime + "]"; >+ } >+ > } >\ No newline at end of file >diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/availability/AvailabilityCollectorRunnable.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/availability/AvailabilityCollectorRunnable.java >index 5ce5bd7..dd6a564 100644 >--- a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/availability/AvailabilityCollectorRunnable.java >+++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/availability/AvailabilityCollectorRunnable.java >@@ -22,14 +22,17 @@ > */ > package org.rhq.core.pluginapi.availability; > >-import java.util.concurrent.Executor; >+import java.util.concurrent.Future; >+import java.util.concurrent.FutureTask; >+import java.util.concurrent.ScheduledExecutorService; >+import java.util.concurrent.TimeUnit; > import java.util.concurrent.atomic.AtomicBoolean; > import java.util.concurrent.atomic.AtomicReference; > > import org.apache.commons.logging.Log; > import org.apache.commons.logging.LogFactory; >- > import org.rhq.core.domain.measurement.AvailabilityType; >+import org.rhq.core.pluginapi.inventory.ResourceComponent; > import org.rhq.core.util.exception.ThrowableUtil; > > /** >@@ -63,7 +66,12 @@ public class AvailabilityCollectorRunnable implements Runnable { > /** > * The thread pool to give this runnable a thread to run in when it needs to check availability. > */ >- private final Executor threadPool; >+ private final ScheduledExecutorService threadPool; >+ >+ /** >+ * Data collection future. >+ */ >+ private Future<?> task = new FutureTask<Void>(this, null); > > /** > * If <code>true</code>, this collector runnable should be actively polling the resource for availability status. >@@ -97,7 +105,7 @@ public class AvailabilityCollectorRunnable implements Runnable { > private final String facetId; > > /** >- * Creates a collector instance that will perform availability checking for a particular managed resource. >+ * Constructs a collector instance that will perform availability checking for a particular managed resource. > * > * The interval is the time, in milliseconds, this collector will wait between availability checks. > * This is the amount of time this collector will sleep after each time an availability >@@ -112,7 +120,7 @@ public class AvailabilityCollectorRunnable implements Runnable { > * @param threadPool the thread pool to be used to submit this runnable when it needs to start > */ > public AvailabilityCollectorRunnable(AvailabilityFacet availabilityChecker, long interval, >- ClassLoader contextClassloader, Executor threadPool) { >+ ClassLoader contextClassloader, ScheduledExecutorService threadPool) { > > if (availabilityChecker == null) { > throw new IllegalArgumentException("availabilityChecker is null"); >@@ -161,7 +169,8 @@ public class AvailabilityCollectorRunnable implements Runnable { > if (isStarted) { > log.debug("Availability collector runnable [" + this.facetId + "] is already started"); > } else { >- this.threadPool.execute(this); >+ task.cancel(true); >+ task = threadPool.scheduleWithFixedDelay(this, 0, interval, TimeUnit.MILLISECONDS); > log.debug("Availability collector runnable [" + this.facetId + "] submitted to thread pool"); > } > } >@@ -173,6 +182,7 @@ public class AvailabilityCollectorRunnable implements Runnable { > */ > public void stop() { > this.started.set(false); >+ task.cancel(true); > log.debug("Availability collector runnable [" + this.facetId + "] was told to stop"); > } > >@@ -182,36 +192,17 @@ public class AvailabilityCollectorRunnable implements Runnable { > * You should not be calling this method directly - use {@link #start()} instead. > */ > public void run() { >- log.debug("Availability collector runnable [" + this.facetId + "] started"); >- > ClassLoader originalClassloader = Thread.currentThread().getContextClassLoader(); > Thread.currentThread().setContextClassLoader(this.contextClassloader); >- > try { >- // while we are still running, we need to sleep then get the new availability >- do { >- try { >- AvailabilityType availability = this.availabilityChecker.getAvailability(); >- this.lastKnownAvailability.set(availability); >- } catch (Throwable t) { >- log.warn("Availability collector [" + this.facetId >- + "] failed to get availability - keeping the last known availability of [" >- + this.lastKnownAvailability.get() + "]. Cause: " + ThrowableUtil.getAllMessages(t)); >- } >- >- try { >- Thread.sleep(this.interval); >- } catch (InterruptedException e) { >- // we got interrupted, we assume we need to shutdown >- this.started.set(false); >- log.debug("Availability collector [" + this.facetId + "] interrupted"); >- } >- } while (this.started.get()); >+ AvailabilityType availability = this.availabilityChecker.getAvailability(); >+ this.lastKnownAvailability.set(availability); >+ } catch (Throwable t) { >+ log.warn("Availability collector [" + this.facetId >+ + "] failed to get availability - keeping the last known availability of [" >+ + this.lastKnownAvailability.get() + "]. Cause: " + ThrowableUtil.getAllMessages(t)); > } finally { > Thread.currentThread().setContextClassLoader(originalClassloader); > } >- >- log.debug("Availability collector runnable [" + this.facetId + "] stopped"); >- return; > } > } >diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/inventory/ResourceContext.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/inventory/ResourceContext.java >index 4b21719..6ef8665 100644 >--- a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/inventory/ResourceContext.java >+++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/inventory/ResourceContext.java >@@ -29,6 +29,7 @@ import java.util.HashMap; > import java.util.List; > import java.util.Map; > import java.util.Set; >+import java.util.concurrent.ScheduledExecutorService; > > import org.apache.commons.logging.Log; > import org.apache.commons.logging.LogFactory; >@@ -42,6 +43,8 @@ import org.rhq.core.pluginapi.availability.AvailabilityContext; > import org.rhq.core.pluginapi.availability.AvailabilityFacet; > import org.rhq.core.pluginapi.content.ContentContext; > import org.rhq.core.pluginapi.event.EventContext; >+import org.rhq.core.pluginapi.measurement.MeasurementCollectorRunnable; >+import org.rhq.core.pluginapi.measurement.MeasurementFacet; > import org.rhq.core.pluginapi.operation.OperationContext; > import org.rhq.core.pluginapi.upgrade.ResourceUpgradeContext; > import org.rhq.core.system.ProcessInfo; >@@ -83,6 +86,7 @@ public class ResourceContext<T extends ResourceComponent<?>> { > private final OperationContext operationContext; > private final ContentContext contentContext; > private final AvailabilityContext availabilityContext; >+ private final ScheduledExecutorService collectionThreadPool; > private final PluginContainerDeployment pluginContainerDeployment; > private final ResourceTypeProcesses trackedProcesses; > >@@ -147,12 +151,16 @@ public class ResourceContext<T extends ResourceComponent<?>> { > * manager > * @param availabilityContext a {@link AvailabilityContext} the plugin can use to interoperate with the > * plugin container inventory manager >+ * @param collectionThreadPool a thread pool that can be used by the plugin component should it wish >+ * or need to perform asynchronous checking or measurements. See the javadoc on >+ * {@link AvailabilityCollectorRunnable} for more information on this. > * @param pluginContainerDeployment indicates where the plugin container is running > */ > public ResourceContext(Resource resource, T parentResourceComponent, ResourceContext<?> parentResourceContext, > ResourceDiscoveryComponent<T> resourceDiscoveryComponent, SystemInfo systemInfo, File temporaryDirectory, > File dataDirectory, String pluginContainerName, EventContext eventContext, OperationContext operationContext, > ContentContext contentContext, AvailabilityContext availabilityContext, >+ ScheduledExecutorService collectionThreadPool, > PluginContainerDeployment pluginContainerDeployment) { > > this.resourceKey = resource.getResourceKey(); >@@ -177,6 +185,7 @@ public class ResourceContext<T extends ResourceComponent<?>> { > this.operationContext = operationContext; > this.contentContext = contentContext; > this.availabilityContext = availabilityContext; >+ this.collectionThreadPool = collectionThreadPool; > > String parentResourceUuid = ""; > if (resource.getParentResource() != null) { >@@ -444,7 +453,7 @@ public class ResourceContext<T extends ResourceComponent<?>> { > * The name of the plugin container in which the resource component is running. Components > * can be assured this name is unique across <b>all</b> plugin containers/agents running > * in the RHQ environment. >- * >+ * > * @return the name of the plugin container > */ > public String getPluginContainerName() { >@@ -454,7 +463,7 @@ public class ResourceContext<T extends ResourceComponent<?>> { > /** > * Indicates where the plugin container (and therefore where the plugins) are deployed and running. > * See {@link PluginContainerDeployment} for more information on what the return value means. >- * >+ * > * @return indicator of where the plugin container is deployed and running > * > * @since 1.3 >@@ -509,11 +518,19 @@ public class ResourceContext<T extends ResourceComponent<?>> { > */ > public AvailabilityCollectorRunnable createAvailabilityCollectorRunnable(AvailabilityFacet availChecker, > long interval) { >- > return getAvailabilityContext().createAvailabilityCollectorRunnable(availChecker, interval); > } > > /** >+ * Under certain circumstances, a resource component may want to perform asynchronous measurement reporting. >+ * >+ * @see #createAvailabilityCollectorRunnable(AvailabilityFacet, long) >+ */ >+ public MeasurementCollectorRunnable createMeasurementCollectorRunnable(MeasurementFacet facet, long interval) { >+ return new MeasurementCollectorRunnable(facet, interval, Thread.currentThread().getContextClassLoader(), this.collectionThreadPool); >+ } >+ >+ /** > * Returns a shared object representing the processes detected for given resource type under given parent. > * Note that this comes from a static field so it is shared by any resource contexts representing a > * resource of the same type under a single parent. This is to reduce the number of needed discoveries >diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/measurement/MeasurementCollectorRunnable.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/measurement/MeasurementCollectorRunnable.java >new file mode 100644 >index 0000000..3a0f345 >--- /dev/null >+++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/measurement/MeasurementCollectorRunnable.java >@@ -0,0 +1,188 @@ >+package org.rhq.core.pluginapi.measurement; >+ >+import java.util.Set; >+import java.util.concurrent.CopyOnWriteArraySet; >+import java.util.concurrent.Future; >+import java.util.concurrent.FutureTask; >+import java.util.concurrent.ScheduledExecutorService; >+import java.util.concurrent.TimeUnit; >+import java.util.concurrent.atomic.AtomicBoolean; >+ >+import org.apache.commons.logging.Log; >+import org.apache.commons.logging.LogFactory; >+import org.rhq.core.domain.measurement.MeasurementReport; >+import org.rhq.core.domain.measurement.MeasurementScheduleRequest; >+import org.rhq.core.pluginapi.availability.AvailabilityCollectorRunnable; >+import org.rhq.core.pluginapi.inventory.ResourceComponent; >+ >+/** >+ * Provides assistance for resource components whose measurement reports take a >+ * long time to complete. Although each measurement can be configured to only be >+ * polled infrequently, in the case of a complex calculation (database query, >+ * hourly reports, etc.) that returns multiple values, this collector ensures >+ * they are not collected in separate calls which may put unnecessary load on >+ * the measured system. This class also effectively creates a lower bound on the >+ * frequency of these calculations. >+ * >+ * Typically, measurement reports are fast (a few seconds). However, the plugin >+ * container is blocked waiting for a plugin's resource component to return >+ * measurements from calls to >+ * {@link MeasurementFacet#getValues(MeasurementReport, Set)()}. Report data is >+ * stored and periodically polled instead from a separate thread. >+ * >+ * @see AvailabilityCollectorRunnable for a similar implementation >+ * >+ * @author Elias Ross >+ */ >+public class MeasurementCollectorRunnable implements Runnable { >+ private static final Log log = LogFactory.getLog(MeasurementCollectorRunnable.class); >+ >+ /** >+ * The minimum interval allowed between availability checks, in milliseconds. >+ */ >+ public static final long MIN_INTERVAL = 60000L; >+ >+ /** >+ * The thread pool to give this runnable a thread to run in when it needs to check availability. >+ */ >+ private final ScheduledExecutorService threadPool; >+ >+ /** >+ * If <code>true</code>, this collector runnable should be actively polling the resource for availability status. >+ */ >+ private final AtomicBoolean started = new AtomicBoolean(false); >+ >+ /** >+ * Data collection future. >+ */ >+ private Future<?> task = new FutureTask<Void>(this, null); >+ >+ /** >+ * The classloader to be used when checking availability. >+ */ >+ private final ClassLoader contextClassloader; >+ >+ /** >+ * The object that is used to check the availability for the managed resource. >+ */ >+ private final MeasurementFacet measured; >+ >+ /** >+ * The time, in milliseconds, that this collector will pause in between availability checks. >+ */ >+ private final long interval; >+ >+ /** >+ * The last known measurements for the resource that this collector is monitoring. >+ */ >+ private MeasurementReport lastReport = new MeasurementReport(); >+ >+ /** >+ * Accumulated report. >+ */ >+ private Set<MeasurementScheduleRequest> requestedMetrics = new CopyOnWriteArraySet<MeasurementScheduleRequest>(); >+ >+ /** >+ * Just a cache of the facet toString used in log messages. We don't want to keep calling toString on the >+ * facet for fear we might get some odd blocking or exceptions thrown. So we call it once and cache it here. >+ */ >+ private final String facetId; >+ >+ /** >+ * Creates a collector instance that will perform measurement reporting for a particular managed resource. >+ * >+ * The interval is the time, in milliseconds, this collector will wait between reports. >+ * A typically value should be something around 30 minutes. >+ * >+ * @param measured the object that is used to periodically check the managed resource (must not be <code>null</code>) >+ * @param interval the interval, in millis, between checking availabilities. >+ * @param contextClassloader the context classloader that will be used when checking availability >+ * @param threadPool the thread pool to be used to submit this runnable when it needs to start >+ */ >+ public MeasurementCollectorRunnable(MeasurementFacet measured, long interval, >+ ClassLoader contextClassloader, ScheduledExecutorService threadPool) { >+ >+ if (measured == null) { >+ throw new IllegalArgumentException("availabilityChecker is null"); >+ } >+ >+ if (threadPool == null) { >+ throw new IllegalArgumentException("threadPool is null"); >+ } >+ >+ if (interval < MIN_INTERVAL) { >+ log.info("Interval is too short [" + interval + "] - setting to minimum of [" + MIN_INTERVAL + "]"); >+ interval = MIN_INTERVAL; >+ } >+ >+ if (contextClassloader == null) { >+ contextClassloader = Thread.currentThread().getContextClassLoader(); >+ } >+ >+ this.measured = measured; >+ this.contextClassloader = contextClassloader; >+ this.interval = interval; >+ this.threadPool = threadPool; >+ this.lastReport = new MeasurementReport(); >+ this.facetId = measured.toString(); >+ } >+ >+ /** >+ * Adds the last measured report data to the passed in report. >+ * This will not perform measurements for the managed resource >+ * For those resource components using this measurement collector utility, >+ * their {@link MeasurementFacet#getValues()} method should simply be calling this method. >+ */ >+ public void getLastValues(MeasurementReport report, Set<MeasurementScheduleRequest> metrics) throws Exception { >+ this.requestedMetrics.addAll(metrics); >+ report.add(this.lastReport); >+ } >+ >+ /** >+ * For those resource components using this measurement collector utility, >+ * their {@link ResourceComponent#start(org.rhq.core.pluginapi.inventory.ResourceContext)} method must call this >+ * to start the measurement checking that this object performs. >+ */ >+ public void start() { >+ boolean isStarted = this.started.getAndSet(true); >+ if (!isStarted) { >+ task.cancel(true); >+ task = threadPool.scheduleWithFixedDelay(this, 0, interval, TimeUnit.MILLISECONDS); >+ log.debug("submit " + this.facetId); >+ } >+ } >+ >+ /** >+ * For those resource components using this measurement collector utility, >+ * their {@link ResourceComponent#stop()} method must call this >+ * to stop the measurement checking that this object performs. >+ */ >+ public void stop() { >+ this.started.set(false); >+ this.task.cancel(true); >+ this.requestedMetrics.clear(); >+ log.debug("stop " + facetId); >+ } >+ >+ /** >+ * Performs the actual measurements. This is the method that is invoked >+ * after this runnable is {@link #start() submitted to the thread pool}. >+ * You should not be calling this method directly - use {@link #start()} instead. >+ */ >+ public void run() { >+ log.debug("run " + facetId); >+ >+ ClassLoader originalClassloader = Thread.currentThread().getContextClassLoader(); >+ Thread.currentThread().setContextClassLoader(this.contextClassloader); >+ >+ try { >+ this.measured.getValues(lastReport, requestedMetrics); >+ if (log.isDebugEnabled()) >+ log.debug("last report " + lastReport); >+ } catch (Exception e) { >+ log.warn("Failed to get values", e); >+ } finally { >+ Thread.currentThread().setContextClassLoader(originalClassloader); >+ } >+ } >+} >diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeContext.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeContext.java >index 3c5b6a2..6f79151 100644 >--- a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeContext.java >+++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeContext.java >@@ -24,6 +24,7 @@ package org.rhq.core.pluginapi.upgrade; > > import java.io.File; > import java.util.concurrent.Executor; >+import java.util.concurrent.ScheduledExecutorService; > > import org.rhq.core.domain.configuration.Configuration; > import org.rhq.core.domain.resource.Resource; >@@ -39,7 +40,7 @@ import org.rhq.core.system.SystemInfo; > > /** > * Represents a resource during the resource upgrade phase of discovery. >- * >+ * > * @see ResourceUpgradeFacet > * > * @since 3.0 >@@ -60,11 +61,12 @@ public class ResourceUpgradeContext<T extends ResourceComponent<?>> extends Reso > T parentResourceComponent, ResourceDiscoveryComponent<T> resourceDiscoveryComponent, SystemInfo systemInfo, > File temporaryDirectory, File dataDirectory, String pluginContainerName, EventContext eventContext, > OperationContext operationContext, ContentContext contentContext, AvailabilityContext availabilityContext, >+ ScheduledExecutorService collectorThreadPool, > PluginContainerDeployment pluginContainerDeployment) { > > super(resource, parentResourceComponent, parentResourceContext, resourceDiscoveryComponent, systemInfo, > temporaryDirectory, dataDirectory, pluginContainerName, eventContext, operationContext, contentContext, >- availabilityContext, pluginContainerDeployment); >+ availabilityContext, collectorThreadPool, pluginContainerDeployment); > > this.resourceConfiguration = resource.getResourceConfiguration(); > this.name = resource.getName(); >diff --git a/modules/core/plugin-api/src/test/java/org/rhq/core/pluginapi/inventory/ResourceContextTest.java b/modules/core/plugin-api/src/test/java/org/rhq/core/pluginapi/inventory/ResourceContextTest.java >index fe194c9..118d514 100644 >--- a/modules/core/plugin-api/src/test/java/org/rhq/core/pluginapi/inventory/ResourceContextTest.java >+++ b/modules/core/plugin-api/src/test/java/org/rhq/core/pluginapi/inventory/ResourceContextTest.java >@@ -86,7 +86,7 @@ public class ResourceContextTest { > > //create object to test and inject required dependencies > ResourceContext<?> objectUnderTest = new ResourceContext(mockResource, null, parentResourceContext, null, null, >- mockTemporaryDirectory, mockDataDirectory, null, null, null, null, null, null); >+ mockTemporaryDirectory, mockDataDirectory, null, null, null, null, null, null, null); > > //run code under test > File result = objectUnderTest.getResourceDataDirectory(); >@@ -152,7 +152,7 @@ public class ResourceContextTest { > > //create object to test and inject required dependencies > ResourceContext<?> objectUnderTest = new ResourceContext(mockResource, null, parent1ResourceContext, null, >- null, mockTemporaryDirectory, mockDataDirectory, null, null, null, null, null, null); >+ null, mockTemporaryDirectory, mockDataDirectory, null, null, null, null, null, null, null); > > //run code under test > File result = objectUnderTest.getResourceDataDirectory(); >@@ -206,7 +206,7 @@ public class ResourceContextTest { > > //create object to test and inject required dependencies > ResourceContext<?> objectUnderTest = new ResourceContext(mockResource, null, parentResourceContext, null, null, >- mockTemporaryDirectory, mockDataDirectory, null, null, null, null, null, null); >+ mockTemporaryDirectory, mockDataDirectory, null, null, null, null, null, null, null); > > //run code under test > File result = objectUnderTest.getResourceDataDirectory(); >@@ -260,7 +260,7 @@ public class ResourceContextTest { > > //create object to test and inject required dependencies > ResourceContext<?> objectUnderTest = new ResourceContext(mockResource, null, parentResourceContext, null, null, >- mockTemporaryDirectory, mockDataDirectory, null, null, null, null, null, null); >+ mockTemporaryDirectory, mockDataDirectory, null, null, null, null, null, null, null); > > //run code under test > File result = objectUnderTest.getResourceDataDirectory(); >@@ -314,7 +314,7 @@ public class ResourceContextTest { > > //create object to test and inject required dependencies > ResourceContext<?> objectUnderTest = new ResourceContext(mockResource, null, parentResourceContext, null, null, >- mockTemporaryDirectory, mockDataDirectory, null, null, null, null, null, null); >+ mockTemporaryDirectory, mockDataDirectory, null, null, null, null, null, null, null); > > //run code under test > File result = objectUnderTest.getResourceDataDirectory(); >@@ -377,7 +377,7 @@ public class ResourceContextTest { > > //create object to test and inject required dependencies > ResourceContext<?> objectUnderTest = new ResourceContext(mockResource, null, parent1ResourceContext, null, >- null, mockTemporaryDirectory, mockDataDirectory, null, null, null, null, null, null); >+ null, mockTemporaryDirectory, mockDataDirectory, null, null, null, null, null, null, null); > > //run code under test > File result = objectUnderTest.getFutureChildResourceDataDirectory(inputChildResourceKey); >diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/CollectorThreadPool.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/CollectorThreadPool.java >new file mode 100644 >index 0000000..c5aba36 >--- /dev/null >+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/CollectorThreadPool.java >@@ -0,0 +1,85 @@ >+/* >+ * 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, version 2, as >+ * published by the Free Software Foundation, and/or the GNU Lesser >+ * General Public License, version 2.1, also as published by the Free >+ * Software Foundation. >+ * >+ * 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 and the GNU Lesser General Public License >+ * for more details. >+ * >+ * You should have received a copy of the GNU General Public License >+ * and the GNU Lesser General Public License along with this program; >+ * if not, write to the Free Software Foundation, Inc., >+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. >+ */ >+package org.rhq.core.pc; >+ >+import java.util.concurrent.Executors; >+import java.util.concurrent.ScheduledExecutorService; >+import java.util.concurrent.ThreadFactory; >+ >+import org.apache.commons.logging.Log; >+import org.apache.commons.logging.LogFactory; >+ >+import org.rhq.core.pc.util.LoggingThreadFactory; >+import org.rhq.core.pluginapi.availability.AvailabilityCollectorRunnable; >+import org.rhq.core.pluginapi.measurement.MeasurementCollectorRunnable; >+ >+/** >+ * A utility class that can be used by plugins whose components may not be able to collect data >+ * fast enough. This thread pool object can be used to submit {@link Runnable} instances, >+ * each of which will be used to collect information from a managed resource. >+ * >+ * This class is used in conjunction with instances of {@link AvailabilityCollectorRunnable} or >+ * {@link MeasurementCollectorRunnable}. Read its javadoc for more information. >+ * >+ * @author John Mazzitelli >+ */ >+public class CollectorThreadPool { >+ private static final Log log = LogFactory.getLog(CollectorThreadPool.class); >+ >+ /** >+ * To avoid many plugins/components needing to spawn their own thread pools/threads, this >+ * will allow everyone to reuse the same thread pool. This thread pool will be allowed to grow as needed, >+ * but will reuse threads when they become available. >+ */ >+ private final ScheduledExecutorService executor; >+ >+ public CollectorThreadPool() { >+ log.debug(this.toString()); >+ ThreadFactory daemonFactory = new LoggingThreadFactory("CollectorThreadPool", true); >+ executor = Executors.unconfigurableScheduledExecutorService(Executors.newScheduledThreadPool(1, daemonFactory)); >+ } >+ >+ /** >+ * Shuts down all tasks. >+ */ >+ public void shutdown() { >+ log.debug("Shutting down AvailabilityCollector thread pool..."); >+ PluginContainer pluginContainer = PluginContainer.getInstance(); >+ pluginContainer.shutdownExecutorService(executor, true); >+ } >+ >+ /** >+ * Returns the underlying scheduled executor, which is unconfigurable. >+ */ >+ public ScheduledExecutorService getExecutor() { >+ return executor; >+ } >+ >+ /** >+ * Returns a debug string. >+ */ >+ public String toString() { >+ return getClass().getName() + " executor=" + executor; >+ } >+ >+} >diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/availability/AvailabilityCollectorThreadPool.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/availability/AvailabilityCollectorThreadPool.java >deleted file mode 100644 >index c4951d9..0000000 >--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/availability/AvailabilityCollectorThreadPool.java >+++ /dev/null >@@ -1,105 +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, version 2, as >- * published by the Free Software Foundation, and/or the GNU Lesser >- * General Public License, version 2.1, also as published by the Free >- * Software Foundation. >- * >- * 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 and the GNU Lesser General Public License >- * for more details. >- * >- * You should have received a copy of the GNU General Public License >- * and the GNU Lesser General Public License along with this program; >- * if not, write to the Free Software Foundation, Inc., >- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. >- */ >-package org.rhq.core.pc.availability; >- >-import java.util.concurrent.Executor; >-import java.util.concurrent.ExecutorService; >-import java.util.concurrent.Executors; >-import java.util.concurrent.ThreadFactory; >- >-import org.apache.commons.logging.Log; >-import org.apache.commons.logging.LogFactory; >- >-import org.rhq.core.pc.PluginContainer; >-import org.rhq.core.pc.util.LoggingThreadFactory; >-import org.rhq.core.pluginapi.availability.AvailabilityCollectorRunnable; >- >-/** >- * A utility class that can be used by plugins whose components may not be able to collect availability statuses >- * fast enough. This thread pool object can be used to submit {@link AvailabilityCollectorRunnable} instances, >- * each of which will be used to collect availability statuses for a managed resource. >- * >- * This class is used in conjunction with instances of {@link AvailabilityCollectorRunnable} - read its javadoc for more. >- * >- * @author John Mazzitelli >- */ >-public class AvailabilityCollectorThreadPool implements Executor { >- private static final Log log = LogFactory.getLog(AvailabilityCollectorThreadPool.class); >- >- /** >- * To avoid many plugins/components needing to spawn their own thread pools/threads, this >- * will allow everyone to reuse the same thread pool. This thread pool will be allowed to grow as needed, >- * but will reuse threads when they become available. >- */ >- private ExecutorService threadPool; >- >- public void initialize() { >- synchronized (this) { >- if (threadPool == null) { >- log.debug("Initializing AvailabilityCollector thread pool"); >- ThreadFactory daemonFactory = new LoggingThreadFactory("AvailabilityCollector", true); >- threadPool = Executors.newCachedThreadPool(daemonFactory); >- } >- } >- return; >- } >- >- public void shutdown() { >- >- synchronized (this) { >- if (threadPool != null) { >- log.debug("Shutting down AvailabilityCollector thread pool..."); >- PluginContainer pluginContainer = PluginContainer.getInstance(); >- pluginContainer.shutdownExecutorService(threadPool, true); >- threadPool = null; >- } >- } >- return; >- } >- >- /** >- * Given a {@link AvailabilityCollectorRunnable} instance, this will run that instance in a thread, thus >- * allowing the availability status for a managed resource to be periodically checked asynchronously. The >- * given runnable will store its last known availability status so it can be retrieved very fast. >- * >- * The given runnable must be of type {@link AvailabilityCollectorRunnable}, otherwise a runtime exception will occur. >- * >- * @param runnable the availability collector runnable that will be invoked in a thread to being collecting >- * availability status of a managed resource. >- */ >- public void execute(Runnable runnable) { >- if (runnable instanceof AvailabilityCollectorRunnable) { >- synchronized (this) { >- if (threadPool != null) { >- threadPool.execute(runnable); >- } >- } >- return; >- } else if (runnable == null) { >- throw new NullPointerException("runnable == null"); >- } else { >- throw new IllegalArgumentException("Runnable is of type [" + runnable.getClass() + "]; must be of type [" >- + AvailabilityCollectorRunnable.class + "]"); >- } >- } >-} >diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/availability/AvailabilityContextImpl.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/availability/AvailabilityContextImpl.java >index 32fb361..f2f7d02 100644 >--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/availability/AvailabilityContextImpl.java >+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/availability/AvailabilityContextImpl.java >@@ -20,7 +20,7 @@ > > package org.rhq.core.pc.availability; > >-import java.util.concurrent.Executor; >+import java.util.concurrent.ScheduledExecutorService; > > import org.rhq.core.domain.measurement.Availability; > import org.rhq.core.domain.measurement.AvailabilityType; >@@ -36,9 +36,9 @@ import org.rhq.core.pluginapi.availability.AvailabilityFacet; > public class AvailabilityContextImpl implements AvailabilityContext { > > private final Resource resource; >- private final Executor availCollectionThreadPool; >+ private final ScheduledExecutorService availCollectionThreadPool; > >- public AvailabilityContextImpl(Resource resource, Executor availCollectionThreadPool) { >+ public AvailabilityContextImpl(Resource resource, ScheduledExecutorService availCollectionThreadPool) { > super(); > this.resource = resource; > this.availCollectionThreadPool = availCollectionThreadPool; >diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java >index 8cd3859..2de7417 100644 >--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java >+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java >@@ -39,8 +39,8 @@ import java.util.UUID; > import java.util.concurrent.Callable; > import java.util.concurrent.ConcurrentHashMap; > import java.util.concurrent.ExecutionException; >-import java.util.concurrent.Executor; > import java.util.concurrent.Future; >+import java.util.concurrent.ScheduledExecutorService; > import java.util.concurrent.ScheduledThreadPoolExecutor; > import java.util.concurrent.TimeUnit; > import java.util.concurrent.atomic.AtomicInteger; >@@ -79,13 +79,13 @@ import org.rhq.core.domain.resource.ResourceError; > import org.rhq.core.domain.resource.ResourceErrorType; > import org.rhq.core.domain.resource.ResourceType; > import org.rhq.core.domain.resource.ResourceUpgradeReport; >+import org.rhq.core.pc.CollectorThreadPool; > import org.rhq.core.pc.ContainerService; > import org.rhq.core.pc.PluginContainer; > import org.rhq.core.pc.PluginContainerConfiguration; > import org.rhq.core.pc.ServerServices; > import org.rhq.core.pc.agent.AgentRegistrar; > import org.rhq.core.pc.agent.AgentService; >-import org.rhq.core.pc.availability.AvailabilityCollectorThreadPool; > import org.rhq.core.pc.availability.AvailabilityContextImpl; > import org.rhq.core.pc.content.ContentContextImpl; > import org.rhq.core.pc.drift.sync.DriftSyncManager; >@@ -193,7 +193,7 @@ public class InventoryManager extends AgentService implements ContainerService, > /** > * Used by resource components that want to perform asynchronous availability checking. > */ >- private AvailabilityCollectorThreadPool availabilityCollectors; >+ private CollectorThreadPool collectors; > > /** > * Handles the resource upgrade during the initialization of the inventory manager. >@@ -220,8 +220,7 @@ public class InventoryManager extends AgentService implements ContainerService, > > //make sure the avail collectors are available before we instantiate any > //resource context - either from disk or from anywhere else. >- availabilityCollectors = new AvailabilityCollectorThreadPool(); >- availabilityCollectors.initialize(); >+ collectors = new CollectorThreadPool(); > > if (configuration.isInsideAgent()) { > loadFromDisk(); >@@ -282,7 +281,7 @@ public class InventoryManager extends AgentService implements ContainerService, > this.persistToDisk(); > } > this.discoveryComponentProxyFactory.shutdown(); >- this.availabilityCollectors.shutdown(); >+ this.collectors.shutdown(); > this.inventoryEventListeners.clear(); > this.resourceContainers.clear(); > } >@@ -1783,7 +1782,8 @@ public class InventoryManager extends AgentService implements ContainerService, > getEventContext(resource), // for event access > getOperationContext(resource), // for operation manager access > getContentContext(resource), // for content manager access >- getAvailabilityContext(resource, this.availabilityCollectors), // for components that want to perform async avail checking >+ getAvailabilityContext(resource, this.collectors.getExecutor()), // for components that want to perform async avail checking >+ this.collectors.getExecutor(), // for components that want to perform async avail checking > this.configuration.getPluginContainerDeployment()); // helps components make determinations of what to do > } > >@@ -1802,7 +1802,8 @@ public class InventoryManager extends AgentService implements ContainerService, > getEventContext(resource), // for event access > getOperationContext(resource), // for operation manager access > getContentContext(resource), // for content manager access >- getAvailabilityContext(resource, this.availabilityCollectors), // for components that want avail manager access >+ getAvailabilityContext(resource, this.collectors.getExecutor()), // for components that want avail manager access >+ this.collectors.getExecutor(), // for components that want to perform async avail checking > this.configuration.getPluginContainerDeployment()); // helps components make determinations of what to do > } > >@@ -2635,7 +2636,8 @@ public class InventoryManager extends AgentService implements ContainerService, > // }; > // } > >- private AvailabilityContext getAvailabilityContext(Resource resource, Executor availCollectionThreadPool) { >+ private AvailabilityContext getAvailabilityContext(Resource resource, >+ ScheduledExecutorService availCollectionThreadPool) { > if (null == resource.getUuid() || resource.getUuid().isEmpty()) { > log.error("RESOURCE UUID IS NOT SET! Availability features may not work!"); > } >diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/CollectorThreadPoolTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/CollectorThreadPoolTest.java >new file mode 100644 >index 0000000..91e699e >--- /dev/null >+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/CollectorThreadPoolTest.java >@@ -0,0 +1,140 @@ >+/* >+ * 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, version 2, as >+ * published by the Free Software Foundation, and/or the GNU Lesser >+ * General Public License, version 2.1, also as published by the Free >+ * Software Foundation. >+ * >+ * 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 and the GNU Lesser General Public License >+ * for more details. >+ * >+ * You should have received a copy of the GNU General Public License >+ * and the GNU Lesser General Public License along with this program; >+ * if not, write to the Free Software Foundation, Inc., >+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. >+ */ >+package org.rhq.core.pc; >+ >+import java.util.HashSet; >+import java.util.Set; >+ >+import org.testng.annotations.AfterTest; >+import org.testng.annotations.BeforeTest; >+import org.testng.annotations.Test; >+ >+import org.apache.commons.logging.Log; >+import org.apache.commons.logging.LogFactory; >+import org.rhq.core.domain.measurement.AvailabilityType; >+import org.rhq.core.domain.measurement.DataType; >+import org.rhq.core.domain.measurement.MeasurementDataTrait; >+import org.rhq.core.domain.measurement.MeasurementReport; >+import org.rhq.core.domain.measurement.MeasurementScheduleRequest; >+import org.rhq.core.pc.CollectorThreadPool; >+import org.rhq.core.pluginapi.availability.AvailabilityCollectorRunnable; >+import org.rhq.core.pluginapi.availability.AvailabilityFacet; >+import org.rhq.core.pluginapi.measurement.MeasurementCollectorRunnable; >+import org.rhq.core.pluginapi.measurement.MeasurementFacet; >+ >+@Test >+public class CollectorThreadPoolTest { >+ >+ protected final Log log = LogFactory.getLog(getClass()); >+ private CollectorThreadPool threadPool; >+ >+ @BeforeTest >+ public void beforeTest() { >+ threadPool = new CollectorThreadPool(); >+ } >+ >+ @AfterTest >+ public void afterTest() { >+ threadPool.shutdown(); >+ threadPool = null; >+ } >+ >+ public void testCollector() throws Exception { >+ >+ AvailabilityType[] avail = new AvailabilityType[] { AvailabilityType.UP }; >+ TestAvailabilityFacet component = new TestAvailabilityFacet(avail); >+ AvailabilityCollectorRunnable runnable = new AvailabilityCollectorRunnable(component, 60000L, null, >+ this.threadPool.getExecutor()); >+ runnable.start(); >+ Thread.sleep(1000L); >+ assert AvailabilityType.UP == runnable.getLastKnownAvailability(); >+ >+ // availability collector cannot allow for collections faster than 60s. So we can't have tests faster than this. >+ // set this if-check to true to fully test the collector (which takes a couple mins of wait time to complete) >+ if (System.getProperty("AvailabilityCollectorTest.longtest", "false").equals("true")) { >+ avail[0] = AvailabilityType.DOWN; >+ log("~~~~~~~~~~sleeping for 60 secs"); >+ Thread.sleep(60100L); >+ assert AvailabilityType.DOWN == runnable.getLastKnownAvailability() : "Collector should have seen the change"; >+ >+ runnable.stop(); >+ avail[0] = AvailabilityType.UP; >+ log("~~~~~~~~~~sleeping for 60 secs"); >+ Thread.sleep(60100L); >+ assert AvailabilityType.DOWN == runnable.getLastKnownAvailability() : "Collector should have stopped and not see the change"; >+ } >+ } >+ >+ private void log(String string) { >+ log.info(string); >+ } >+ >+ public void testMeasurement() throws Exception { >+ log("testMeasurement"); >+ TestMeasumentFacet component = new TestMeasumentFacet(); >+ MeasurementCollectorRunnable runnable = new MeasurementCollectorRunnable(component, 500L, null, >+ this.threadPool.getExecutor()); >+ runnable.start(); >+ Set<MeasurementScheduleRequest> metrics = new HashSet(); >+ metrics.add(new MeasurementScheduleRequest(0, "name", 0, true, DataType.TRAIT)); >+ MeasurementReport report = new MeasurementReport(); >+ runnable.getLastValues(report, metrics); >+ assert 0 == report.getCollectionTime(); >+ assert report.getTraitData().isEmpty(); >+ >+ log("sleeping"); >+ Thread.sleep(1000L); >+ >+ report = new MeasurementReport(); >+ runnable.getLastValues(report, metrics); >+ assert 42 == report.getCollectionTime(); >+ assert !report.getTraitData().isEmpty(); >+ } >+ >+ protected class TestAvailabilityFacet implements AvailabilityFacet { >+ private AvailabilityType[] avail; >+ >+ public TestAvailabilityFacet(AvailabilityType[] avail) { >+ this.avail = avail; >+ } >+ >+ public AvailabilityType getAvailability() { >+ log("~~~~~~~~~~" + new java.util.Date() + " == " + this.avail[0]); >+ return this.avail[0]; >+ } >+ } >+ >+ protected class TestMeasumentFacet implements MeasurementFacet { >+ >+ @Override >+ public void getValues(MeasurementReport report, >+ Set<MeasurementScheduleRequest> metrics) throws Exception { >+ log("getValues " + metrics); >+ report.setCollectionTime(42L); >+ for (MeasurementScheduleRequest request : metrics) { >+ report.addData(new MeasurementDataTrait(0, request, "good times")); >+ } >+ } >+ >+ } >+} >diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/availability/AvailabilityCollectorTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/availability/AvailabilityCollectorTest.java >deleted file mode 100644 >index ec0538b..0000000 >--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/availability/AvailabilityCollectorTest.java >+++ /dev/null >@@ -1,88 +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, version 2, as >- * published by the Free Software Foundation, and/or the GNU Lesser >- * General Public License, version 2.1, also as published by the Free >- * Software Foundation. >- * >- * 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 and the GNU Lesser General Public License >- * for more details. >- * >- * You should have received a copy of the GNU General Public License >- * and the GNU Lesser General Public License along with this program; >- * if not, write to the Free Software Foundation, Inc., >- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. >- */ >-package org.rhq.core.pc.availability; >- >-import org.testng.annotations.AfterTest; >-import org.testng.annotations.BeforeTest; >-import org.testng.annotations.Test; >- >-import org.rhq.core.domain.measurement.AvailabilityType; >-import org.rhq.core.pluginapi.availability.AvailabilityCollectorRunnable; >-import org.rhq.core.pluginapi.availability.AvailabilityFacet; >- >-@Test >-public class AvailabilityCollectorTest { >- >- private AvailabilityCollectorThreadPool threadPool; >- >- @BeforeTest >- public void beforeTest() { >- threadPool = new AvailabilityCollectorThreadPool(); >- threadPool.initialize(); >- } >- >- @AfterTest >- public void afterTest() { >- threadPool.shutdown(); >- threadPool = null; >- } >- >- public void testCollector() throws Exception { >- >- AvailabilityType[] avail = new AvailabilityType[] { AvailabilityType.UP }; >- TestAvailabilityFacet component = new TestAvailabilityFacet(avail); >- AvailabilityCollectorRunnable runnable = new AvailabilityCollectorRunnable(component, 60000L, null, >- this.threadPool); >- runnable.start(); >- Thread.sleep(1000L); >- assert AvailabilityType.UP == runnable.getLastKnownAvailability(); >- >- // availability collector cannot allow for collections faster than 60s. So we can't have tests faster than this. >- // set this if-check to true to fully test the collector (which takes a couple mins of wait time to complete) >- if (System.getProperty("AvailabilityCollectorTest.longtest", "false").equals("true")) { >- avail[0] = AvailabilityType.DOWN; >- System.out.println("~~~~~~~~~~sleeping for 60 secs"); >- Thread.sleep(60100L); >- assert AvailabilityType.DOWN == runnable.getLastKnownAvailability() : "Collector should have seen the change"; >- >- runnable.stop(); >- avail[0] = AvailabilityType.UP; >- System.out.println("~~~~~~~~~~sleeping for 60 secs"); >- Thread.sleep(60100L); >- assert AvailabilityType.DOWN == runnable.getLastKnownAvailability() : "Collector should have stopped and not see the change"; >- } >- } >- >- protected class TestAvailabilityFacet implements AvailabilityFacet { >- private AvailabilityType[] avail; >- >- public TestAvailabilityFacet(AvailabilityType[] avail) { >- this.avail = avail; >- } >- >- public AvailabilityType getAvailability() { >- System.out.println("~~~~~~~~~~" + new java.util.Date() + " == " + this.avail[0]); >- return this.avail[0]; >- } >- } >-} >diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/bundle/BundleManagerTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/bundle/BundleManagerTest.java >index b6b39e0..4b37c89 100644 >--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/bundle/BundleManagerTest.java >+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/bundle/BundleManagerTest.java >@@ -478,7 +478,7 @@ public class BundleManagerTest { > @SuppressWarnings("unchecked") > private static class MockResourceContext extends ResourceContext { > public MockResourceContext(Resource resource) { >- super(resource, null, null, null, null, null, null, null, null, null, null, null, null); >+ super(resource, null, null, null, null, null, null, null, null, null, null, null, null, null); > } > } > } >\ No newline at end of file >diff --git a/modules/plugins/ant-bundle/src/test/java/org/rhq/plugins/ant/AntBundlePluginComponentTest.java b/modules/plugins/ant-bundle/src/test/java/org/rhq/plugins/ant/AntBundlePluginComponentTest.java >index 05ebc2f..daf5463 100644 >--- a/modules/plugins/ant-bundle/src/test/java/org/rhq/plugins/ant/AntBundlePluginComponentTest.java >+++ b/modules/plugins/ant-bundle/src/test/java/org/rhq/plugins/ant/AntBundlePluginComponentTest.java >@@ -101,7 +101,8 @@ public class AntBundlePluginComponentTest { > resource.setUuid(UUID.randomUUID().toString()); > @SuppressWarnings({ "rawtypes", "unchecked" }) > ResourceContext<?> context = new ResourceContext(resource, null, null, null, >- SystemInfoFactory.createJavaSystemInfo(), tmpDir, null, "antBundleTestPC", null, null, null, null, null); >+ SystemInfoFactory.createJavaSystemInfo(), tmpDir, null, "antBundleTestPC", null, null, null, null, null, >+ null); > this.plugin.start(context); > } > >diff --git a/modules/plugins/hardware/src/main/java/org/rhq/plugins/hardware/SmartDiskComponent.java b/modules/plugins/hardware/src/main/java/org/rhq/plugins/hardware/SmartDiskComponent.java >index ec7bb9f..bde1627 100644 >--- a/modules/plugins/hardware/src/main/java/org/rhq/plugins/hardware/SmartDiskComponent.java >+++ b/modules/plugins/hardware/src/main/java/org/rhq/plugins/hardware/SmartDiskComponent.java >@@ -116,7 +116,7 @@ public class SmartDiskComponent implements ResourceComponent, MeasurementFacet { > public static void main(String[] args) throws Exception { > SmartDiskComponent sdc = new SmartDiskComponent(); > sdc.start(new ResourceContext(new Resource("/dev/sda", "foo", new ResourceType()), null, null, null, null, null, >- null, null, null, null, null, null, PluginContainerDeployment.AGENT)); >+ null, null, null, null, null, null, null, PluginContainerDeployment.AGENT)); > sdc.getValues(null, null); > > } >diff --git a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/nonpc/UploadAndDeployTest.java b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/nonpc/UploadAndDeployTest.java >index 8ddb308..28a8688 100644 >--- a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/nonpc/UploadAndDeployTest.java >+++ b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/nonpc/UploadAndDeployTest.java >@@ -345,7 +345,8 @@ public class UploadAndDeployTest extends AbstractIntegrationTest { > resource.setUuid(UUID.randomUUID().toString()); > StandaloneASComponent parentComponent = new StandaloneASComponent(); > parentComponent.setConnection(getASConnection()); >- ResourceContext context = new ResourceContext(resource,parentComponent,null,null,null,null,null,null,null,null,null,null,null); >+ ResourceContext context = new ResourceContext(resource, parentComponent, null, null, null, null, null, null, >+ null, null, null, null, null, null); > bc.start(context); > > String bytes_value = uploadToAs(TEST_WAR_PATH); >@@ -379,7 +380,8 @@ public class UploadAndDeployTest extends AbstractIntegrationTest { > resource.setUuid(UUID.randomUUID().toString()); > StandaloneASComponent parentComponent = new StandaloneASComponent(); > parentComponent.setConnection(getASConnection()); >- ResourceContext context = new ResourceContext(resource,parentComponent,null,null,null,null,null,null,null,null,null,null,null); >+ ResourceContext context = new ResourceContext(resource, parentComponent, null, null, null, null, null, null, >+ null, null, null, null, null, null); > bc.start(context); > > String bytes_value = uploadToAs(TEST_WAR_PATH); >diff --git a/modules/plugins/snmptrapd/src/test/java/org/rhq/plugins/snmptrapd/ComponentTest.java b/modules/plugins/snmptrapd/src/test/java/org/rhq/plugins/snmptrapd/ComponentTest.java >index b023609..cfd64fb 100644 >--- a/modules/plugins/snmptrapd/src/test/java/org/rhq/plugins/snmptrapd/ComponentTest.java >+++ b/modules/plugins/snmptrapd/src/test/java/org/rhq/plugins/snmptrapd/ComponentTest.java >@@ -5,6 +5,7 @@ import java.io.InputStream; > import java.util.Set; > import java.util.UUID; > import java.util.concurrent.Executors; >+import java.util.concurrent.ScheduledExecutorService; > > import org.apache.commons.logging.Log; > import org.apache.commons.logging.LogFactory; >@@ -95,11 +96,12 @@ public abstract class ComponentTest { > EventContext eventContext = new EventContextImpl(resource); > OperationContext operationContext = new OperationContextImpl(0); > ContentContext contentContext = new ContentContextImpl(0); >+ ScheduledExecutorService availCollectorThreadPool = Executors.newScheduledThreadPool(1); > PluginContainerDeployment pluginContainerDeployment = null; >- AvailabilityContext availContext = new AvailabilityContextImpl(resource, Executors.newCachedThreadPool()); >+ AvailabilityContext availContext = new AvailabilityContextImpl(resource, availCollectorThreadPool); > ResourceContext context = new ResourceContext(resource, parentResourceComponent, parentResourceContext, > resourceDiscoveryComponent, systemInfo, temporaryDirectory, dataDirectory, pluginContainerName, >- eventContext, operationContext, contentContext, availContext, pluginContainerDeployment); >+ eventContext, operationContext, contentContext, availContext, availCollectorThreadPool, pluginContainerDeployment); > Assert.assertNotNull(context.getEventContext()); > component.start(context); > } >-- >1.7.6.4 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 783603
:
566971
|
593489
|
593545
|
625107