XCAP協議中的冪等性(idempotency)研究

XCAP協議中的冪等性(idempotency)研究
************************************************************************
作者:胡家輝/雨水 轉載請註明出處http://blog.csdn.net/gobitan
************************************************************************
XCAP(XML Configuration Access Protocol,XML配置訪問協議),也稱XML配置接入協議。它是IETF制定的一個協議,前面陸續發佈了一系列草案,於2007年5月正式成爲RFC規範。
該協議允許客戶端讀、寫、修改存放在服務器中的XML格式的應用配置數據。XCAP將XML文檔中的節點映射到HTTP URIs中,使得這些組件能夠直接通過HTTP訪問。
該協議中有一個極爲重要的概念—冪等性,英文爲idempotency。如果讀者最先沒有接觸過相關協議,初次遇到這個概念難免不知所云。本文結合XCAP協議對這個概念做出解釋。
首先,我們來看一下XCAP協議的原文,看看協議怎麼說。原文摘自RFC 4825。
7. Client Operations
HTTP also specifies that PUT and DELETE requests are idempotent. This means that, if the client performs a PUT on a document and it succeeds, it can perform the same PUT, and the resulting document will look the same(HTTP也要求PUT和DELETE請求滿足冪等性。這意味着,如果一個客戶端在一個文檔上執行了PUT操作,並且執行成功。那麼在該文檔上再次執行同樣的PUT操作,操作後的文檔跟操作前是一樣的(即內容沒有發生改變)). Similarly, when a client performs a DELETE, if it succeeds, a subsequent DELETE to the same URI will generate a 404; the resource no longer exists on the server since it was deleted by the previous DELETE operation(同樣地,當客戶端執行一個DELETE,如果成功了,那麼接下來的具有同樣URI的DELETE操作將返回404,這是因爲先前的DELETE已經將該資源刪除,該資源已經不存在了) . To maintain this property, the client SHOULD construct its URIs such that, after the modification has taken place, the URI in the request will point to the resource just inserted for PUT (i.e., the body of the request), and will point to nothing for DELETE(爲了維護這個屬性,客戶端構造的URI應該滿足:修改發生之後,請求中的URI對於PUT來說將指向剛剛插入的資源(如請求消息體),對於DELETE則指向空). If this property is maintained, it is the case that GET to the URI in the PUT will return the same content (i.e., GET(PUT(X)) == x). This property implies idempotency(如果滿足該屬性,那麼對PUT請求中的URI執行GET操作將返回與PUT請求消息體中同樣的內容(即GET(PUT(X)==X))這個屬性就被稱爲冪等性). Although a request can still be idempotent if it does not possess this property, XCAP does not permit such requests. If the client's request does not have this property, the server will reject the request with a 409 and indicate a cannot-insert error condition.(儘管不擁有這個屬性的請求也可能是冪等的,但是XCAP不允許這樣的請求。如果客戶的請求不具有這個屬性,那麼服務器將以409拒絕,並指示不能插入錯誤。)
從上面協議中的描述可以看出,這裏的冪等性主要與修改操作有關,即PUT和DELETE方法。對於PUT來說,就是同樣的PUT操作無論執行多少次,其結果都跟第一次執行的結果相同,後面會介紹一個例子。
而對於DELETE操作來說,一次刪除之後資源就不存在了。這裏舉一個不滿足冪等性的DELETE例子,如某個DELETE操作指示刪除XML文檔中某個根元素下的第一個元素,如果該根元素下不只一個元素,那麼顯然該操作不滿足冪等性。因爲第一次該根元素下的第一個元素被刪除了,但是第二個元素自動成爲了該根元素的第一個元素,第二次執行DELETE時並不返回404,因此不滿足冪等性的規定。
下面我們再看看協議中7.4節對冪等性的描述,它提到了冪等性對操作所帶來的限制以及解決辦法。
7.4. Create or Replace an Element
To be certain that element insertions have the GET(PUT(x))==x property, the client can check that the attribute predicates in the final path segment of the URI match the attributes of the element in the body of the request. As an example of an request that would not have this property and therefore not be idempotent, consider the following PUT request (URIs are line-folded for readability):
(爲了確保元素插入滿足冪等性,客戶端應該檢查URI路徑中的屬性謂詞,看它是否與請求消息體中元素的屬性值向匹配。一個不具有該屬性的請求,它是非冪等的,來看下面的請求(URI折行是爲了便於閱讀))
PUT
/rls-services/users/sip:[email protected]/index/~~/rls-services/
service%5b@uri=%22sip:[email protected]%22%5d
HTTP/1.1
Content-Type:application/xcap-el+xml
Host: xcap.example.com
<service uri="sip:[email protected]">
<resource-list>http://xcap.example.com/resource-lists/users /sip:[email protected]/index/~~/resource-lists/list%5b@name=%22l1%22%5d
</resource-list>
<packages>
<package>presence</package>
</packages>
</service>
This request will fail with a 409. The Request URI contains a final path segment with a predicate based on attributes - @uri="sip:[email protected]". However, this will not match the value of the "uri" attribute in the element in the body (sip:[email protected])(請求將以409失敗。該請求的URI中包含了@uri="sip:[email protected]"。然而它與請求消息體中元素的屬性值sip:[email protected]不匹配).
也就是說,上面例子中URI中屬性指示的值與請求消息體中不匹配,因此不滿足冪等性。下面的協議部分講述了冪等性的侷限性。
The GET(PUT(x))==x property introduces some limitations on the types of operations possible. It will not be possible to replace an element with one that has a new value for an attribute that is the sole unique element identifier, if the URI contained a node selector which was using the previous value of that attribute for purposes of selecting the element. This is exactly the use case in the example above(GET(PUT(x))==x屬性給某些操作帶來了一些限制。對於用一個新的屬性值去替換一個元素,而該屬性是該元素的唯一標識,這操作是可能執行的。因爲如果URI的節點選擇符中包含了先前的屬性值,那麼這正好是上面例中的情況). To get around this limitation, the selection can be done by position instead of attribute value, or the parent of the element to be replaced can be selected, and then the body of the PUT operation would contain the parent, the child to be replaced, and all other siblings.
(爲了解決這個限制問題,可以通過基於位置的屬性值替換。或者通過選擇元素的父元素替換,這樣它的子元素和所有其他兄弟都將被替換。)
下面對上面協議的描述做一個解釋。冪等性帶來的限制就是如果該屬性唯一標識該元素,那麼無法用新的屬性值去替換一個元素。比如下面的例子,假設XML文檔中含有如下元素:
<book id=”1234567”>Inside the C++ Object Model</book>
這個時候你以如下的元素來替換上面的元素將是無法辦到的,即
<book id=”7654321”>Unix Network Programming</book>
原因在於,你如果要替換該元素那麼首先要通過id=”1234567”來把該元素標識出來,即指明你要替換這個元素。然而你的PUT請求消息體中的id卻是”7654321”,這就恰恰違背了冪等性操作的約束。這就使冪等性所帶來的限制。
參考文獻: http://www.ietf.org/rfc/rfc4825.txt
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章