運用 REST API 整合及擴充套件 IBM Rational Team Concert

myattitude發表於2010-08-03
沈 銳, 軟體工程師, IBM

簡介: 從 IBM Rational Team Concert 2.0 開始,REST API 得到了正式地支援(實驗版釋出在RTC 1.0.1)。雖然目前 REST API 提供的功能還比較有侷限,但對於一般的整合需求已經足夠,而且對於 REST API 的增強在後續版本中會不斷推出。本文將引領讀者瞭解在 RTC 2.0.0.2 中 REST API 所提供的功能以及相關概念。並且提供了一個 Java 實現的 RTC REST API 客戶端程式供讀者參考。


 

IBM Rational Team Concert 簡介

IBM Rational Team Concert (RTC) 是構建在 IBM Rational 面向軟體交付技術的下一代協作平臺 Jazz 平臺上的第一個商用產品、一個協作式的軟體開發環境,它包含了整合的原始碼控制、工作項管理和構建管理等功能。IBM Rational Team Concert 是一個可實時相互協作的軟體交付環境,可以幫助跨地域分佈的開發團隊簡化協作開發過程,並使其軟體交付過程實現自動化管理。developerWorks 及網路上有大量的文章對 RTC 進行介紹,這裡就不再贅述。參考資源部分列出了一些資源供大家學習。截至本文發表 RTC 最新的穩定版是 2.0.0.2,因此,以下所有對於 RTC REST API 的介紹都是基於 2.0.0.2 的。

OSLC-CM 規範

RTC REST API 的實現遵守 OSLC-CM 規範。

什麼是 OSLC?

OSLC 是 Open Service for Lifecycle Collaboration 的縮寫,亦即面向生命週期協作的開放服務。OSLC 社群的成立旨在幫助軟體實施團隊在合作中簡化生命週期工具的使用。OSLC 社群的使命是建立開放、公開的資源和介面描述用以分享軟體實施團隊所依賴的基礎設施,例如,變更管理、測試用例、缺陷、需求以及使用者故事。倘若所有對生命週期資源和服務的訪問都遵從公共的規範,工具之間傳統的障礙將自然消除從而開啟一扇通向新型協作方式的大門。無論是對於最敏捷的或者是最傳統的專案,OSLC 都能夠為軟體實施團隊以及工具提供商帶來價值,同樣,它也能夠造福於商業工具、開源工具以及內部開發的工具。

什麼是 OSLC-CM?

OSLC-CM 是 OSLC 的一個子集。它的重點在於變更管理(Change Management)。通過 OSLC-CM 你可以查詢、連結、獲取、建立以及更新變更請求。

RTC REST API 概述

RTC 1.0 僅提供給使用者 Java API 以整合和擴充套件 RTC。Java API 包含兩部分:Eclipse 外掛 API 和一般 Java API。Eclipse 外掛 API 適用於在現有的 RTC Eclipse 客戶端中擴充套件 RTC 應用而一般 Java API 則適用於普通的 Java 應用程式。在 RTC 1.0.1 中,出現了 REST API,不過是實驗版。在 RTC 2.0 中,RTC 正式開始支援 REST API,目前 REST API 支援的功能還較為有限,但對於一般的整合需求已經足夠,其功能主要集中在對工作項(Work Item)的管理。在後續的版本中,越來越多的功能將會加入到 REST API 中。目前已經有不少軟體在使用 RTC REST API,例如 Mylyn、Rational Quality Manager、Rational Requirements Composer 以及 Git Integration 等。

關於 REST 的優點,維基百科上是這樣定義的:

  • 可以利用快取 Cache 來提高響應速度
  • 通訊本身的無狀態性可以讓不同的伺服器的處理一系列請求中的不同請求,提高伺服器的擴充套件性
  • 瀏覽器即可作為客戶端,簡化軟體需求
  • 相對與其他疊加在 HTTP 協議之上的機制,REST 的軟體依賴性更小
  • 不需要額外的資源發現機制
  • 在軟體技術演進中的長期的相容性更好

對 RTC 而言,有了 REST API 的支援後,客戶端的程式語言將不再侷限於 Java。即便你的應用是一般的 Java 應用,REST API 同樣值得推薦,因為使用 REST API 程式碼更加簡潔並且依賴的 Jar 檔案比較少(使用 Java API 約需要引入大約 20M 的 Jar 檔案,但是使用 REST API 大約只需要引入 3M 左右的 Jar 檔案,見本文提供的示例程式)。

簡單來說,RTC REST API 提供瞭如下功能:

  • 以多種格式(如 JSON、XML、ATOM 以及 HTML)在不同粒度級別上獲取工作項
  • 通過更新 JSON 或者 XML 的方式修改工作項的屬性
  • 通過獲取 HTML 的建立對話方塊模組來建立工作項
  • 通過傳送帶有 JSON 或者 XML 格式資料的 Post 請求建立工作項
  • 增加或者刪除連結
  • 通過全文檢索和指定屬性查詢工作項
  • 通過獲取 HTML 的選擇器模組查詢工作項

RTC REST API 詳解

下面對 RTC REST API 的功能做更為具體的介紹。

服務發現

RTC 提供了服務發現機制。使用者應當通過該機制獲得需要的服務 URL 而不是將服務 URL 硬編碼在自己的程式中。根服務發現 URL 格式如下:

https://://rootservices

例項如:

https://localhost:9443/jazz/rootservices

該 URL 將返回一個 XML 文件,其中對主要的服務資源入口做了定義。該機制是一個鏈式機制,也就是說,當你獲得了根服務描述文件後,可以根據其中包含的資源的 URL 進一步獲取子集中的服務 URL。

獲取資源表象

通過如下兩種 URL 格式可以獲取資源表象。

格式一(位置 URI)

https://:/jazz/resource/itemName/
com.ibm.team.workitem.WorkItem/

例項如:

https://localhost:9443/jazz/resource/itemName/
com.ibm.team.workitem.WorkItem/262

以及

https://localhost:9443/jazz/resource/itemOid/
com.ibm.team.workitem.WorkItem/_Kk8YQFElEd6wrL4Qi7w25Q

格式二:

https://:/jazz/oslc/workitems/
.

例項如:

https://localhost:9443/jazz/oslc/workitems/821.xml

以及

https://localhost:9443/jazz/oslc/workitems/_Kk8YQFElEd6wrL4Qi7w25Q.json

此此格式主要用於開發階段。

除了 .xml 和 .json,其他幾種支援的媒體型別擴充套件包括:.hover.html,.atom 以及 .xhtml。如若要返回一個資源的多種表象則需要通過指定 HTTP 的 Accept 頭資訊或者在 URL 中指定 _mediaType 引數,例如:

https://localhost:9443/jazz/resource/itemName/
com.ibm.team.workitem.WorkItem/821?_mediaType=application/x-oslc-cm-changerequest%2Bjson

該 URL 將返回工作項 821 的 JSON 格式資料。

獲取資源表象部分屬性

有時我們只需要獲取一個資源部分屬性資料,尤其在移動裝置應用中,出於減少頻寬消耗的考慮,我們通常只獲取我們真正需要的資料。通過在 URL 中新增 oslc_cm.properties=propA,propB 可以實現資源部分屬性資料的獲取。例如:

https://localhost:9443/jazz/oslc/workitems/
821.json?oslc_cm.properties=dc:identifier,dc:title

將僅返回資源的 dc:identifierdc:title 屬性值。

查詢工作項

查詢工作項通過在 https://:/jazz/oslc/contexts//workitems 的後面新增 ?oslc_cm.query=[query] 語句實現。[query] 是一個 CM Query 語句。詳細語法請參見 變更管理查詢語法講解

例如,下面這個查詢是一個編碼過的全文檢索查詢,用來獲取所有包含“NPE”文字的工作項。

https://localhost:9443/jazz/oslc/contexts/_9BHm0EqVEd6HXO10niqZpg/workitems
?oslc_cm.query=oslc_cm%3AsearchTerms%3D%22NPE%22

同樣,你可以通過新增 oslc_cm.properties 語句限制結果返回的屬性值,並且還可以使用“/sort”指定查詢返回結果的排序方式。分頁查詢也是支援的,例如使用 oslc_cm.pageSize 引數就可以指定查詢結果每頁返回的條目數。

使用預定義的查詢語句

通過形如 https://localhost:9443/jazz/oslc/queries.xml(當然你可以用 queries.json)的 URL 可以獲得所有預定義的查詢語句。增加 oslc_cm.query 引數則可以根據指定的查詢引數過濾返回的查詢語句結果。獲取查詢語句的唯一識別符號之後,便可進而通過如下的 URL 獲取該查詢的返回結果。

https://localhost:9443/jazz/oslc/queries/_vS4rsF5eEd6EzYK1TPZjDw/rtc_cm:results.atom

建立工作項

構造併傳送包含某種媒體型別(例如 JSON)的工作項表象資料的 POST 請求到形如下的 URL 即可建立一個工作項:

https://localhost:9443/jazz/oslc/contexts/_9BHm0EqVEd6HXO10niqZpg/workitems

其中,_9BHm0EqVEd6HXO10niqZpg 是專案區域唯一識別符號。那麼,如何得知媒體型別的具體格式規範呢?當然,你可以通過檢視 OSLC-CM 規範獲得。但是,一個更為直觀快捷的方式是你先用那種媒體型別獲得某個工作項的資料,然後檢視其格式。例如,你可以通過以下的 URL 返回的資料得知如何定義一個工作項的 JSON 格式表象。

https://localhost:9443/jazz/oslc/workitems/821.json

建立草稿工作項同建立一般的工作項一樣,只需將傳送的目標 URL 改為如下:

https://localhost:9443/jazz/oslc/contexts/_9BHm0EqVEd6HXO10niqZpg/drafts/workitems

更新工作項

更新工作項的過程為:首先以某種媒體格式獲取資源資料,接著根據需要對資料進行修改,最後傳送 PUT 或者 PATCH 請求。可能會出現在你獲取資源並且提交修期間其他客戶端也修改了該資源的情況,如果沒有采取任何措施,那麼你的提交就會覆蓋先前那個客戶端的修改內容,從而造成資料丟失。為防止此現象的發生,你可以在獲取資源後獲取並儲存它的 ETag 屬性值,並在傳送 PUT 或者 PATCH 請求的 If-Match 頭資訊中設定該 ETag 值。那麼,倘若其他客戶端在期間做了修改,你將會收到 HTTP 響應的 412 返回程式碼。此時,你應該重新獲取資料並修改後重新提交。

更新工作項的部分屬性

有時我們需要更新工作項的部分屬性(或許這樣更加安全)。你可以通過以下兩種方式:

方法一:傳送 URL 中帶有 oslc_cm.properties 的 PUT 請求

例如,傳送 PUT 請求到:

https://localhost:9443/jazz/resource/
itemName/com.ibm.team.workitem.WorkItem/821?oslc_cm.properties=dc:type

無論傳送的資料中包含多少更改,都只更新 dc:type 屬性。

方法二:傳送 PATCH 請求

例如,傳送僅包含 dc:type 屬性的資料的 PATCH 請求到:

https://localhost:9443/jazz/oslc/workitems/821

也將只更改其 dc:type 屬性。

增加 / 刪除連結

通過在傳送的工作項表象資料中包含連結更新整個工作項是一增加連結的方式,除此以外,你還可以採用傳送包含如下的 JSON 或者 XML 資料的 POST 請求到形如:

https://localhost:9443/jazz/oslc/workitems/
821/oslc_cm:relatedChangeManagement

的 URL 的方式。

XML


JSON

{
 "rdf:resource":"https:\/\/example.org\/changerequests\/10253",
 "oslc_cm:label":"Task 10253"
}

如需增加多條連結,只需在 JSON 或 XML 資料中增加多項即可。

刪除連結如同增加連結一樣:從資料中刪除連結後,傳送 PUT 或者 PATCH 請求更新工作項。

增加備註

傳送帶有如下資料的 POST 請求到形如 https://localhost:9443/jazz/oslc/workitems/821/rtc_cm:comments 的 URL 可以為工作項增加備註。

{
 "dc:description":"My new comment"
}

上面的例子是 JSON 資料。當然,你也可以採用其他的媒體型別。

RTC REST API 客戶端示例程式介紹

通常,為了方便其他程式模組對 REST API 的呼叫,我們都會將其封裝。這樣的程式模組叫做 REST API 客戶端。本文提供了一個 Java 實現的 REST API 客戶端示例程式供使用者參考。當然,該示例程式純粹用於向讀者示範 RTC REST API 的使用,所以它對 RTC REST API 封裝的並不完整並且可能存有缺陷,為了簡單起見,其中資源 URL 也並非從 RTC 服務發現功能中獲取。因此,讀者若真要在自己的環境中使用,仍需要進一步修改和完善它。該示例程式簡單的封裝了對 RTC REST API 的呼叫,並實現瞭如下步驟的測試用例:

  1. 建立一個標題為“Sample title”的缺陷
  2. 通過缺陷的 ID 獲取該新建立的缺陷
  3. 修改缺陷的嚴重性以及標題值
  4. 為缺陷增加備註
  5. 將缺陷的狀態從 New 改為 Resolved 再改為 Closed
  6. 通過缺陷的狀態及標題查詢出該缺陷

開發環境的搭建

下載程式碼包 RTCRestClient_sample.zip,(參見下載)並直接作為已有專案匯入到工作區。出於種種考慮,本文附帶的程式碼包並未包含依賴的 Jar 檔案,因此你會發現專案有編譯錯誤,所以接下來你需要自己下載依賴的 Jar 檔案並手動新增到專案構建路徑當中。


圖 1. 匯入示例專案
圖 1. 匯入示例專案

以下是該示例程式依賴的開源專案:

  • HttpClient 4.0.1:用來傳送處理 HTTP 請求以呼叫 RTC REST API。
  • Json-lib 2.3 :示例程式中選用了 JSON 的傳送 / 返回資料格式。Json-lib 用來封裝傳送及返回的資料。
  • Log4j-1.2.12:用來輸出日誌。
  • 若干 Apache Commons 專案:這些都是 HttpClient 以及 Json-lib 依賴的庫檔案。

以下是你需要下載及匯入的 Jar 檔案:

  • apache-mime4j-0.6.jar
  • commons-beanutils-1.8.3.jar
  • commons-codec-1.3.jar
  • commons-collections-3.2.1.jar
  • httpclient-4.0.1.jar
  • httpcore-4.0.1.jar
  • httpmime-4.0.1.jar
  • commons-lang-2.5.jar
  • commons-logging-1.1.1.jar
  • ezmorph-1.0.6.jar
  • json-lib-2.3-jdk15.jar
  • log4j-1.2.12.jar

你可以從以下網站獲得上面的 Jar 檔案:

執行示例程式

如果專案能夠正常編譯之後,你就可以開始執行示例程式。下面是執行該示例程式的步驟:

步驟一:在 config.properties 中設定你的 RTC 的使用者名稱,密碼,RTC 基本 URL 以及專案區域名稱。


清單 1. config.properties 設定

# RTC account id, e.g shenrui@cn.ibm.com
username=shenrui@cn.ibm.com
# RTC account password
password=
# RTC base URL, e.g. https://:/jazz
rtc.base.url=
# Project Area name, e.g. Mashup Center
projectarea.name=Mashup Center

步驟二:執行 SampleCaller.java。由於示例程式中使用 JVM 的斷言語句,所以,請在執行配置中新增 JVM 引數“-ea”以啟用 JVM 的斷言功能。


圖 2. 示例程式執行設定
圖 2. 示例程式執行設定

如果一些正常,Eclipse 控制檯將顯示如下類似資訊。


清單 2. 控制檯輸出示例

2010-06-03 13:33:37 [com.ibm.rtc.restclient.SampleCaller]-[INFO] 
    14789 was created successfully. -(:40)
2010-06-03 13:33:44 [com.ibm.rtc.restclient.SampleCaller]-[INFO] 
    14789 was retrived successfully. -(:47)
2010-06-03 13:34:01 [com.ibm.rtc.restclient.SampleCaller]-[INFO] 
    14789 was updated successfully. -(:59)
2010-06-03 13:34:20 [com.ibm.rtc.restclient.SampleCaller]-[INFO] 
    14789 was closed successfully. -(:72)
2010-06-03 13:34:31 [com.ibm.rtc.restclient.SampleCaller]-[INFO] 
    14789 was searched successfully. -(:84)

示例程式原始碼解析

開啟包管理器,所有類如下圖所示。


圖 3. 原始碼包結構
圖 3. 原始碼包結構

下面對每個類的功能進行簡單地介紹。

RTCRestClientException.java 該類作為該專案的根 Exception 類。 Resource.java 該類封裝了 RTC 中常規資源的屬性:包含資源的名稱、型別以及對應的資源 URL。比如工作項中的 Severity、Priority 以及 State 等都是一個資源物件例項。 Workitem.java 該類對 RTC 中的工作項進行了封裝。一個工作項中通常包含唯一識別符號、標題、描述、Severity、Priority 等屬性。該類也包含了同 JSON 物件之間相互轉換的方法。 Configuration.java 該類用於讀取系統配置檔案 config.properties。 QueryResults.java 該類用以封裝 REST API 的查詢結果。 RTCRestClient.java 該類封裝了對 RTC REST API 呼叫,以傳統的 Java 方法暴露對 RTC 的操作。對於每次 REST API 操作,程式會檢查是否已進行過認證或者之前認證後獲取的 Cookie 是否仍有效或者已過期。如果 Cookie 已過期則重新認證。本示例程式碼實現是表單認證方式,如果你的 RTC 配置的是基本認證方式則需要自己對程式碼做些修改。 WorkitemManager.java 該類通過對 RTCRestClient.java 的呼叫封裝了若干對工作項的操作,例如建立工作項、查詢工作項、修改工作項狀態等操作。 SampleCaller.java 該類是一個示例客戶端呼叫程式。它呼叫了 WorkitemManager 中的方法並輸出執行結果。


 

建立工作項程式碼詳解


圖 4. UML 時序圖(建立工作項)
圖 4. UML 時序圖(建立工作項)

從上面的時序圖中,讀者可以清楚地瞭解程式碼之間的呼叫關係。下面是相關的程式碼片斷。


清單 3. SampleCaller.java

Workitem wi=new Workitem();
wi.setTitle(title);
wi.setDescription("Sample description");
wi.setFiledAgainst(new Resource(Resource.RES_TYPE_FILEDAGAINST,"MM V2.4"));
wi.setFoundIn(new Resource(Resource.RES_TYPE_FOUNDIN,"2.4/CSA2"));
wi.setSeverity(new Resource(Resource.RES_TYPE_SEVERITY,"Sev4"));
wi.setPriority(new Resource(Resource.RES_TYPE_PRIORITY,"Low"));
wi.setOwnedBy(RTCRestClient.getInstance().getUser("example@example.com"));
wi.setType(new Resource(Resource.RES_TYPE_TYPE,"Defect"));
wi=manager.createWorkitem(wi);

首先,建立一個 Workitem 例項,然後構造並設定需要的屬性,之後呼叫 WorkitemManager.java 的 createWorkitem 方法建立工作項。


清單 4. WorkitemManager.java

public Workitem createWorkitem(Workitem workitem){
    JSON jsonObject=client.post(projectAreaWorkitemsUrl, workitem.toJSONString());
    return Workitem.fromJSON((JSONObject) jsonObject);
}

createWorkitem 方法呼叫 RTCRestClient.java 的 post 方法傳送 POST 請求以建立 Workitem,之後並呼叫 Workitem.java 的 fromJSON 方法將返回的字串構造成一個 Workitem 例項作為方法返回值。


清單 5. RTCRestClient.java

public JSON post(String url, String requestContent) {
        return jsonHttp(url, HTTP_METHOD_POST, requestContent);
    }
private JSON jsonHttp(String url, int httpType, String requestContent) {
try {
    authenticate();
    DefaultHttpClient httpClient = new DefaultHttpClient();
    httpClient.getCookieStore().addCookie(cookie);
    HttpRequestBase httpMethod = null;
    switch (httpType) {
        case HTTP_METHOD_GET:
            httpMethod = new HttpGet(url);
            break;
        case HTTP_METHOD_POST:
            httpMethod = new HttpPost(url);
            break;
        case HTTP_METHOD_PUT:
            httpMethod = new HttpPut(url);
            break;
        }
        httpMethod.addHeader("Content-Type","application/x-oslc-cm-change-request+json");
        httpMethod.addHeader("Accept", "text/json");
        if (httpType == HTTP_METHOD_POST || httpType == HTTP_METHOD_PUT) {
            StringEntity requestEntity = new StringEntity(requestContent);
                ((HttpEntityEnclosingRequestBase) httpMethod)
                        .setEntity(requestEntity);
        }
        HttpResponse response = httpClient.execute(httpMethod);
        String rtJson = convertStreamToString(response.getEntity()
                    .getContent());
        httpClient.getConnectionManager().shutdown();
        return JSONSerializer.toJSON(rtJson);
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

jsonHttp 對各種型別的 HTTP 請求進行了封裝並將返回值構造成 JSON 物件。而 post,get 以及 put 方法都呼叫 jsonHttp 方法實現真正的 HTTP 請求操作,只是傳入了不同的 HTTP 請求型別字串 httpType。HTTP_METHOD_GET,HTTP_METHOD_POST 以及 HTTP_METHOD_PUT 是三個字串靜態常量,用來代表不同的 HTTP 請求型別。

清單 6. Workitem.java

public static Workitem fromJSON(JSONObject jsonObject) {
    DynaBean bean = (DynaBean) JSONSerializer.toJava(jsonObject);
    Workitem workitem=new Workitem();
    workitem.setIdentifier(((Integer) bean.get("dc:identifier")).intValue());
    workitem.setTitle((String) bean.get("dc:title"));
    workitem.setDescription((String) bean.get("dc:description"));
    workitem.setType(createResource(bean,"dc:type",Resource.RES_TYPE_TYPE));
    workitem.setOwnedBy(createResource(bean,"rtc_cm:ownedBy",
        Resource.RES_TYPE_USER));
    workitem.setFoundIn(createResource(bean,"rtc_cm:foundIn",
        Resource.RES_TYPE_FOUNDIN));
    workitem.setFiledAgainst(createResource(bean,"rtc_cm:filedAgainst",
        Resource.RES_TYPE_FILEDAGAINST));
    workitem.setSeverity(createResource(bean,"oslc_cm:severity",
        Resource.RES_TYPE_SEVERITY));
    workitem.setPriority(createResource(bean,"oslc_cm:priority",
        Resource.RES_TYPE_PRIORITY));
    workitem.setState(createResource(bean,"rtc_cm:state",Resource.RES_TYPE_STATE));
    return workitem;
}

fromJSON 方法能夠將 JSONObject 物件轉換成一個 Workitem 例項。

更新工作項程式碼詳解


圖 5. UML 時序圖(建立工作項)
圖 5. UML 時序圖(建立工作項)

更新工作項的過程比建立工作項的過程稍微複雜一些。下面是相關的程式碼片斷。


清單 7. SampleCaller.java

/*
* Get the workitem
*/
wi=manager.getWorkitemById(wi.getIdentifier());
assert wi.getIdentifier()==workitemId;
logger.info(wi.getIdentifier()+" was retrived successfully.");
/*
* Change its severity
*/
Resource severity=wi.getSeverity();
severity.setTitle("Sev3");
wi.setSeverity(severity);
wi.setTitle(newTitle);
wi=manager.updateWorkitem(wi);
assert "Sev3".equals(wi.getSeverity().getTitle());
assert newTitle.equals(wi.getTitle());
logger.info(wi.getIdentifier()+" was updated successfully.");

SampleCaller 首先通過唯一識別符號呼叫 WorkitemManager.java 的 getWorkitemById 方法獲取 Workitem 例項,然後修改 Workitem 例項的屬性值,最後呼叫 WorkitemManager.java 的 updateWorkitem 方法更新 Workitem 例項。


清單 8. WorkitemManager.java

public Workitem updateWorkitem(Workitem workitem){
    String url=workitemsUrl+"/"+workitem.getIdentifier();
    JSON jsonObject=client.put(url, workitem.toJSONString());
    return Workitem.fromJSON((JSONObject) jsonObject);
}
public Workitem getWorkitemById(int id){
    String url=workitemsUrl+"/"+id;
    return Workitem.fromJSON((JSONObject) client.get(url));
}

WorkitemManager.java 呼叫 RTCRestCient.java 的 put 方法更新 Workitem 資料,其中的 workitemsUrl 在 WorkitemManager.java 的建構函式被初始化,程式碼如下:


清單 9. WorkitemManager.java 建構函式

private WorkitemManager(){
    client=RTCRestClient.getInstance();
    String projectAreaId=client.getProjectAreaId();
    String rtcBaseUrl=client.getRtcBaseURL();
    projectAreaWorkitemsUrl= rtcBaseUrl + "/oslc/contexts/" 
        + projectAreaId + "/workitems";
    workitemsUrl= rtcBaseUrl + "/oslc/workitems";
}

workitemUrl 理論上應當通過服務發現機制獲得,這裡只是從簡單實現角度出發,所以採用了字串拼接的方法。


清單 10. RTCRestClient.java

public JSON get(String url) {
    return jsonHttp(url, HTTP_METHOD_GET, null);
}

public JSON put(String url, String requestContent) {
    return jsonHttp(url, HTTP_METHOD_PUT, requestContent);
}

如“建立工作項詳解”部分所述:get 和 put 方法都呼叫 jsonHttp 方法實現真正的 HTTP 請求操作的。

值得一提的是目前無法通過像修改工作項的其他屬性那樣的方式修改工作項的狀態,而需要傳送帶有 _action 引數的 PUT 請求實現。例如,要關閉一個工作項,那麼需要傳送 PUT 請求到

https://localhost:9443/jazz/oslc/workitems/821?_action=bugzillaWorkflow.action.close

不過,action 字串是可以配置的,因此本示例中的這個 action 字串未必可以適用於你的 RTC,所以關於該 action 字串請聯絡你的 RTC 管理員。如果你需要你在關閉工作項的同時又修改某些工作項屬性,可以在傳送的 PUT 請求中資料中包含修改後的屬性值(當然,你需要把它構造成 JSON,XML 或者其他支援的媒體型別)。如果你不需要修改任何屬性,就在 PUT 請求中包含唯一識別符號。你可以在 WorkitemManager.java 的 changeState 方法中找到相關的程式碼。

另外,通過 RTCRestClient.java 的 getResUrlByTitle 方法,對於所有的資源,你只需要指定名稱就可以獲得資源對應的 URL 後構造出 Resource 例項。但是不幸地是在目前的版本中,你無法通過使用者的名稱查詢出對應的資源 URL(會出現一個 dc:title 無法被識別的錯誤資訊),所以該示例程式實現了 getUser(String userId) 方法從而通過使用者唯一識別符號獲取對應的使用者例項。

結束語

本文對涉及 RTC REST API 的相關概念以及其提供的功能做了介紹。但是限於篇幅原因,有些內容並未展開(例如,OSLC-CM 查詢語法),所以建議讀者在閱讀完本文後對於未展開講解的部分自己學習。另外,本文雖然附有 RTC REST API 客戶端的示例程式碼,但是它僅僅為讀者提供參考,所以,無論從功能的完整性以及整體程式架構上說,它都很不完善。讀者如果需要在自己的程式中整合 RTC,仍需要在參考示範程式碼的基礎上進一步修改和完善。

原文連結:http://www.ibm.com/developerworks/cn/rational/r-cn-rtc2restapi/index.html

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/14780914/viewspace-670085/,如需轉載,請註明出處,否則將追究法律責任。

相關文章