WS API: questions about deleting Attachments and AttachmentContent
search cancel

WS API: questions about deleting Attachments and AttachmentContent

book

Article ID: 57532

calendar_today

Updated On:

Products

Rally On-Premise Rally SaaS

Issue/Introduction

Attachment and AttachmentContent are separate objects in WS API.

1. If an attachment is deleted will its content be also deleted, or an orphaned AttachmentContent object remains in the system unless it is explicitly deleted?
2. If an attachment content is deleted will the relevant attachment be also deleted, or an empty attachment object remains in the system?

Resolution

1. If an attachment is deleted will its content be also deleted, or an orphaned AttachmentContent object remains in the system unless it is explicitly deleted?

Content of the attachment is automatically deleted when the related attachment is successfully deleted.

There are two separate objects in WS API related to this discussion: Attachment, which has a Content attribute, and a separate AttachmentContent object.
Content attribute points to the relevant AttachmentContent object.
Here is a Ruby example based on CA Agile Central Ruby REST Toolkit that deletes a specific attachment:

require 'rally_api'

#Setup custom app information
headers = RallyAPI::CustomHttpHeader.new()
headers.name = "My Utility"
headers.vendor = "N.M. RallyLab"
headers.version = "1.0"

# Connection to CA Agile Central
config = {:base_url => "https://rally1.rallydev.com/slm"}
config[:username] = "<User>@<Company.com>"
config[:password] = "<PASSWORD>"
config[:workspace] = "W1"
config[:project] = "P1"
config[:version] = "v2.0"
config[:headers] = headers #from RallyAPI::CustomHttpHeader.new()

@rally = RallyAPI::RallyRestJson.new(config)

query = RallyAPI::RallyQuery.new()
query.type = :attachment
query.workspace = {"_ref" => "https://rally1.rallydev.com/slm/webservice/v2.0/workspace/<WORKSPACE_OID>" } #use valid workspace oid 
query.query_string = "(ObjectID = \"<OBJECT_OID>\")" 
query.fetch = "ObjectID"

result = @rally.find(query).first
puts result["ObjectID"]

result.delete #success


Let's say we have an artifact in CA Agile Central of type defect with one attachment.

Replace ObjectIDs in this example with those valid in your subscription if you want to follow the steps outlined below and delete? attachments and attachment content in your subscription.

Paste a valid defect endpoint in the browser

https://rally1.rallydev.com/slm/webservice/v2.0/Defect/<DEFECT_OID>

The json includes Attachments collection object:

  • Attachments: {
    • _ref: "https://rally1.rallydev.com/slm/webservice/v2.0/Defect/<DEFECT_OID>/Attachments",
    • _type: "Attachment",
    • Count: 1
    },

Count 1 indicates that there is only one element in this collection. Click on the reference. This single attachment's URL is:

https://rally1.rallydev.com/slm/webservice/v2.0/attachment/<OBJECT_OID>

The json of the attachment includes a reference to AttachmentContent object:
https://rally1.rallydev.com/slm/webservice/v2.0/attachmentcontent/<OBJECT_OID>

If a Ruby code example above is run with this query:

query.query_string = "(ObjectID = \"<OBJECT_OID>\")" 

and the attachment is successfully deleted, pasting the following URLs in the browser shows that both the attachment and the content are gone:

https://rally1.rallydev.com/slm/webservice/v2.0/attachment/<OBJECT_OID>

{

  • OperationResult:?{
    • _rallyAPIMajor:?"2",
    • _rallyAPIMinor:?"0",
    • Errors:?[
      • "Cannot find object to read"
      ],
    • Warnings: [ ]
    }

}
https://rally1.rallydev.com/slm/webservice/v2.0/attachmentcontent/<OBJECT_OID>
{

  • OperationResult:?{
    • _rallyAPIMajor:?"2",
    • _rallyAPIMinor:?"0",
    • Errors:?[
      • "Cannot find object to read"
      ],
    • Warnings: [ ]
    }

}

2. If an attachment content is deleted will the relevant attachment be also deleted, or an empty attachment object remains in the system?

If an attachment content is deleted, an empty attachment object remains in the system.

Here is a fragment of code example that deletes attachment content:
?

@rally = RallyAPI::RallyRestJson.new(config)

query = RallyAPI::RallyQuery.new()
query.type = :attachment
query.workspace = {"_ref" => "https://rally1.rallydev.com/slm/webservice/v2.0/workspace/<WORKSPACE_OID>" } #use valid workspace oid 
query.query_string = "(ObjectID = \"<OBJECT_OID>\")" 
query.fetch = "ObjectID,Content"

result = @rally.find(query).first
puts result["ObjectID"]
puts result["Content"]["_ref"]
content = result["Content"]
content.delete


After the code is run, we copy the output of this line from the terminal

puts result["Content"]["_ref"]

https://rally1.rallydev.com/slm/webservice/v2.0/attachmentcontent/<OBJECT_OID>

and paste it in the browser, "Cannot find object to read" is returned:

{

  • OperationResult:
    ?
    {
    • _rallyAPIMajor: "2",
    • _rallyAPIMinor: "0",
    • Errors:
      ?
      [
      • "Cannot find object to read"
      ],
    • Warnings: [ ]
    }

}

If we download the respective attachment from Rally, it will show size 0.