0
votes

I'm trying to set up a Load Test in soapUI for my API with a series of AMF Requests, but I'm having trouble figuring out how to make a property transfer with an XML response like this:

<flex.messaging.io.amf.ASObject serialization="custom">
  <unserializable-parents/>
  <map>
    <default>
      <loadFactor>0.75</loadFactor>
      <threshold>48</threshold>
    </default>
    <int>64</int>
    <int>28</int>
    <string>key</string>
    <boolean>value</boolean>
    <string>key</string>
    <boolean>value</boolean>
    <string>key</string>
    <string>value</string>
    <string>key</string>
    <boolean>value</boolean>
    <string>key</string>
    <null/>
    <string>key</string>
    <null/>
    <string>key</string>
    <null/>
    <string>key</string>
    <null/>
    <string>key</string>
    <null/>
    <string>key</string>
    <null/>
    <string>key</string>
    <boolean>value</boolean>
    <string>key</string>
    <boolean>value</boolean>
    <string>key</string>
    <null/>
    <string>key</string>
    <string>value</string>
    <string>key</string>
    <string>value</string>
    <string>key</string>
    <object-array/>
    <string>key</string>
    <flex.messaging.io.amf.ASObject serialization="custom">
      <unserializable-parents/>
      <map>
        <default>
          <loadFactor>0.75</loadFactor>
          <threshold>12</threshold>
        </default>
        <int>16</int>
        <int>3</int>
        <string>key</string>
        <boolean>value</boolean>
        <string>key</string>
        <boolean>value</boolean>
        <string>key</string>
        <boolean>value</boolean>
      </map>
      <flex.messaging.io.amf.ASObject>
        <default>
          <inHashCode>false</inHashCode>
          <inToString>false</inToString>
          <namedType>package/class</namedType>
        </default>
      </flex.messaging.io.amf.ASObject>
    </flex.messaging.io.amf.ASObject>
    <string>key</string>
    <string>value</string>
    <string>key</string>
    <boolean>value</boolean>
    <string>key</string>
    <string>value</string>
    <string>key</string>
    <flex.messaging.io.amf.ASObject serialization="custom">
      <unserializable-parents/>
      <map>
        <default>
          <loadFactor>0.75</loadFactor>
          <threshold>12</threshold>
        </default>
        <int>16</int>
        <int>5</int>
        <string>key</string>
        <boolean>value</boolean>
        <string>key</string>
        <boolean>value</boolean>
        <string>key</string>
        <boolean>value</boolean>
        <string>key</string>
        <boolean>value</boolean>
        <string>key</string>
        <boolean>value</boolean>
      </map>
      <flex.messaging.io.amf.ASObject>
        <default>
          <inHashCode>false</inHashCode>
          <inToString>false</inToString>
          <namedType>package/class</namedType>
        </default>
      </flex.messaging.io.amf.ASObject>
    </flex.messaging.io.amf.ASObject>
    <string>guid</string>
    <string>818f40db-c217-46ed-a6a2-7c830d894a95</string>
    <string>key</string>
    <string>value</string>
    <string>key</string>
    <null/>
    <string>key</string>
    <string>value</string>
    <string>key</string>
    <string>value</string>
    <string>key</string>
    <null/>
    <string>key</string>
    <null/>
  </map>
  <flex.messaging.io.amf.ASObject>
    <default>
      <inHashCode>false</inHashCode>
      <inToString>false</inToString>
      <namedType>package/class</namedType>
    </default>
  </flex.messaging.io.amf.ASObject>
</flex.messaging.io.amf.ASObject>

As I'm not using soapUI Pro, I don't have access to the xpath wizard. Is there a way to access this node with a Property transfer or a Groovy Script?

1

1 Answers

0
votes

You can access those two like so using XmlSlurper:

def src = '''<flex.messaging.io.amf.ASObject serialization="custom">
            |  <unserializable-parents/>
            |  <map>
            |    <default>
            |      <loadFactor>1.00</loadFactor>
            |      <threshold>50</threshold>
            |    </default>
            |    <string>Not what I need</string>
            |    <string>Not what I need</string>
            |    <string>Not what I need</string>
            |    <string>Not what I need</string>
            |    <string>Not what I need</string>
            |    <object-array/>
            |    <string>Not what I need</string>
            |    <string>This is the KEY I'm looking for</string>
            |    <string>This is the VALUE I need to pass to the next test step</string>
            |    <string>Not what I need</string>
            |    <string>Not what I need</string>
            |    <string>Not what I need</string>
            |    <null/>
            |    <string>Not what I need</string>
            |    <string>Not what I need</string>
            |    <string>Not what I need</string>
            |    <string>Not what I need</string>
            |    <string>Not what I need</string>
            |    <null/>
            |    <string>Not what I need</string>
            |    <null/>
            |  </map>
            |</flex.messaging.io.amf.ASObject>'''.stripMargin()

def aso = new XmlSlurper().parseText( src )

def (key,value) = aso.map.string[6..7]*.text()

println "  key = $key"
println "value = $value"

This feels a bit 'hard-coded', but I cannot see how those values can be located programatically :-(


Edit

Given the new XML you posted, this seems to work in this instance:

println aso.map.children()[ 3..-1 ]    // Strip out the initial default and ints
       .collate( 2 )                   // Group the key/value pairs
       .findAll { 
         it[ 0 ].text() == 'guid'      // find all that have 'guid' as element 0
       }
       .collectEntries { it*.text() }  // convert this into a map

And prints:

[guid:818f40db-c217-46ed-a6a2-7c830d894a95]

However, a more thorough depthFirst algorithm might be a more solid way of scanning all possible inputs (I don't know ASObject serialization, so I don't know if this just works for this instance)


Edit 2

As you are stuck with a version of Groovy with no collate method (1.8.6), you can do something like this using a traditional for loop:

def aso = new XmlSlurper().parseText( src ).map.children()
String guid = null
for( i = 3 ; i < aso.size() ; i += 2 ) {
  if( aso[ i ] == 'guid' ) {
    guid = aso[ i + 1 ]
    break
  }
}
println guid