CRUD RTC work items using cURL (Part 2: Create)

I hope you enjoy my first post on the subject: CRUD RTC work items using cURL (Part 1: Read)

At this point we should have all the inputs to create a new work item using the OSLC APIs. It is time to retrieve the OSLC factory service used to create a work item. Actually, by calling the REST API answering the list of services provides by a project area:

rem Authentication
...
rem Request the url using the authentication
curl.exe -k -b %COOKIES% https://jazz.server.com:9443/ccm/oslc/contexts/_TN0swJPUEeOnRa9khWwR1A/workitems/services.xml

you can retrieve the Work Item creation service. Actually, you will retrieve for each of your Work Item type a corresponding “factory” service.

So, if you want to create a task, retrieve the factory title “Location for creation of Task change requests”, the associate oslc_cm:url element provides the REST API to create a Task.

<oslc_cm:factory calm:id="requirementChangeRequest">
	<dc:title>Location for creation of Task change requests </dc:title>
	<oslc_cm:url>https://jazz.server.com:9443/ccm/oslc/contexts/_TN0swJPUEeOnRa9khWwR1A/workitems/task</oslc_cm:url>
</oslc_cm:factory>

Now to create a work item you can run the following code:

rem Authentication
...
curl.exe -k -b %COOKIES% -H "Content-Type: application/x-oslc-cm-change-request+xml" -H "Accept: text/xml" -X POST -d @newtask.xml https://jazz.server.com:9443/ccm/oslc/contexts/_TN0swJPUEeOnRa9khWwR1A/workitems/task

The cURL instruction references several important parameters:

  • The “-H” parameters specify the format of the body request (“Content-Type: application/x-oslc-cm-change-request+xml”) as well as the answer format (“Accept: text/xml”).
  • The “-X” parameter specifies the HTTP method to use: a POST method to create a new work item.
  • The “-d” parameter designates the content of the request body. You can either provide a string with the XML code of your new work item or you can use the character @ and reference a file containing the XML code of your new work item.

In our case we decided to use a separate file named “newtask.xml” containing the following XML code:

<oslc_cm:ChangeRequest
    xmlns:oslc_cm="http://open-services.net/xmlns/cm/1.0/"
    xmlns:dc="http://purl.org/dc/terms/"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:calm="http://jazz.net/xmlns/prod/jazz/calm/1.0/"
    xmlns:rtc_cm="http://jazz.net/xmlns/prod/jazz/rtc/cm/1.0/"
    xmlns:oslc_pl="http://open-services.net/ns/pl#">

        <rtc_cm:filedAgainst rdf:resource="https://jazz.server.com:9443/ccm/resource/itemOid/com.ibm.team.workitem.Category/_UFKkcJPUEeOnRa9khWwR1A"/>
        <oslc_cm:priority <span="" class="hiddenSpellError" pre="priority " data-mce-bogus="1">rdf:resource="https://jazz.server.com:9443/ccm/oslc/enumerations/_TN0swJPUEeOnRa9khWwR1A/priority/priority.literal.l01"/>
        <oslc_cm:severity <span="" class="hiddenSpellError" pre="severity " data-mce-bogus="1">rdf:resource="https://jazz.server.com:9443/ccm/oslc/enumerations/_TN0swJPUEeOnRa9khWwR1A/severity/severity.literal.l3"/>
        <dc:title>New PK Task</dc:title>
        <rtc_cm:plannedFor rdf:resource="https://jazz.server.com:9443/ccm/oslc/iterations/_TPm1c5PUEeOpAbBwyZpuzw"/>
</oslc_cm:ChangeRequest></pre>
<pre>

As you can see this file doesn’t mention the work-item ID, it will be provided by the JTS during the creation of the work item and it will be returned in the request answer.

<dc:identifier>173</dc:identifier>

The answer has the same format as the one returned when we access to a work item.

The second post was easy to write once the first one is posted.

The third one will be more complex because it will talk about ETag which is concept I’m discovering.

In mid time, I hope this one will help you…

Advertisements

CRUD RTC work items using cURL (Part 1: Read)

Introduction

Often I wanted to learn how to use cURL to be able to interact with the OSLC API without using Java and often I run out of time to do it. This time I could not avoid it because a colleague of mine was expecting an answer from me. So I decided to go thru all the learning process and figure it out.

First of all, you need to have a good understanding of what OSLC is all about, it will help you figure out the technology and the API we are using to interact with our Jazz Team Server (JTS). For that check out some references mentioned at the end of this article.

These days you can find more and more inputs about OSLC, RESTFul and cURL than I could find in some early days, when I started playing with OSLC. So don’t hesitate to “google” if you have any concern regarding one of the mentioned points.

This article should be split in four CRUD parts :

  • Part 1: How to Read a Work Item using cURL.
  • Part 2: How to Create a Work Item using cURL
  • Part 3: How to Update a Work Item using cURL
  • Part 4: How to Delete a Work Item using cURL

And you are reading the first one.Read More »

Jazz Form-based Authentication

This spring Steve Wasleski (Jazz Jumpstart team), Steve Speicher (OSLC and Change Management Architect) and myself built a workshop on Jazz Extensibility for Innovate 2010, the Rational Software Conference. This workshop, labs and source code, has been published on jazz.net under this link: OSLC Workshop and Jazz Extensions Workshop.

During the labs elaboration, I had to understand how the Jazz Team Server manages the authentication: Form-based Authentication and how to interact with it as a client. Because it took me some times to figure it out, I think this blog is a good place to extract this part of the lab and share it with the “Rest of the World”.

The Form-Based Authentication is a three steps process:

  1. The client requests a protected resource.
  2. If the client is not authenticated, the server redirects to the login page, and the client has to fill the form and submit it to the server.
  3. If the login has succeeded, the client submits a request the protected resource again and should get it back.

Clearly, the behavior doesn’t seem obvious because the process seems to indicate that it requires a human behind interaction.
Actually, you can perfectly emulate and manage this interaction programmatically.
Let say you want to reach a resource designated by a URL (protectedResource) which is protected by a Form-based authentication.
The following snippet code describes how you will implement this 3-steps process:

HttpGet documentGet = new HttpGet(protectedResource);
documentGet.addHeader("accept", mediaType);
//
// Step (1): Request the protected resource
//
HttpResponse response = httpClient.execute(documentGet);
if (response.getStatusLine().getStatusCode() == 200) {
   Header header =
         response.getFirstHeader("x-com-ibm-team-repository-web-auth-msg");
   if ((header!=null) && ("authrequired".equals(header.getValue()))) {
      response.getEntity().consumeContent();
      // The server requires an authentication: Create the login form
      HttpPost formPost = new HttpPost(serverURI+"/j_security_check");
      List nvps = new ArrayList();
      nvps.add(new BasicNameValuePair("j_username", login));
      nvps.add(new BasicNameValuePair("j_password", password));
      formPost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
      //
      // Step (2): The client submits the login form
      //
      HttpResponse formResponse = httpClient.execute(formPost);
      header = formResponse.getFirstHeader("X-com-ibm-team-repository-web-auth-msg");
      if ((header!=null) && ("authfailed".equals(header.getValue()))) {
         // The login failed
         throw new InvalidCredentialsException("Authentication failed");
      } else {
         // The login succeed
         formResponse.getEntity().consumeContent();
         //
         // Step (3): Request again the protected resource
         //
         HttpGet documentGet2 = new HttpGet(protectedResource);
         documentGet2.addHeader("accept", mediaType);
         return httpClient.execute(documentGet2);
      }
   }
return response;

This code is based on Apache HTTP Client (Release 4.0.1) APIs.

I hope it will help.

-Philippe