ClearQuest ClearQuest 的 Hook 机制

scm002@gmail.com · 2008年07月17日 · 2 次阅读

ClearQuest 的 Hook 机制级别: 初级 [url=http://www.ibm.com/developerworks/cn/rational/r-cq-hook/#author] 嘉 吴 [/url], IBM 中国软件开发实验室工程师

2005年11月01日 [indent] 本文全面介绍了 ClearQuest 的 Hook 机制,并且通过制订一个具体的变更管理模板,为其定义了多种不同类型的、完成不同功能的 Hooks,以便于大家在实际操作中用较短的时间了解 hooks,并掌握基本的定义 Hooks 的方法。[/indent] 内容简介 ClearQuest 是业界领先的变更管理工具。变更可以是新的需求、软件缺陷、各种工单等。 ClearQuest 更能让客户根据自己的具体需求,灵活的设计变更管理流程。客户可以定义变更的字段和值的范围、变更的各种状态、引起状态转换的操作,和变更之间的关系等等。除此以外,ClearQuest 还提供了 Hook 机制,让变更管理系统的定义更加灵活、功能更加强大。 本文全面介绍了 ClearQuest 的 Hook 机制,并且通过制订一个具体的变更管理模板,为其定义了多种不同类型的、完成不同功能的 Hooks,以便于大家在实际操作中用较短的时间了解 hooks,并掌握基本的定义 Hooks 的方法。

什么是 Hook? 在 ClearQuest 里,Hook 就是用户用某种语言编写的一小段代码,会在操作某个记录(Record)的特定时候触发执行。它可以检查某个记录的字段是否满足复杂的约束条件,可以限制特定的当前用户才有权限操作,可以限制上传文件的大小,可以在对特定的事件记录日志,可以动态灵活的生成各种选择列表,甚至可以更灵活的和其他 Rational 工具,如 ClearCase、Requirement 工具等集成。

Hook 的种类 在 ClearQuest 中定义了四种 Hook:

  1. 字段(Field )Hook
  2. 操作(Action )Hook
  3. 记录类型(Entity)Hook
  4. 全局(Global)Hook

字段(Field)Hook 字段 Hook 可以在运行时检查字段的值约束条件,赋予它缺省值,或者根据当前情况调整其他字段等。 根据触发时机,字段 Hook 又可以分为以下几类: 1. 缺省值(Default Value)Hook 缺省值 Hook 设置字段的缺省值。在 ClearQuest Designer 中,可以直接为记录字段设置常量的缺省值。如果缺省值要求是动态生成的,还可以编写字段的缺省值 Hook 脚本来实现。缺省值 Hook 在开始 SUBMIT 类型操作时触发调用。 2. 选择列表(Chioce List)Hook 选择列表 Hook 生成并返回字段可选择的有效值列表。选择列表可以用下拉列表框控件展示。在 ClearQuest Designer 中,可以直接为记录字段设置简单的可选择的有效值列表。如果可选择的有效值生成规则复杂,则需借助编写选择列表 Hook 脚本来动态生成。选择列表 Hook 紧接着 Default Value Hook 后触发调用。 3. 权限检查(Permission)Hook 记录的字段是否必须设定由其在各个状态下的 Behavior 属性指定。其可为只读的、强制设定的、可选的和使用 Hook 四种类型。如果在某一状态下,属性 Behavior 设定为使用 Hook,则会调用这个字段的权限检查(Permission)Hook 来限制满足条件的用户才能存取本字段。其可用于设定复杂的安全检查机制。权限检查 Hook 在最初存取字段时触发调用。 4. 值改变(Value Changed)Hook 当字段的值发生变化时触发值改变(Value Changed)Hook。值改变 Hook 可用于设定和本字段的值有联动关系的其他字段值。 5. 有效验证(Validation)Hook 当字段的值发生变化时,在运行完值改变 Hook 后还会进一步触发有效验证 Hook,可用于检查当前记录的字段是否有效、是否满足设定的规则。

操作(Action)Hook 操作 Hook 可以检查执行操作的权限,验证整个记录的有效性,或当操作完成后发送通知。根据触发时机,操作 Hook 又可以分为以下几类: 1. 权限控制(Access Control )Hook 权限控制 Hook 用于检查当前用户是否有权限执行本操作。 2. 初始化(Initialization)Hook 初始化 Hook 用于在执行本操作前初始化该记录,比如设定字段值等。它在显示记录表单前触发调用。 3. 有效验证(Validation)Hook 在提交记录的变更前(也就是点击 Apply 按钮提交变更到数据库去)会触发有效验证 Hook,用于验证整个记录复杂的规则。 4. 提交(Commit)Hook 在提交记录的变更到数据库前最后触发运行的是提交 Hook。 5. 通知(Notification)Hook 在提交记录的变更到数据库后触发运行。

记录类型(Record)hook 记录类型 hook 是针对某一记录类型定义的 hook,在 Record Scripts 中编写。它的使用方法有三种: 1)在本记录类型的其他 Hook 中调用,使用 entity 类的 FireNamedHook 方法直接调用。 2)将其和某个 Form 上的某个控件的某个事件关联起来,当发生此事件时触发 hook。具体操作是双击要关联的控件,在控件的 Extended tab 中,为此控件的具体事件选择想要触发的记录类型 Hook。 例如,下图中是在对 defect form 上的 Apply 按钮的 Click 事件设置相应的记录类型 hook。

[img=528,335]http://www.ibm.com/developerworks/cn/rational/r-cq-hook/images/image002.jpg/img][

3)创建类型为"RECORD_SCRIPT_ALIAS"的操作,将其和记录类型 hook 关联起来。 "RECORD_SCRIPT_ALIAS"类型其实提供了一种自定义操作的方式。其具体的操作内容由和其相关的记录类型 hook 来决定。

全局(Global)Hook 全局 Hook 实际上就是全局函数,可以在任何 hooks 中调用。调用方式就像在程序里调用一个函数一样。以 Perl 脚本为例:

[table=98%][tr][td]$result = OneofMyGlobalHooks($session, $entity);[/td][/tr][/table] 除了 Global Hook, 其他三种 Hook 都是和某一个记录类型相关的,均在对某一特定纪录对象的操作中触发执行。Global Hook 是不会被直接触发执行的。

Hook 调用顺序 ClearQuest 中能定义这么多种类的 Hook,它们的调用顺序又是怎样的呢?我们从四个阶段来说明: 开始执行一个操作时,顺序调用: 1) 操作 Access Control Hook 2) 字段 Permission Hook 3) 操作 Initialization Hook 4) 字段 Default Value Hook 5) 字段 Choice List Hook

设置字段值时,顺序调用: 6) 字段 Value Changed Hook 7) 字段 Validation Hook 8) 如果需要重新计算字段的可选择有效值列表,字段 Choice List Hook

验证记录有效性时,顺序调用: 9) 字段 Validation Hook 10) 操作 Validation Hook

提交记录(到数据库)时,顺序调用: 11) 操作 Commit Hook 12) 操作 Notification Hook

BASE 类型的操作的 Hooks 在 ClearQuest Designer 中,可以定义一种特殊的操作:BASE 类型的操作。和其他类型的操作一样,BASE 类型的操作也可以定义上边的五种操作 Hook。Base 类型的操作的各个 Hook 会在所有其它操作的相同类型的 Hook 触发前调用。 可以定义多个 Base 类型的操作和它们的各种 Hooks。而 Base 操作的同一种类型的 Hook 的调用顺序按照其在 ClearQuest Designer 定义的顺序来执行。 例如,在某个模板中为某记录类型顺序定义操作 myBaseAction1 和 myBaseAction2,均为 BASE 类型。两者均定义了 Initialization Hook。则在这个模板所对应的用户数据库中,在针对这种类型的记录的所有操作的初始化阶段,都会先调用 myBaseAction1 的 Initialization Hook 脚本,再调用 myBaseAction2 的 Initialization Hook 的脚本,最后调用本操作自身的 Initialization Hook 的脚本(如果定义的话)。

怎样定义 Hooks [b][font=Arial] Hooks 的语言种类: [/font][/b] Hook 根据定义所用的语言不同,还可以分为以下几类: 1. VB 脚本 2. Perl 脚本 3. 常量 4. 常量列表 所有的 Hook 类型,不管是字段还是操作的,都支持 VB 脚本和 Perl 脚本。一个 Hook 可以同时定义这两种脚本,其中 Windows 平台上缺省使用 VB 脚本,而 Unix 和 Linux 平台上只能使用 Perl 脚本。如果想改变 Windows 平台上的缺省脚本语言,可以在模板的属性里面设置。如下图所示:

[img=548,280]http://www.ibm.com/developerworks/cn/rational/r-cq-hook/images/image004.jpg/img][

常量就是定义其为一个常量值;常量列表就是定义字段选择列表。只有字段 Default Value Hook 和字段 Choice List Hook 支持常量和常量列表。 ClearQuest 以前还提供用 SQL 语言编写 Hook 的功能,现在已经取消。但是 ClearQuest 系统仍能兼容运行以前定义的 SQL Hook。 Hook 类型 和 Hook 语言对应表:

[img=578,435]http://www.ibm.com/developerworks/cn/rational/r-cq-hook/images/table.gif/img][

如何编写 Hook 脚本 一个 Hook 脚本其实就是一个方法,可以用 VB 脚本语言或者 Perl 脚本语言编写。ClearQuest 提供了这两种脚本语言的 API。VB 脚本的 API 是用一个 COM 库来实现,Perl 脚本的则是用一个名为 CQPerlExt 的 perl package 实现。他们都提供了一些 ClearQuest 重要的类和方法。 下图是此 API 提供的 ClearQuest 类和它们之间的关系:

[img=554,360]http://www.ibm.com/developerworks/cn/rational/r-cq-hook/images/image006.gif/img][

由于 Hook 都是在对一个记录的操作中触发执行的,ClearQuest 会传给被触发的 Hook 当前记录对象(entity)。在 VB 脚本中它是缺省操作对象;在 Perl 脚本中它是 $entity。从这个记录对象出发,可以得到象 session 对象,、记录的各个 fieldinfo 对象、当前的 database 对象,等等。 以 Perl 脚本为例,下面这段代码取出 id 为 MyDB00000001 的 defect 记录,改变了它的 description 字段值,并提交改变,写到数据库中:

[table=98%][tr][td]$session = $entity->GetSession();$anotherEntity = $session->LoadEntity("defect", "MyDB00000001");$anotherEntity->EditEntity("modify");$anotherEntity->SetFieldValue("description", "updated description");$anotherEntity->Validate();$anotherEntity->Commit();[/td][/tr][/table] 关于具体的类及其方法的使用描述,请参见 ClearQuest 随身附带的文档"cq_api.pdf"。

如何 Debug Hook 脚本? ClearQuest 自带了一个名为 dbwin32.exe 的工具,在 ClearQuest 安装目录下。其可用于显示调用 Session 类的 OutputDebugString() 方法输出的文本,以及其他一些 ClearQuest 的一些输出信息。如果想跟踪 hook 的执行情况,则启动这个工具即可收集这些输出信息。 如果想让 dbwin32.exe 输出较详细的信息,需要在 Windows 注册表以下位置添加一个类型为 REG_DWORD 的键 HookDebug: My Computer \HKEY_CURRENT_USER \Software \Rational Software \ClearQuest <version id> \Common \ 设置这个键的值为 1。 假设我们在某一个 hook 中定义了如下代码:

[table=98%][tr][td] $session->OutputDebugString("\nOpenning exported.defect..."); $DefectId = 4; $session->OutputDebugString("\nExported DefectId is ".$DefectId); [/td][/tr][/table] 则在调用这个 hook 时,如果已打开 dbwin32,则在其窗口会显示:

[img=252,180]http://www.ibm.com/developerworks/cn/rational/r-cq-hook/images/image008.jpg/img][

实例:定义一个使用多种 Hooks 的缺陷跟踪处理流程模板 在这个例子中,我们创建一个简单的缺陷跟踪处理模板,定义了包括字段缺省 Hook,字段值改变 Hook,操作权限控制 Hook,操作提交 Hook,记录类型 hook,全局 Hook,以及 BASE 类型操作的通知 Hook。这个缺陷跟踪处理系统其实并不完整,但我们的目的就是让大家尽快的对不同类型的 Hook 及其使用和编写有一个全面、基本的认识。在本例中,我们均使用 Perl 来编写 hooks。 我们在 ClearQuest Designer 中创建一个基于 Blank 的模板,创建"defect"记录类型,并为其定义如下的字段: 1)DefectId:整型 2)Description:短字符串 3)OsType:短字符串 4)OsVersion:短字符串 5)StepToRecreate:多行字符串。 "defect"记录类型的字段定义窗口如下图所示:

[img=600,348]http://www.ibm.com/developerworks/cn/rational/r-cq-hook/images/image010.jpg/img][

其中,DefectId 和 OsVersion 均是只读字段。整型 DefectId 由系统自动累加生成。OsType 的值是固定的几个常量之一;OsVersion 值则由 OsType 设定的值来确定。 然后,为其定义如下的状态转换图:

[img=554,250]http://www.ibm.com/developerworks/cn/rational/r-cq-hook/images/image011.gif/img][

在 ClearQuest Designer 中,状态转换定义如下图所示:

[img=408,168]http://www.ibm.com/developerworks/cn/rational/r-cq-hook/images/image013.jpg/img][

其中,Dup 是 DUPLICATE 类型,Open 是 SUBMIT 类型。另外还定义 Delete 类型的"Delete" 操作。只有用户组 defectcoordinators 的用户才有 Delete 一个 defect 的权限。 当验证通过(即 Accept)一个 fixed defect 时,此 defect 的所有 duplicate 的 defect,包括它的 duplicate 的 duplicate 等等,也同时验证通过。同时,在本系统中禁止直接验证某一个 duplicate defect。 每当一个操作发生并提交,系统都会在自己的一个 log 文件中记录相关信息。所以我们还定义了一个 Base 类型的操作"BaseLog"。 在 ClearQuest Designer 中,操作定义如下图所示:

[img=552,245]http://www.ibm.com/developerworks/cn/rational/r-cq-hook/images/image015.jpg/img][

为了实现上述功能,我们定义了如下的几个 Hook: 1)字段 DefectId 的 Default Value Hook: 在 ClearQuest Designer 中打开模板,选择 Record Types ->defect ->Fields,双击 Fields。点击 DefectId 字段的 Default Value hook,选择 SCRIPTS ->;Perl:

[img=588,361]http://www.ibm.com/developerworks/cn/rational/r-cq-hook/images/image017.jpg/img][

现在可以开始编写 DefectId 字段的 Default Value hook 了:

[img=588,187]http://www.ibm.com/developerworks/cn/rational/r-cq-hook/images/image019.jpg/img][

编写如下的脚本:

[table=98%][tr][td] sub defectid_DefaultValue{ my($entityDef, $session, $querydef, $queryfields, $queryfield, $resultset, $fetchStatus, $DefectId); # 创建一个用于查询 Defect 记录的查询对象,直接定义其使用的 SQL 语句: $entitydef = $entity->GetEntityDefName(); $session = $entity->GetSession(); $querydef = $session->BuildQuery($entitydef); $querydef->SetSQL("select max(defectid) from defect"); # 运行这个查询,得到当前数据库中 DefectId 的最大值: $resultset = $session->BuildResultSet($querydef); $resultset->Execute(); $fetchStatus = $resultset->MoveNext(); if ($fetchStatus eq $CQPerlExt::CQ_SUCCESS) { $DefectId = $resultset->GetColumnValue(1); if ($DefectId > 0){ $DefectId++; }else{$DefectId = 1; } $entity->SetFieldValue($fieldname,"$DefectId"); }else { $session->OutputDebugString("\nThis should not happen. fetchStatus is ".$fetchStatus); }}[/td][/tr][/table] 2)OsType 的 Choice List Hook: 点击 DefectId 字段的 Choice List hook,选择 CONSTANT_LIST,并输入"windows","unix","linux"选项,如图所示:

[img=528,350]http://www.ibm.com/developerworks/cn/rational/r-cq-hook/images/image021.jpg/img][

3)OsType 的值改变 Hook: 同样的,点击 DefectId 字段的 Value Changed hook,选择 SCRIPTS ->;Perl。编写如下的脚本:

[table=98%][tr][td] sub ostype_ValueChanged{ my($OsType, $session); $OsType = $entity->GetFieldValue($fieldname)->GetValue(); $session = $entity->GetSession(); if ($OsType eq "windows"){ $entity->SetFieldValue("OsVersion","Win2k Sp4"); }elsif ($OsType eq "linux"){ $entity->SetFieldValue("OsVersion", "Redhat AS4"); }elseif ($OsType eq "unix"){ $entity->SetFieldValue("OsVersion", "AIX 5L"); }else{ $entity->SetFieldValue("OsVersion", "unknown"); }}[/td][/tr][/table] 4)Accept 操作的 AccessControl Hook: 在本系统中,对于 Duplicate 的 defects 不能直接操作。所以编写 AccessControl Hook,判断当前的状态是否为 Duplicate,如果是,则拒绝执行。 在 ClearQuest Designer 中打开模板,选择 Record Types ->defect ->States and Actions ->Actions,双击 Actions。点击 Accept 操作的 Access Control hook,选择 SCRIPTS ->;Perl:

[img=564,335]http://www.ibm.com/developerworks/cn/rational/r-cq-hook/images/image023.jpg/img][

现在可以开始编写 Accept 操作的 Access Control hook 了:

[img=564,251]http://www.ibm.com/developerworks/cn/rational/r-cq-hook/images/image025.jpg/img][

编写如下的脚本:

[table=98%][tr][td] sub defect_AccessControl { # Set $result to 1 if the user has permission to perform # this action, otherwise set it to 0. my($session, $state); $session = $entity->GetSession(); $state = $entity->GetFieldValue("State")->GetValue(); if($state eq "duplicate"){ $result = 0; }else{ $result = 1; }return $result;}[/td][/tr][/table] 5)Accept 操作的 Commit Hook: 同样的,点击 Accept 操作的 Commit hook,选择 SCRIPTS ->;Perl,编写如下的脚本:

[table=98%][tr][td] sub defect_Commit { # This hook is fired during the "commit" step of an entity update, so # it is the appropriate place to put activity which should be bundled # into the same transaction as the commit, such as subactions or an # update of external data storage. my($duplicates, $count, $session, $link, $dup, $validresult); $session = $entity->GetSession(); $duplicates = $entity->GetDuplicates(); if(!$duplicates){ die; } $count = $duplicates->Count(); for($i=0; $i<$count; $i++){ $link = $duplicates->Item($i); $dup = $link->GetChildEntity(); $dup->EditEntity("Accept"); $validresult = $dup->Validate(); $session->OutputDebugString("\nAccept Validation Error: ".$validresult); # 调用其 duplicate defect 的 Commit 方法,又会触发调用其 duplicate defect 的 Commit Hook,从而递归验证关闭所有相关联的 defects。 $dup->Commit(); }}[/td][/tr][/table] 6)全局 Hook 我们编写一个全局 Hook,定义一个简单的方法"BuildLogEntry"来组装一个字串: 在模板中,右击 Global Scripts ->;Perl,选择 Add 添加 global script,并编写如下脚本:

[img=516,323]http://www.ibm.com/developerworks/cn/rational/r-cq-hook/images/image027.jpg/img][

[table=98%][tr][td] sub BuildLogEntry { my($action, $login) = @_; return "\n*** Action committed ***"."\nAction Taken: ".$action."\nUser: ".$login;}[/td][/tr][/table] 7)"LogBase"的 Notification Hook: 为实现在日志文件中记录所有提交执行的操作的功能,我们定义了 BASE 类型操作 "LogBase",并为其定义了 Notification Hook。这个 Hook 调用了 Global Hook"BuildLogEntry"。 点击 LogBase 操作的 Commit hook,选择 SCRIPTS ->;Perl,编写如下的脚本:

[table=98%][tr][td] sub defect_Notification { # Post-commit notifications about actions may be handled here. my($session, $logFile, $login, $logEntry); $session = $entity->GetSession(); # 操作执行的信息记录在 f:\tmp\actions.log 中 open($logFile, "+>>f:\tmp\actions.log") || $session->OutputDebugString("open actions.log failed"); $login = $session->GetUserLoginName(); $logEntry = BuildLogEntry($actionname, $login); print $logFile $logEntry; close($logFile); }[/td][/tr][/table] 8)Delete 权限控制 Hook: 限制只有特定组"defectcoordinators"的用户才能删除 defects。 这个功能也可以对 Delete 操作的权限控制直接定义用户组来实现。这里是为了演示 Hook 的功能。使用 Hook 可以实现更复杂的逻辑。 点击 Delete 操作的 Access Control hook,选择 SCRIPTS ->;Perl,编写如下的脚本:

[table=98%][tr][td] sub defect_AccessControl { my $session = $entity->GetSession(); my @groups; $groups = $session->GetUserGroups(); $session->OutputDebugString("\nThe first groups is ".@$groups[0]); $result = 0; my $group; for $group (@$groups){ if ($group eq "defectcoordinators"){ $result = 1; break; } }}[/td][/tr][/table] 9)记录类型 hook 最后,为了演示记录类型 hook 的使用方法,我们再定义一个类型为 RECORD_SCRIPT_ALIAS 的操作"ExportDefect"。它所关联的 record scripts 是我们定义的记录类型 hook "defect_ExportDefectToTxt"。defect_ExportDefectToTxt 将当前 defect 基本信息写到一个文本文件中: 首先先定义一个记录类型 hook"defect_ExportDefectToTxt"。在模板中,右击 Record Types ->defect ->Record Scripts ->;Perl,选择 Add 添加 record script,并编写如下脚本:

[img=456,341]http://www.ibm.com/developerworks/cn/rational/r-cq-hook/images/image029.jpg/img][

[table=98%][tr][td] sub defect_ ExportDefectToTxt { my($result); if (ref ($param) eq "CQEventObject") { # add your CQEventObject parameter handling code here my($MYFILE, $session, $DefectId, $description); $session = $entity->GetSession(); $DefectId = $entity->GetFieldValue("defectid")->GetValue(); open($MYFILE, "+>f:\tmp\Exported_".$DefectId.".defect") || $session->OutputDebugString("\nExport File Open failed!"); $DefectId = $entity->GetFieldValue("DefectId")->GetValue(); $description = $entity->GetFieldValue("Description")->GetValue(); print $MYFILE ("\nDefectID: " . $DefectId . "\nDefectDescription: " . $description); close($MYFILE); } elsif (ref (\$param) eq "SCALAR") { # add your scalar parameter handling code here } else { # add your handling code for other type parameters here, for example: # die("Unknown parameter type");} }[/td][/tr][/table] 然后,回到 actions 定义窗口,点击操作类型为 RECORD_SCRIPT_ALIAS 的 "ExportDefect"的 Record Scripts,选择刚才定义的 record script。这样,在 ClearQuest 客户端选择操作"ExportDefect"就会触发 defect_ ExportDefectToTxt Hook 脚本。

[img=516,252]http://www.ibm.com/developerworks/cn/rational/r-cq-hook/images/image031.jpg/img][

最后,为 defect 记录类型定义一个表单。如下图所示:

[img=553,350]http://www.ibm.com/developerworks/cn/rational/r-cq-hook/images/image033.jpg/img][

ClearQuest 客户端的实际操作 现在,我们来实际演示一下在实际操作中这些 Hooks 是如何发生作用的。 首先创建用户组"defectcoordinators"和用户"Mary""Rose",其中"Mary"是"defectcoordinators"的组员。根据刚才创建的模板生成一个用户数据库,将用户组"defectcoordinators"和用户"Rose"加入此数据库。然后打开 ClearQuest 客户端,以用户 Mary 的身份连接到刚才创建的用户数据库,做如下操作: 1)创建一个 defect 纪录。DefectId 值是系统调用 Defect 的 Default Value Hook 自动生成的。如下图所示:

[img=592,402]http://www.ibm.com/developerworks/cn/rational/r-cq-hook/images/image035.jpg/img][

2)从下拉列表中选择 OsType 的值,由于触发了 OsType 的 Value Changed Hook,OsVersion 的值会自动设上:

[img=576,358]http://www.ibm.com/developerworks/cn/rational/r-cq-hook/images/image037.jpg/img][

3)我们创建 4 个 defects 用于测试系统 duplicate 的功能。通过 Duplicate 操作将 defect2、defect4 设为 defect1 的 duplicate,defect4 又设为 defect2 的 duplicate。

[img=612,312]http://www.ibm.com/developerworks/cn/rational/r-cq-hook/images/image039.jpg/img][

4)试图将 defect2 设为验证通过,打开 defect2,点击其 Action 列表中的 Accept。由于 Accept 的 Access Control Hook 不允许针对 duplicate 状态下的 defect 操作,所以得到错误信息,操作不能执行:

[img=528,373]http://www.ibm.com/developerworks/cn/rational/r-cq-hook/images/image041.jpg/img][

6)对 defect1 进行 Fix 和 Accept 操作,当 Apply Accept 操作(也就是提交 Accept 操作)时,defect1 的 Accept 操作的 Commit hook 被调用,所有直接和间接的 duplicate defects 都同时被验证通过:(需要刷新才能看到所有 defect 的最新状态)

[img=528,349]http://www.ibm.com/developerworks/cn/rational/r-cq-hook/images/image043.jpg/img][

7)察看系统的 actions.log 日志文件记录了所有提交执行的操作。这是目前 actions.log 的最后部分:

[table=98%][tr][td]*** Action committed Action Taken: DupUser: Mary Action committed Action Taken: DupUser: Mary Action committed Action Taken: DupUser: Mary Action committed Action Taken: FixUser: Mary Action committed ***Action Taken: AcceptUser: Mary[/td][/tr][/table] 8)在 defect 记录的表单中,有我们自定义的操作 Exportdefect 选项:

[img=492,373]http://www.ibm.com/developerworks/cn/rational/r-cq-hook/images/image045.jpg/img][

对 defect4 点击 Exportdefect 进行操作,触发调用了我们定义的记录类型 hook "defect_ExportToTxt",当前的 defect 信息会写入对应的文件 Exported_4.defect 中,其内容为:

[table=98%][tr][td] DefectID: 4DefectDescription: duplicate to 1[/td][/tr][/table] 9)以另外一个用户 Rose 的身份登陆,尝试删除某个 defect。Delete 的 Access Control Hook 检测到 Rose 不是 defectcoordinators 组的成员,操作不能执行:

[img=480,346]http://www.ibm.com/developerworks/cn/rational/r-cq-hook/images/image047.jpg/img][

在刚才的一系列操作中,我们触发调用了本模板定义的所有 Hooks,均能正常工作。

总结 Hooks 是 ClearQuest 提供的一个很重要、很有用的功能。利用它就可以非常灵活的定义变更管理模板,扩展 ClearQuest 的功能。同时,使用编写 Hooks 也是非常的方便。

关于作者 [table=98%][tr][td=3,1][img]http://www.ibm.com/i/c.gif/img]/td]/tr] tr] td][ [/td][td][img=4,5]http://www.ibm.com/i/c.gif/img]/td] td] 吴嘉,现为 IBM 中国软件开发实验室工程师,参与过多个开发、测试、技术支持项目。今年加入 Rational[ Engineering 部门,参与 ClearQuest 产品的开发工作。 [/td][/tr][/table]

[[i] 本帖最后由 CMing 于 2008-7-17 15:32 编辑 ]

good~ 听我一个校友说,IBM 自己都用的是 Excel 表格 -,-~~

very good.

很好的 CQ hook 学习资料.

多多努力,多多学习,共同进步.

需要 登录 后方可回复。