map built from string value extraction - cannot recover value - groovy

I'm currently trying to manipulate a map in groovy but I'm facing a problem that I can't work out.
I build a map in order to have an id as key and a name as value
I have to store it as a string, then recover it and rebuild the map.
My keys look like id:my:device, names look like
When I build my map, I end up having something like
mymap = [id:my:device: ...etc.] which does not cause any problem for recovery, mymap[id:my:device] gives my device name.
EDIT :
I build the map doing name_uid_map[measure.uid] =jSonResponse.value for every map element and, at the end of my testCase, I store it doing testRunner.testCase.setPropertyValue("name_uid_map", name_uid_map.toString()
After storage and recovery, as it is stored as a string, it becomes uneasy to decypher. I modify the string in order to have "id:my:device"='my device name', then I rebuild the map doing the following (otherwise it splits from the first ':')
mymap = map.split(",\\s*").collectEntries{
def keyAndVal = it.split("=")
[(keyAndVal[0]):keyAndVal[1]]
}
The problem is now my rebuilt map looks like
{"id:my:device"='my device name' ... }
If I do
mymap.each{
key, value ->
log.info key
log.info value
}
I obtain
key : "id:my:device"
value : my device name
which is correct. When I want to recover value from the key, I encounter my problem, ie:
mymap["id:my:device"] = null
If I try to get the type of the value I get :
my value = class org.codehaus.groovy.runtime.NullObject
I'm not easy at all with handling maps in groovy and I'm sure I've done something wrong, but I can't figure it out, could someone help me ?
Alex

Well,
Actually I found another way to fulfill my needs
In the testStep where I build my initial map I do the following:
import groovy.json.JsonBuilder
and I store my map in a custom property like this, to make sure it's a valid JSON
testRunner.testCase.setPropertyValue("name_uid_map", new JsonBuilder(name_uid_map).toString())
In the next testStep, I do the following (simple extraction of JSON):
def name_uid_map = context.expand( '${#TestCase#name_uid_map}' )
def jsonSlurper = new groovy.json.JsonSlurper()
map = jsonSlurper.parseText(name_uid_map)
and it works fine.

Related

How to pass Map between testCases using properties

I want to do the following in SOAPUI using Groovy:
In a TestCase1 select values (Lastname, firstname) from database, and create a Map with dynamic values: def Map = [Login :"$Login", Nom: "$Nom"]
I need my map to be transferred to another TestCase, for this
I'm trying to put my map into properties:
testRunner.testCase.setPropertyValue( "Map", Map)
But I have error:
groovy.lang.MissingMethodException: No signature of method:
com.eviware.soapui.impl.wsdl.WsdlTestCasePro.setPropertyValue() is
applicable for argument types: (java.lang.String,
java.util.LinkedHashMap) values: [OuvInfoPersoMap,
[Login:dupond0001, Nom:Dupond]] Possible solutions:
setPropertyValue(java.lang.String, java.lang.String),
getPropertyValue(java.lang.String) error at line: 123
I found some posts on internet that suggests to use metaClass groovy property
context.testCase.metaClass.map = Map
log.info context.testCase.map
But I don't think it enough in my case.
I would like to be able to pass a map to Testcase2 using:
createMap = testRunner.testCase.testSuite.project.testSuites.testCases["TestCase1"]
createMap.map
Hopefully you can help me solving this problem.
Thanks advance
As #SiKing correctly explain in the comments, setPropertyValue method expects and String for the property name and for the property value.
Note that as #Rao suggest in general testCase execution should be independent, however despiste this technically it's possible to do what you ask for.
So a possible solution for your case is in the first testCase to serialize the Map to String in order that it's possible to save using setPropertyValue(Strig propertyName, String value) method, and then in the second testCase deserialitze it, something like the follow code must work:
TestCase 1
Serialize the map using inspect() method and save it as a property:
def map = ['foo':'foo','bar':'bar', 'baz':'baz']
testRunner.testCase.setPropertyValue('map',map.inspect())
TestCase2
Deserialitze the String property using Eval.me(String exp)::
// get the first testCase
def testCase1 = testRunner.testCase.testSuite.testCases["TestCase1"]
// get the property
def mapAsStr = testCase1.getPropertyValue('map')
// deserialize the string as map
def map = Eval.me(mapAsStr)
assert map.foo == 'foo'
assert map.bar == 'bar'
assert map.baz == 'baz'

Get the values of maps in arrayList

I have an arrayList of maps that i generate in my controller and pass to GSP page!
i would like to get the values of the maps as a list to present in g:select in gsp!
as in each element (Map) in the arrayList! The select option value should be the map value and the map key as an optionKey
as i want to use this key in a script when the user choose an option!
sorry am a bit confused if the question is not quite clear!
ArrayList[Map1,Map2,Map3]
Map1[1,value1]
Map2[2,value2]
Map3[3,value3]
// the values are strings to show in select
//the respective key of the option value the user has chosen i want it as option key so i can pass it to script
If I understood correctly you have a list (ArrayList) of Maps and you want to represent each map as a select, right?
Your arraylist of maps could be something like this:
def words_en = ['One':'Apple', 'Two':'Pear', 'Three': 'Strawberry']
def words_it = ['One':'Mela', 'Two':'Pera', 'Three': 'Fragola']
def words_de = ['One':'Apfel', 'Two':'Birne', 'Three': 'Erdbeere']
def myList = [words_en, words_it, words_de]
you can generate the select elements as follows:
<g:each var="myMap" in="${myList}" status="i">
<g:select id="select_${i}" name="select_${i}" optionKey="key" from="${myMap}" optionValue="value" ></g:select> <br/>
</g:each>
EDIT:
With the edited version of your question I understood that you have several maps each containing only one key-value pair. Given that your keys are unique, the best approach is to merge all your maps into one and simply use that to populate the select:
def words_1 = ['One':'Apple']
def words_2 = ['Two':'Pera']
def words_3 = ['Three': 'Erdbeere']
def myList = [words_1, words_2, words_3]
def myMap = [:]
myList1.each{map->
myMap.putAll(map)
}
and in the view:
<g:select id="mySelect" name="mySelect" optionKey="key" from="${myMap}" optionValue="value" ></g:select>

Setting fields on a new HL7 Message wrapped in Terser

When attempting to use ca.uhn.hl7v2.util.Terser to set empty fields on a given specific subclass of ca.uhn.hl7v2.model.Message (in this case ca.uhn.hl7v2.model.v251.message.ORU_R01), I receive no error messages during the .each{} closure and afterwards the message object has no fields populated.
hl7Map is populated on class instantiation, with values like:
def hl7Map= [ "HL7MessageFields":['PID-3-1':"internal order map key",
'PID-3-4':"internal order map key",etc.]]
Code below:
def buildHL7Message(order){
def date = new Date()
def format = new SimpleDateFormat(hl7Map["dateFormat"]).format(date)
//Set date on the Message Header Object
hl7Map["MSH"]["-7"]= format
def message = (context.getModelClassFactory().getMessageClass(hl7Map["MessageInstantiationMap"]["messageType"],
hl7Map["MessageInstantiationMap"]["version"],
true) as Class).newInstance()
Terser terser = new Terser(message)
hl7Map["HL7MessageFields"].each{
terser.set(it.key, order[it.value])
}
println message
return message
}
The end of method results in no output and error logged about encoding, MSH-1 is a required field, pipe delminator but is empty. If the code above uses message.initQuickstart("ORU", "R01", "T"), only the default initQuickstart fields are populated.
If hl7Map["HL7MessageFields"] contains a 'it.key' that is not a valid Group/Segment field, an error is logged by terser that it failed to find the value, the above code with a properly formatted map does not cause an error.
Can anyone help explain why I am not receiving errors yet my message is empty, and help me to populate the message with the appropriate terser.set(params)?
Found solution that worked for me after a couple of hours of searching.
The message object's internal representation has a tree like structure where the MSH Segment is the parent, and the segments located after the MSH segment are child segments. Because of this structuring, MSH fields must be set as my original code does, but child segment fields must be set with "/." prepended to the map key devised (i.e. "PID-3-1" must become "/.PID-3-1" in the terser.set() line.
The hl7Map format was updated to better support this terser.set() syntactical requirement.
From the terser documentation, the / indicates search should start at the root of the message, and from an answer on a HAPI mail list link I've now lost, the . indicates search should include child elements of the MSH.
Full code below:
def buildHL7Message(order){
def date = new Date()
def format = new SimpleDateFormat(hl7Map["dateFormat"]).format(date)
//Set date on the Message Header Object
hl7Map["MSH"]["-7"]= format
//See http://stackoverflow.com/questions/576955/groovy-way-to-dynamically-invoke-a-static-method
//And
//http://stackoverflow.com/questions/7758398/groovy-way-to-dynamically-instantiate-a-class-from-string
def message = (context.getModelClassFactory().getMessageClass(hl7Map["MessageInstantiationMap"]["messageType"],
hl7Map["MessageInstantiationMap"]["version"],
true) as Class).newInstance()
Terser terser = new Terser(message)
hl7Map["MSH"].each{
terser.set("MSH"+it.key, it.value)
}
hl7Map["HL7MSHChildSegmentMap"].each{
terser.set(("/."+it.key) as String, order[it.value] as String)
}
println message
return message
}

Second map value is always null, even if it prints out 1

I have some code getting data and then selecting it in order. For this I use simple maps that I may later access with ease (I thought..).
I use the following code within a loop to insert maps to another map named "companies":
def x = [:]
x.put(it.category[i], it.amount[i])
companies.put(it.company, x)
And I can surely write the result out: [Microsoft:[Food:1], Apple:[Food:1]]
But then, when I am about to get the food value of each company it always is null. This is the code I use to get the values:
def val = companies.get(it.company).get(key.toString())
def val = companies[it.company][key] // doesn't make a difference
Val is always null. Can someone help and / or explain why I have this error. What am I doing wrong? I mean, I can clearly see the 1 when I print it out..
My guess is that it.category[i] and key are completely different types...
One thing you could try is:
x.put(it.category[i].toString(), it.amount[i])
and then
def val = companies[it.company][key.toString()] // doesn't make a difference
The solution was simple to make the category as a string:
x.put(it.category[i].toString(), it.amount[i])
And after that little fix it all works as expected.

Get key in groovy maps

def map = [name:"Gromit", likes:"cheese", id:1234]
I would like to access map in such a way that I can get the key
something like the output should be
map.keys returns array of string. basically i just want to get the keys
output:
name
likes
id
try map.keySet()
and if you want an array:
map.keySet() as String[]; // thx #tim_yates
Or, more groovy-ish:
map.each{
key, value -> print key;
}
Warning: In Jenkins, the groovy-ish example is subtly broken, as it depends on an iterator. Iterators aren't safe in Jenkins Pipeline code unless wrapped in a #NonCPS function.
def map = [name:"Gromit", likes:"cheese", id:1234]
println map*.key
In groovy * is use for iterate all

Resources