IBM®WebSphere®MQ环境可能变得非常庞大,并且涉及许多对象定义。 使您可以自动检查这些对象定义的系统可以帮助加快WebSphere MQ网络的开发和调试。
WebSphere MQ Explorer是WebSphere MQ管理工具集的名称,它使您能够创建,更改和删除对象。 MQ Explorer建立在Eclipse之上,可以使用Eclipse插件进行扩展。 本文向您展示如何编写一个插件以在WebSphere MQ环境上执行检查,以一个示例为例,该插件可验证所有对象是否符合公司命名标准。
该插件将使用Java™和XML的组合编写,并将实现可以从WebSphere MQ Explorer GUI启动的检查。 结果将显示在Eclipse Problems视图中,从中可以将它们分类为错误,警告或信息。
图1. WebSphere MQ Explorer GUI,显示问题视图的用法,以显示测试和检查的结果

先决条件
本文假定您已在Linux®或Microsoft®Windows®上安装了WebSphere MQ Explorer。 它还假定您要使用WebSphere MQ Explorer随附的Eclipse工作台。 缺省情况下,WebSphere MQ Explorer禁用Eclipse平台的全部工作台功能。 要启用工作台,请选择Windows => Preferences => WebSphere MQ Explorer , 在Eclipse工作台中选择Startup ,然后重新启动WebSphere MQ Explorer。
图2. WebSphere MQ Explorer首选项对话框,显示了运行完整的Eclipse工作台的设置

本文还使用WebSphere MQ Explorer Healthcheck SupportPac(MH01)来减少定制检查所需的Java开发。 您可以在本文底部下载MH01 SupportPac ,其中包括安装说明。 它具有以下优点:
- 与WebSphere MQ Explorer和Eclipse GUI集成-用于运行新检查的GUI控件自动包含在GUI中; 通过检查发现的结果将显示在“问题视图”中并为您管理; 您提供的任何文档都会适当显示并启动; 等等。
- 基本线程模型-您可以在使用WebSphere MQ Explorer GUI的同时在后台运行新检查,并与其他测试并行运行,而无需考虑代码中的线程含义,
您所需要做的就是编写逻辑代码以检查问题,并描述应如何措辞您发现的任何潜在问题。
准备插件开发环境
Eclipse插件开发透视图
WebSphere MQ Explorer随附Eclipse Java IDE,可用于开发插件。 要切换到Eclipse插件开发环境(PDE),请选择Window => Open Perspective => Other 。 PDE为您提供了开发环境的概述,可在其中编辑Java和XML文件的编辑器以及许多其他有用的视图。 有关PDE的更多信息,请参见下面的“ 相关主题” 。
创建一个新项目
为您的代码创建一个新的插件项目。 在新添加的项目旁边的Package Explorer中右键单击,然后选择New => Plug-in Project 。 就本示例而言,将新项目命名为com.ibm.mq.explorer.healthcheck.samples
。
创建完成后,为新插件打开自动生成的plugin.xml
。 使用“ 依赖关系”选项卡将以下插件添加为新插件的依赖项。 这些是一些核心Eclipse GUI插件以及WebSphere MQ使用的一些项目的组合:
-
com.ibm.mq.commonservices
-
com.ibm.mq.explorer.core
-
com.ibm.mq.explorer.healthcheck
-
com.ibm.mq.explorer.plugins
-
com.ibm.mq.explorer.ui
-
com.ibm.mq.internal.pcf
-
com.ibm.mq.internal.pcf.event
-
com.ibm.mq.runtime
-
org.eclipse.core.resources
图3. plugin.xml中的依赖项

创建一个新测试
每个测试需要:
- 插件的XML中的一个条目,用于向WebSphere MQ Explorer GUI提供要为测试显示的信息
- 进行测试的Java类
用XML定义新的测试
打开您的插件的plugin.xml
。 使用扩展选项卡将com.ibm.mq.explorer.healthcheck.MQtests
添加到您的项目中。
右键单击MQtests扩展,然后添加将定义您的测试的新test
条目:
图4. plugin.xml中的新扩展

选择测试项目后,输入以下信息:
- 名称 -表示此检查时在GUI中显示的用户友好名称
- class-您将在下一步中编写的Java类的全限定名称
- id-此测试的唯一标识符(例如,上面输入的Java类的标准名称)
- description-要在GUI中显示的测试的简短描述
- testset-测试集的名称。 GUI使您可以将测试分为几组,这在您进行大量测试时非常有用,并且可以轻松地运行一组检查。 如果输入的名称不存在,则会为您创建。 尽管建议,但这是可选的。
- 进一步信息-HTML页面的位置,其中包含有关此测试及其创建的结果的更多详细信息。 GUI可以显示其他文档,以解释它们返回的结果,并提供有关解决问题的方法的指导。 文档应以HTML格式提供,并且可以标识为:
- 插件内部 -存储在提供测试本身的插件项目中。 该位置应在XML中相对于
plugin.xml
文件本身进行定义; 例如doc/TestDoc.html
。 - 插件外部 -存储在Web服务器上,允许与测试本身分开维护文档。 使用以
http://
开头的完整URL指定位置。
- 插件内部 -存储在提供测试本身的插件项目中。 该位置应在XML中相对于
例如,输入以下内容来定义一个测试,该测试将验证您的MQ环境的命名约定:
图5. plugin.xml扩展

单击plugin.xml选项卡,然后查看XML源。 您的XML应该如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.0"?>
<plugin
id="com.ibm.mq.explorer.healthcheck.samples"
name="Custom WebSphere MQ Tests"
version="1.0.0"
provider-name="IBM developerWorks"
class="com.ibm.mq.explorer.healthcheck.samples.SamplesPlugin">
<runtime>
<library name="samples.jar">
<export name="*"/>
</library>
</runtime>
<requires>
<import plugin="org.eclipse.ui"/>
<import plugin="org.eclipse.core.runtime"/>
<import plugin="com.ibm.mq.commonservices"/>
<import plugin="com.ibm.mq.explorer.core"/>
<import plugin="com.ibm.mq.explorer.healthcheck"/>
<import plugin="com.ibm.mq.explorer.plugins"/>
<import plugin="com.ibm.mq.explorer.ui"/>
<import plugin="com.ibm.mq.internal.pcf"/>
<import plugin="com.ibm.mq.internal.pcf.event"/>
<import plugin="com.ibm.mq.runtime"/>
<import plugin="org.eclipse.core.resources"/>
</requires>
<extension point="com.ibm.mq.explorer.healthcheck.MQtests">
<test
furtherinfo="doc/QueueNamesInfo.html"
class="com.ibm.mq.explorer.healthcheck.samples.QueueNames"
description="A sample test to check queue names against simple naming conventions."
testset="Queues"
name="Naming Conventions"
id="com.ibm.mq.explorer.healthcheck.samples.QueueNames"/>
</extension>
</plugin>
MQtests XML是Healthcheck插件中定义的接口,它使Healthcheck能够正确地找到并从多个插件中加载测试。 有关插件体系结构的更多信息,请参阅下面“ 相关主题 ”下的Eclipse文章。
用Java准备新测试
从“程序包资源管理器”中创建一个新的Java类,确保为其提供一个名称和程序包,该名称和程序包与先前定义的XML的class
属性中标识的位置一致。 该类应扩展com.ibm.mq.explorer.healthcheck.objects.WMQTest
。
“问题视图”将继续显示所有现有的WebSphere MQ Explorer Healthcheck问题以及Java源问题。 您可以使用“问题视图”过滤器将其过滤掉。
目前,做最少的事情来编译您的Java类,即创建一个空类。 稍后我们将返回详细的实现。
package com.ibm.mq.explorer.healthcheck.samples;
import com.ibm.mq.explorer.healthcheck.objects.WMQTest;
/**
* Empty test class - enough to compile.
*
* @author Dale Lane
*/
public class QueueNames extends WMQTest {
}
准备新测试的文档
编写要与测试一起显示在GUI中的文档。 该文档应使用HTML编写,并保存在plugin.xml
文件中指定的位置。 如前所述,它可以是本地的(在此插件内部,例如在doc
文件夹中)或远程的(在Web服务器上)。
图6.项目结构显示了与上面显示的XML一致的文档HTML的位置

部署测试
在Package Explorer中,右键单击您的项目,然后选择Export 。 单击可部署的插件和片段 。 在打开的“导出”对话框中,单击“ 部署为目录结构”,然后将目标目录设置为Healthcheck插件安装的位置。 默认安装位置在Windows上为C:\Program Files\IBM\WebSphere MQ\eclipse
,在Linux上为/opt/mqm/eclipse/plugins/
。
重新启动Eclipse。 重新打开后,使用Windows菜单返回到WebSphere MQ Explorer透视图。 您的新测试应该出现在Navigators视图树中的Queues
文件夹中的WebSphere MQ Healthcheck节点下,如plugin.xml
所指定。 如果单击树中的新测试,则HTML文档应显示在“内容视图”页面中。
如果您HTML文档在WebSphere MQ Explorer GUI中不可见,则您HTML文件可能未包含在插件的构建中。 通过打开build.properties
文件并在Binary Build列表中选择文档,将HTML文件添加到构建列表中:
图7.构建配置

确认插件的结构正常工作后,请返回PDE为测试提供实现。
对Java代码进行任何更改之后,您必须重复之前的部署步骤以重新测试。 另外,在开发期间,您可以使用Run As => Run-time Workbench启动Eclipse的测试实例,该实例使您可以在不关闭开发环境的情况下进行和测试更改。 更改完成后,您可以执行上面概述的部署步骤。
用Java实施新测试
初次尝试
我们将逐步建立测试,并在下面用更详细的解释性注释对示例源代码进行注释。 我们的第一次尝试返回静态数据,并演示了WMQTest接口的基本元素:
package com.ibm.mq.explorer.healthcheck.samples;
import java.util.ArrayList;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import com.ibm.mq.explorer.healthcheck.HealthcheckPlugin;
import com.ibm.mq.explorer.healthcheck.actions.WMQTestEngine;
import com.ibm.mq.explorer.healthcheck.objects.WMQTest;
import com.ibm.mq.explorer.healthcheck.objects.WMQTestResult;
/**
* A sample skeleton implementation of a Healthcheck test.
*
*Download the source from Resources below .
*
* @author Dale Lane
*/
public class QueueNames extends WMQTest {
// notice that no constructor is required
/**
* Starts the test.
*
* @param callback handle to the test engine running the test
* @param guimonitor handle to the object monitoring the test,
* provided to allow the test to periodically check
* if the user has tried to cancel the test running
* and provide additional user feedback
*/
public void runTest(WMQTestEngine callback, IProgressMonitor guimonitor) {
// start with the default implementation. this will store a handle
// to the test engine that will be needed when we want to submit
// any results at the end of the test
super.runTest(callback, guimonitor);
// start the progress monitor for this test
String myName = getTestName() ;
guimonitor. beginTask (myName, 10);
guimonitor.subTask("Getting preferences for test");
// prepare space to store any results we might want to return
ArrayList testResults = new ArrayList();
// generate nine meaningless test results
for ( int i=0; i < 9; i++ ) {
// update progress monitor
guimonitor.subTask("Generating test result " + i + " of 9");
// if the test has been cancelled, we break out of the
// for loop to return asap
if ( isCancelled() )
break;
try {
// wait here for two seconds to simulate lengthy test processing
Thread.sleep(2000);
} catch ( InterruptedException e ) {
// unexpected exception
Status internal_error = new Status(IStatus.ERROR, "com.ibm.mq.explorer.healthcheck.coretests", 0, "Unexpected exception encountered while " + "waiting for test to return", e); HealthcheckPlugin.getPlugin().getLog().log(internal_error);
}
// create a fake result and add it to the list
WMQTestResult nxtResult = new WMQTestResult(IMarker.SEVERITY_INFO, "Blah blah blah test result number " + i + " here", "QMGR_1", "Queues");
testResults.add(nxtResult);
// increment progress monitor
guimonitor.worked(1);
}
// update progress monitor
guimonitor.subTask("Returning results to test engine");
// return any results that this test has generated
WMQTestResult[] finalresults =
(WMQTestResult[]) testResults.toArray(new WMQTestResult[testResults.size()]);
testComplete(finalresults) ;
// complete progress monitor
guimonitor.done();
}
}
尝试使用此示例代码来修改您自己的测试对象,然后将其重新部署以进行测试。 您应该能够运行测试,并看到在Eclipse Problems视图中显示的测试结果。
MQ感知尝试
现在,我们将特定于WebSphere MQ的代码添加到测试对象,从而允许它验证队列对象的名称。
本文无意作为用Java编写WebSphere MQ应用程序的教程。 有关Java API的更多信息,请参见《 使用Java 》手册。 它可以显示如何修改此示例以访问队列以外的对象以及对象名称以外的属性。 但是,编写与Explorer GUI集成的代码的基本方法保持不变:
package com.ibm.mq.explorer.healthcheck.samples;
import java.io.IOException;
import java.util.ArrayList;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import com.ibm.mq.MQException;
import com.ibm.mq.MQQueueManager;
import com.ibm.mq.explorer.healthcheck.HealthcheckPlugin;
import com.ibm.mq.explorer.healthcheck.PreferenceStoreManager;
import com.ibm.mq.explorer.healthcheck.actions.WMQTestEngine;
import com.ibm.mq.explorer.healthcheck.objects.WMQTest;
import com.ibm.mq.explorer.healthcheck.objects.WMQTestResult;
import com.ibm.mq.explorer.ui.extensions.MQQmgrExtObject;
import com.ibm.mq.explorer.ui.internal.objects.ExplorerExtensionBase;
import com.ibm.mq.pcf.CMQC;
import com.ibm.mq.pcf.CMQCFC;
import com.ibm.mq.pcf.PCFMessage;
import com.ibm.mq.pcf.PCFMessageAgent;
/**
* A sample test used to check Queue Names against naming conventions.
* Queue names are checked if they begin with any of a set range of
* prefixes, defined in this class. Any names which do not start with
* one of the prefixes are output in an error.
*
*Download the source from Resources below .
*
* @author Dale Lane
*/
public class QueueNames extends WMQTest {
/** Maintain a count of how many queue managers we are waiting for replies from. */
private static int numberOfQmgrs = 0;
/** Stores the accepted queue name prefixes. */
private static final String[] ACCEPTED_Q_PREFIXES = { "SALES_",
"MARKETING_",
"SHIPPING_",
"INCOMING_",
"OUTGOING_" };
/** Stores the user preference for whether hidden queue managers should be included. */
boolean includeHiddenQmgrs = false;
/** Stores the user preference for whether system queues should be included. */
boolean includeSystemObjs = false;
/**
* Starts the test.
*
* @param callback handle to the test engine running the test
* @param guimonitor a handle to the object monitoring the test,
* provided to allow the test to periodically check
* if the user has tried to cancel the test running
* and provide additional user feedback
*/
public void runTest(WMQTestEngine callback, IProgressMonitor guimonitor) {
// start with the default implementation. this will store a handle
// to the test engine that will be needed when we want to submit
// any results at the end of the test
super.runTest(callback, guimonitor);
// prepare space to store any results we might want to return
ArrayList testResults = new ArrayList();
// get from Preferences whether we should include hidden queue managers
includeHiddenQmgrs = PreferenceStoreManager.getIncludeHiddenQmgrsPreference() ;
// get from Preferences whether we should include system queues
includeSystemObjs = PreferenceStoreManager.getIncludeSysObjsPreference() ;
// get a list of queue managers from the Explorer
ArrayList allQmgrs;
if (includeHiddenQmgrs){
allQmgrs = ExplorerExtensionBase.getAllQueueManagers();
}
else {
allQmgrs = ExplorerExtensionBase.getShownQueueManagers();
}
// how many queue managers are there?
numberOfQmgrs = allQmgrs.size();
// use the number of queue managers as a guide to track progress
guimonitor. beginTask ( getTestName() , numberOfQmgrs);
// for each queue manager, submit a query
for (int i=0; i < numberOfQmgrs; i++){
// get next queue manager
MQQmgrExtObject nextQueueManager = (MQQmgrExtObject) allQmgrs.get(i);
// only submit queries to connected queue managers
if (nextQueueManager.isConnected()){
// get the name of the queue manager, for use in GUI
String qmgrName = nextQueueManager.getName();
// get a handle to a Java object representing the queue manager
MQQueueManager qmgr = nextQueueManager.getMQQueueManager();
try {
// get a PCF message agent to handle sending PCF inquiry to
PCFMessageAgent agent = new PCFMessageAgent(qmgr);
// use PCF to submit an inquire queue names query
PCFMessage response = submitQueueNamesQuery(qmgrName, agent) ;
// did we get a response to the query?
if (response != null){
// get the queue names out of the reply
String[] qnames = (String[]) response.getParameterValue(CMQCFC.MQCACF_Q_NAMES);
// check each name
for (int j=0; j < qnames.length; j++){
boolean qnameOkay = checkQueueName(qnames[j]) ;
if (!qnameOkay){
// if a problem was found with the name, we generate an
// error message, and add it to the collection to be
// returned
testResults.add( generateTestResult(qnames[j], qmgrName) );
}
}
}
} catch (MQException e) {
// record error details
Status internal_error = new Status( IStatus.ERROR, "com.ibm.mq.explorer.healthcheck.coretests", 0, "Error encountered while getting PCFMessageAgent to " + qmgrName, e); HealthcheckPlugin.getPlugin().getLog().log(internal_error);
}
}
// finished examining a queue manager
guimonitor. worked (1);
}
// return any results that this test has generated
WMQTestResult[] finalresults =
(WMQTestResult[]) testResults.toArray(new WMQTestResult[testResults.size()]);
testComplete(finalresults);
}
/**
* Used internally to submit INQUIRE_Q_NAMES query using PCF to given queue manager
*
* @param qmgrName name of queue manager to submit query to
* @param agent
* @return PCF response from queue manger
*/
private PCFMessage submitQueueNamesQuery(String qmgrName, PCFMessageAgent agent){
// build the pcf message
PCFMessage inquireQNames = new PCFMessage(CMQCFC.MQCMD_INQUIRE_Q_NAMES);
inquireQNames.addParameter(CMQC.MQCA_Q_NAME, "*");
try {
// send the message
PCFMessage[] responseMsgs = agent.send(inquireQNames);
// check if results received successfully
if ( responseMsgs[0].getCompCode() == 0 ) {
return responseMsgs[0];
}
} catch (IOException e) {
// record error details
Status internal_error = new Status( IStatus.ERROR, "com.ibm.mq.explorer.healthcheck.coretests", 0, "Error encountered while sending INQUIRE_Q_NAMES PCF to " + qmgrName, e); HealthcheckPlugin.getPlugin().getLog().log(internal_error);
} catch (MQException e) {
// record error details
Status internal_error = new Status( IStatus.ERROR, "com.ibm.mq.explorer.healthcheck.coretests", 0, "Error encountered while sending INQUIRE_Q_NAMES PCF to " + qmgrName, e); HealthcheckPlugin.getPlugin().getLog().log(internal_error);
}
// for some reason, we don't have a response, so return null
return null;
}
/**
* Used internally to check the given queue name against the collection
* of acceptable prefixes.
*
* @param queueName queue name to check
* @return true if queue name is okay,
* false otherwise
*/
private boolean checkQueueName(String queueName){
// if this is a system object (i.e. it has a name which begins with
// "SYSTEM.") we check the
if ((queueName.startsWith("SYSTEM.")) || (queueName.startsWith("AMQ."))){
if (! includeSystemObjs ){
// user has requested that we do not include system
// objects in the test, so we return true to
// avoid any problems being reported for this queue
return true;
}
}
// PCF response will white-pad the queue name, so we trim it now
queueName = queueName.trim();
// check the queue name against each of the acceptable prefixes
// in turn, returning true immediately if it is
for (int i=0; i < ACCEPTED_Q_PREFIXES.length; i++){
if (queueName.startsWith(ACCEPTED_Q_PREFIXES[i]))
return true;
}
// we have checked against all accepted prefixes, without
// finding a match
return false;
}
/**
* Used internally to generate a test result for the given queue name.
*
* @param queueName queue name that doesn't meet requirements
* @param qmgrName name of queue manager that hosts the queue
* @return generated test result
*/
private WMQTestResult generateTestResult(String queueName, String qmgrName){
return new WMQTestResult(IMarker.SEVERITY_ERROR, "Queue (" + queueName.trim() + ") " + "does not begin with " + "a known prefix", qmgrName, "Queues") ;
}
}
关于上述源代码的注释
跳到下一部分 。
创建测试对象
如前所述,您的测试应扩展WMQTest
。 WebSphere MQ Explorer将使用提供的构造函数WMQTest()
实例化测试对象。 无需继承此构造函数。
测试属性
下表指定了WMQTest超类的某些属性及其访问器方法。 这些属性不打算由子类实现更改,但可能对输出有用。
属性名称 | 属性访问者 | 属性说明 |
---|---|---|
测试编号 | getTestId() | 包含测试的唯一标识符的字符串,如在plugin.xml中指定的 |
名称 | getTestName() | 字符串,包含您的plugin.xml中指定的测试的用户友好名称 |
描述 | getDescription() | 包含您plugin.xml中指定的测试描述的字符串 |
文档路径 | getFurtherInfoPath() | 字符串,包含用于测试HTML文档的位置(在plugin.xml中指定) |
创建测试结果
当测试发现想要返回给用户的内容时,它应该创建一个测试结果对象来描述问题。 测试结果被实现为WMQTestResult
对象,并应使用new WMQTestResult(int severity, String description, String qmgrname, String objectType)
创建new WMQTestResult(int severity, String description, String qmgrname, String objectType)
severity | 标识问题严重性的整数。 应该是以下之一: IMarker.SEVERITY_ERROR , IMarker.SEVERITY_WARNING 或IMarker.SEVERITY_INFO |
---|---|
description | 解释测试发现的问题的字符串,将显示在“问题视图”中 |
qmgrname | 发现问题的队列管理器的名称 |
objectType | 给出问题所在的对象类的字符串(例如“队列”,“通道”等) |
启动测试
WebSphere MQ Explorer调用runTest(WMQTestEngine, IProgressMonitor)
以开始运行测试。 测试的主体应该在这里。
runTest方法的开始应该是使用super.runTest(callback, guimonitor)
的默认实现。 该缓存处理提供的参数,这是各种后台任务所必需的。
WMQTestEngine
参数为运行测试的测试引擎提供了一个句柄。 使用测试引擎的returnResult(WMQTestResult[], WMQTest)
方法returnResult(WMQTestResult[], WMQTest)
该句柄允许测试在进行测试时返回结果:
- 此方法的第一个参数(
WMQTestResult[]
)包含要返回的结果。 - 第二个参数(
WMQTest
)应该是this
,以便测试引擎知道结果来自何处。
使用WMQTestEngine
参数返回中期结果是可选的,但对于长时间运行的测试可能很有用。 或者,可以在完成测试时返回测试结果,如下所述。
IProgressMonitor
参数提供用于当前测试运行的GUI反馈监视器的句柄。 它使您的测试既可以提供有关当前正在运行的任务和/或子任务的文本反馈,也可以提供完成进度的进度条。
如上所述, runTest
Monitor的句柄由runTest
的默认实现缓存,因此也可以使用WMQTest方法getGUIMonitor()
访问Progress Monitor的句柄。
进度监视器是Eclipse的核心资源。 有关如何使用它的详细信息,请参阅Eclipse API文档。 下表显示了一些有用的方法:
beginTask(String taskName, int numberOfStepsInTask) | 表示任务正在启动,并提供要显示的名称和在进度栏中使用的预期步骤数 |
---|---|
worked(int numberOfStepsCompleted) | 将进度条增加提供的步数 |
done() | 表示任务已完成 |
完成测试
通过调用testComplete(WMQTestResult[])
并向其传递测试结果对象数组来完成测试。 如上所述, testComplete
方法需要启动测试运行的测试引擎的句柄,并且如果没有在testComplete
调用之前调用runTest
的默认实现,则该方法将不起作用。
如上所述,除了使用returnResult
在测试运行期间返回测试结果之外,或者作为替代方法,您还可以使用此方法在完成时返回结果。 但是,两次返回的任何结果都将显示两次。
即使您的测试使用WMQTestEngine
方法returnResult
返回其所有结果,它也必须在完成时调用testComplete
才能完成测试处理。 如果没有其他结果要返回,则可以在testComplete
方法中提供WMQTestResult
对象的空数组。
处理取消
用户可以在运行时取消单个测试,也可以取消整个测试。 方法isCancelled()
可用于检查测试是否应停止。 良好的测试应定期检查以查看是否已取消,以避免不必要地延迟用户。
如果您尝试取消测试,但是测试无法长时间返回,则测试引擎将通过终止正在运行它的线程来强制测试停止。 但不要依赖此方法-最好及时返回测试,以便清理所有资源并返回生成的任何测试结果。
报告错误
可以这样报告测试运行过程中遇到的错误:
Status internal_error = new Status(IStatus.ERROR,
"com.ibm.mq.explorer.healthcheck.coretests",
0,
"Error encountered while doing something",
event.getException());
HealthcheckPlugin.getPlugin().getLog().log(internal_error);
该错误将被写入Eclipse错误视图,包括Java异常(如果提供)中包含的堆栈跟踪。 运行检查导致的未捕获异常和错误将被Healthcheck测试引擎捕获,并以这种方式写入错误视图。 因此,在开发新测试时,定期检查“错误视图”是一个好主意。
用户偏好
测试应符合使用“ Eclipse首选项”对话框提供的用户首选项。 使用以下方式访问首选项:
偏爱 | 如果...则返回真 | 如果...则返回FALSE |
---|---|---|
PreferenceStoreManager.getIncludeHiddenQmgrsPreference() | 您应该在测试中包括从WebSphere MQ Explorer隐藏的队列管理器 | 您应该排除测试中已从WebSphere MQ Explorer隐藏的队列管理器 |
PreferenceStoreManager.getIncludeSysObjsPreference() | 系统对象(名称以SYSTEM开头的对象)应包括在测试中 | 系统对象(名称以SYSTEM开头的对象)应从测试中排除 |
复杂测试
测试结构
如前所述,WMQTest方法runTest
定义了测试的主体,并被调用以启动测试运行。
runTest
方法的结束并不意味着测试的结束(需要使用testComplete对其进行明确指定),从而使测试开发人员可以自由地使用异步方法来实现测试以获取数据进行分析。
例如, runTest
可以提交请求以获取有关WebSphere MQ对象的数据。 可以从接收到回复的侦听器方法继续执行测试。 实质上,这使测试可以等待数据,而测试开发人员无需实现线程等待。 以下伪代码示例演示了如何实现此目的:
package com.ibm.mq.explorer.healthcheck.samples;
import java.util.ArrayList;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.IProgressMonitor;
import com.ibm.mq.explorer.healthcheck.HealthcheckPlugin;
import com.ibm.mq.explorer.healthcheck.PreferenceStoreManager;
import com.ibm.mq.explorer.healthcheck.actions.WMQTestEngine;
import com.ibm.mq.explorer.healthcheck.objects.WMQTestResult;
import com.ibm.mq.pcf.CMQC;
/**
* Pseudo-code sample demonstrating an asynchronous approach to implementing a
* Healthcheck test.
*
* @author Dale Lane
*/
public class QueuesTest extends WMQTest implements SomeListener {
/** Used to store test results. */
private ArrayList testresults = new ArrayList();
/**
* Used to start the test.
*
* @param callback handle to the test engine running the test
* @param guimonitor handle to the object monitoring the test,
* provided to allow the test to periodically check
* if the user has tried to cancel the test running
*/
public void runTest(WMQTestEngine callback, IProgressMonitor guimonitor) {
super.runTest(callback, guimonitor);
// reset all test stores
testresults = new ArrayList();
// initialise the progress bar part of the GUI used to show progress of
// this test
guimonitor.beginTask(getTestName(), numqmgrs);
// start the test!
// send query
PseudoQueueManager qmgrHandle = pseudoGetQueueManager();
submitQmgrQuery(qmgrHandle, this, query);
// note that the runTest method is now finished, but the test is not over!
}
/**
* Used to process results received in response to query submitted by runTest.
*
* @param objects data received
*/
public void dataReponseReceived(ArrayList objects) {
// analyse each of the replies in the collection received in the reply
for ( int i = 0; i < objects.size(); i++ ) {
PseudoQueue nxtQueue = (PseudoQueue) objects.get(i);
analyseQueue(nxtQueue);
// increment GUI progress bar used to show progress of this test
getGUIMonitor().worked(1);
}
// now that we have got the data that we were waiting for, and have
// finished processing it, the test has really finished - we are
// nearly ready to call testComplete to mark the test finished
// return the completed results
WMQTestResult[] finalresults =
(WMQTestResult[]) testresults.toArray(new WMQTestResult[0]);
testComplete(finalresults);
}
/**
* Analyse the given queue. If any potential problems are found, a problem
* marker is added to the testresults collection.
*
* @param queue queue to analyse
*/
private void analyseQueue(PseudoQueue queue) {
// do something
// add a problem marker to the collection
if (problemFound) {
testresults.add(new WMQTestResult(IMarker.SEVERITY_WARNING,
"A problem was found with "
+ queueName,
getQueueManagerName(queue),
"Queues"));
}
}
}
如果在测试中需要手动等待/睡眠,则当您要使用Java等待/通知方法时,可以将对象监视器用于测试对象。 在不使用单个测试对象的对象监视器的情况下实现了Healthcheck测试引擎的线程。
结论
本文向您展示了如何通过使用Java编写Eclipse插件来扩展WebSphere MQ Explorer功能。 本文概述了编写扩展的步骤,该扩展使WebSphere MQ Explorer可以验证MQ对象名称使用预定义的前缀集。
可以从下面下载本文描述的完整Eclipse项目,并将其用作开发自己的自定义测试的起点。 通过选择将现有项目导入到Workspace中来解压缩文件并将其内容导入到Package Explorer中,代替本文中描述的创建新项目。
翻译自: https://www.ibm.com/developerworks/websphere/library/techarticles/0512_lane/0512_lane.html