4

I have several issues stored in my YouTrack Server and I would like to extract those issues and pack the information in Strings.

I already worked with the RESTClient, however I got bad output and thus want to try a different way to extract the issues using HttpBuilder and formatting the xml response in JSON. However I don't know yet, how to do that in Groovy (probably because I lack a complete, running example):

Going by this website and this

I would expect my code to look something like this:

def http = new HTTPBuilder('http://www.MyYouTrackServer.com')

AuthenticateMe() // I need that, otherwise I cannot access my server

http.get( path : 'MyIssue-25',
          contentType : JSON,
          query : [???'] ) { resp, reader ->
....        
        // This gap has to be filled somehow,        
        // so that I have a JSONObject or JSONArray, I can work with. 
....
      }
      println 'Response data: -----'
      System.out << reader
      println '\n--------------------'
    }
    String str; // this is the important String containing the data

Any constructive advice, answer or comment is appreciated.

The response then will look like this:

<issues>
 <issue>
  <comment created="1277899067543" text="is it something wrong?" author="root"/>
  <field name="numberInProject"><value>0</value></field>
  <field name="summary"><value>susjs</value></field>
  <field name="priority"><value>1</value></field>
  <field name="description"><value>at jsjsjsj.mps.E.java at line 12</value></field>
  <field name="created"><value>1277392628191</value></field>
  <field name="updated"><value>1277399118476</value></field>
  <field name="reporterName"><value>root</value></field>
  <field name="updaterName"><value>root</value></field>
  <field name="state"><value>Submitted</value></field>
  <field name="subsystem"><value>No subsystem</value></field>
  <field name="fixedInBuild"><value>Next build</value></field>
  <field name="permittedGroup"><value>All Users</value></field>
 </issue>
</issues>
albciff
  • 18,112
  • 4
  • 64
  • 89
blauerschluessel
  • 219
  • 1
  • 3
  • 14

2 Answers2

2

To achieve your goal you can use a follow approach to work with json:

import groovyx.net.http.HTTPBuilder


def http = new HTTPBuilder('http://www.MyYouTrackServer.com')
...
http.get(   path : '/MyIssue-25',
            contentType : 'application/json'
        ) { resp, reader ->

        // inside reader you've your json object in `net.sf.json.JSONObject` instance
        println reader

}

Take in account that query parameter of get() method it's optional, this parameter is used for query approach urls like https://twitter.com/search?q=asd, for this case the query parameter will be query : [ q : 'asd' ].

So returning to the code, in the reader object you've an instance of net.sf.json.JSONObject to work with, take a look at its API.

To show a little example I've a server at http://localhost/index.json which returns the follow json { "a":"a", "b": { "b1":"b1", "b2":"b2" }, "c":"c" } to work with I use the follow code:

import groovyx.net.http.HTTPBuilder

def http = new HTTPBuilder('http://localhost')
http.get(   path : '/index.json',
            contentType : 'application/json'
        ) { resp, reader ->

        // cast the object it's not necessary... I cast it 
        // to have the method suggestions by IDE
        net.sf.json.JSONObject read = reader
        println read.get("a") // prints "a"
        println read.get("b").get("b1") // prints "b1"
        //...

        // you can also use this approach 
        println read.a // prints "a"
        println read.b.b1 // prints "b1"
        println read.b // prints [b1:b1, b2:b2]

}

UPDATE

I read again your questions, an seems for your description that you're trying to read the issues from YourTrack in a xml format. To do so the approach it's really similar to the json in this case the reader object is an instance of GPathResult take a look at the follow sample supposing that your response look like the one that you put in your question:

http = new HTTPBuilder('http://www.MyYouTrackServer.com')
http.get(   path : '/MyIssue-25',
            contentType : 'application/xml'
        ) { resp, reader ->

        //  since your response is an xml now in reader you've GPathResult

        // and now some samples on how to work with the response:

        // get the text of each <field>
        def fields = reader.issue.field*.text();

        fields.each {
            print "$it " // prints 0 susjs 1 at jsjsjsj.mps.E.java at line 12 1277392628191 1277399118476 root root Submitted No subsystem Next build All Users numberInProject
        }

        // another sample... get the name attribute value for the <field> elements
        def namesAttr = reader.issue.field*.@name
        namesAttr.each {
            print "$it " // prints numberInProject summary priority description created updated reporterName updaterName state subsystem fixedInBuild permittedGroup
        }

        // find the <field> value for element which has attribute name="state"
        def field = reader.issue.'*'.findAll {
            it.@name == 'state'
        }

        println field.text() // prints submitted

}

Also in this YourTrack operation seems that there are two query parameters (project and max) to use it you can add the query parameter to the get() method, i.e: query : [ max : '15' ].

Hope this helps,

albciff
  • 18,112
  • 4
  • 64
  • 89
2

Here's how you can convert the XML response into a JSON object. Note: I added an additional issue to the XML response to demonstrate the output better.

import groovy.util.XmlParser
import groovy.json.JsonBuilder

def text = '''
<issues>
 <issue>
  <comment created="1277899067543" text="is it something wrong?" author="root"/>
  <field name="numberInProject"><value>0</value></field>
  <field name="summary"><value>susjs</value></field>
  <field name="priority"><value>1</value></field>
  <field name="description"><value>at jsjsjsj.mps.E.java at line 12</value></field>
  <field name="created"><value>1277392628191</value></field>
  <field name="updated"><value>1277399118476</value></field>
  <field name="reporterName"><value>root</value></field>
  <field name="updaterName"><value>root</value></field>
  <field name="state"><value>Submitted</value></field>
  <field name="subsystem"><value>No subsystem</value></field>
  <field name="fixedInBuild"><value>Next build</value></field>
  <field name="permittedGroup"><value>All Users</value></field>
 </issue>

 <issue>
  <comment created="1277899067543" text="does this work?" author="root"/>
  <field name="numberInProject"><value>0</value></field>
  <field name="summary"><value>susjs</value></field>
  <field name="priority"><value>1</value></field>
  <field name="description"><value>at jsjsjsj.mps.E.java at line 12</value></field>
  <field name="created"><value>1277392628191</value></field>
  <field name="updated"><value>1277399118476</value></field>
  <field name="reporterName"><value>root</value></field>
  <field name="updaterName"><value>root</value></field>
  <field name="state"><value>Submitted</value></field>
  <field name="subsystem"><value>No subsystem</value></field>
  <field name="fixedInBuild"><value>Next build</value></field>
  <field name="permittedGroup"><value>All Users</value></field>
 </issue>
</issues>'''

def xml = new XmlParser().parseText(text)
def json = new JsonBuilder()

json xml.issue.inject([]) {list, issue -> 
    def map = [:]

    map.comment = [
        created: issue.comment["@created"][0],
        text: issue.comment["@text"][0],
        author: issue.comment["@author"][0],
    ]


    issue.field.each {field ->
        map[field['@name']] = field.value[0].children()[0]
    }

    list << map

    return list
}

json.toString()

The pretty formatted output (thanks to TextMate) of json.toString() is this:

[
    {
        "comment": {
            "author": "root",
            "created": "1277899067543",
            "text": "is it something wrong?"
        },
        "created": "1277392628191",
        "description": "at jsjsjsj.mps.E.java at line 12",
        "fixedInBuild": "Next build",
        "numberInProject": "0",
        "permittedGroup": "All Users",
        "priority": "1",
        "reporterName": "root",
        "state": "Submitted",
        "subsystem": "No subsystem",
        "summary": "susjs",
        "updated": "1277399118476",
        "updaterName": "root"
    },
    {
        "comment": {
            "author": "root",
            "created": "1277899067543",
            "text": "does this work?"
        },
        "created": "1277392628191",
        "description": "at jsjsjsj.mps.E.java at line 12",
        "fixedInBuild": "Next build",
        "numberInProject": "0",
        "permittedGroup": "All Users",
        "priority": "1",
        "reporterName": "root",
        "state": "Submitted",
        "subsystem": "No subsystem",
        "summary": "susjs",
        "updated": "1277399118476",
        "updaterName": "root"
    }
]

I transformed the XML into what I think is a more reasonable representation of the data.

Emmanuel Rosa
  • 9,697
  • 2
  • 14
  • 20