Optimize Groovy code - groovy

I am fairly new to the Groovy/Grails arena. I recently modified some code to add the following block.
result.processed.each{
def queueEntry = QueueEntry.findById(it.id)<<<START ADD>>>
Set dates = new HashSet<Long>()
def children = QueueEntry.findAllByParent(queueEntry)
for(QueueEntry qe : children){
def f = new GregorianCalendar()
f.setTimeInMillis(DateUtils.getClearedTime(qe.entryTimestamp))
def l = new GregorianCalendar()
l.setTimeInMillis(DateUtils.getClearedTime(qe.exitTimestamp))
while(f < l){
if(f.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY && f.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY){//only add weekdays
dates.add(f.time.time)
}
def xx = new GregorianCalendar()
xx.setTimeInMillis(f.time.next().time)
f = xx
}
dates.add(l.time.time)
} <<<STOP ADD>>>
Set outsideDays = it.numberOfDaysOutsideCVB
Set days = DateUtils.businessDaysBetweenDates(it.entryTimestamp, it.exitTimestamp)
days.removeAll(outsideDays)
days.removeAll(dates)
turnTimes << days.size()
}
The application is now crawling. I am obviously doing something wrong. When this is run for small data-sets it will complete slowly. On larger sets it doesn't finish. Prior to this change it was completing.

You can start with the lines of the below changes.
// Proposed
import static java.util.Calendar.*
// Query for all the children upfront instead of hitting
// database twice on each iteration.
// You can also avoid N + 1 situation if children is fetched eagerly
def allChildren = QueueEntry.where {
id in (result.processed*.id as List<Long>)
}.children.list()
def turnTimes = result.processed.collect { entry ->
allChildren.findAll { it.parent.id == entry.id }.collect { child ->
Set dates = []
new Date( child.entryTimeStamp ).upto( new Date( child.exitTimestamp ) ) {
if ( !( it[DAY_OF_WEEK] in [ SUNDAY, SATURDAY ] ) ) {
dates << it.time
}
}
Set outsideDays = child.numberOfDaysOutsideCVB
Set days =
DateUtils.businessDaysBetweenDates(
child.entryTimestamp,
child.exitTimestamp
)
( days - outsideDays - dates )?.size() ?: 0
}
}
Assumptions:
QueueEntry hasMany children
entryTimestamp/exitTimestamp is java.sql.Timestamp
entryTimestamp/exitTimestamp are not null and entryTimestamp comes before exitTimestamp.
As Burt suggested this question best fits in codereview.stackexchange.com

Related

NIFI: Generating dates between two dates using ExecuteScript processor

I am currently trying to get list of all dates in a flowfile between the two dates specified using ExecuteScript. But I am somehow getting empty attribute.
Following is my Groovy code of ExecuteScript for the specified startdate and enddate variable specified:
flowFile = session.get();
if(!flowFile)
return;
DATE_FORMAT = 'dd-MM-yyyy';
startDate = Date.parse(DATE_FORMAT, flowFile.getAttribute("startdate"));
endDate = Date.parse(DATE_FORMAT, flowFile.getAttribute("enddate"));
allDates = "";
Calendar calendar = Calendar.getInstance();
Set allDates = new LinkedHashSet();
numbers = TimeUnit.MILLISECONDS.toDays(Math.abs(endDate - startDate))
for (int i = 1; i <= numbers; i++) {
calendar.setTime( startDate );
calendar.add( Calendar.DATE, i );
}
days.each {
day -> allDates = allDates + day + "\n";
}
flowFile = session.putAttribute(flowFile,"allDates", allDates );
session.transfer(flowFile,REL_SUCCESS)
On my outgoing queue I find the attribute allDates is empty String
What is going wrong with my code?
you have some problems in your code
for example the variable allDates declared twice i two different scopes:
global (without type or def)
allDates = "";
and local (with type)
Set allDates = new LinkedHashSet();
after that it's hard to predict which one is used
and actually code could be easier in groovy:
def DATE_FORMAT = 'dd-MM-yyyy';
def startDate = Date.parse(DATE_FORMAT, '01-11-1970');
def endDate = Date.parse(DATE_FORMAT, '09-11-1970');
def allDates = ""
for (def d = startDate; d<=endDate; d++){
allDates+=d.format(DATE_FORMAT)+"\n"
}
println allDates
note that this is runable code so you can use groovyconsole or any IDE to debug it before integrating into nifi
of cause you have to wrap it with flow file handling before using in nifi

How to use Groovy script in soapUi to loop multiple time

I am new to SoapUi. I am exploring on how multiple request in soapUi is done using groovy script.
below is the example that im trying to do, based on example that i found through "googling"
import com.eviware.soapui.SoapUI;
import com.eviware.soapui.model.testsuite.*;
import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCaseRunner
import java.util.Random
import com.eviware.soapui.model.testsuite.TestRunner.Status
// Define your testCase pointer
//def testcase = testRunner.testCase.testSuite.project.testSuites["TestSuite - User Management REST API"].getTestCaseByName ("Authenticate User")
def counterUser = testRunner.testCase.testSuite.getPropertyValue( "counter" )
int value = counterUser.toInteger()
String tester = ""
30.times {
value = value + 1
tester = "tester " + value.toString()
testRunner.testCase.testSuite.setPropertyValue( "userName", tester )
testRunner.runTestStepByName("POST - createUser - Create a User")
}
testRunner.testCase.testSuite.setPropertyValue( "counter", value.toString() )
I want to create a 30 users which start from Tester1...tester2.....tester30.
Is it possible to do this way? I keep getting an error such as NullPointerException at this line
int value = counterUser.toInteger()
I got what you say.
That is because, initially there is no value for counter which results to null and you are applying toInteger() over it.
Just change:
From:
int value = counterUser.toInteger()
To:
int value = counterUser?.toInteger() ?: 0

Loop test steps in multiple test cases using SOAPUI

I'm having some issue in automating web services.
Actually I have an excel sheet containing all the input and outputs needed.
I wrote a groovy script that retrieve inputs, save them in properties, execute query, retrieve outputs and compare them with excel outputs.
My problem is that all the process is execute as one test case.
I want to "pimp" my process so that every line of my Excel sheet is dealt as a test case.
Here's the groovy code :
import jxl.*
import jxl.write.*
Workbook workbook1 = Workbook.getWorkbook(new File("C:\\Users\\****\\Desktop\\GroovyPSSheet.xls"))
Sheet sheet1 = workbook1.getSheet(0)
for (int i=6; i<sheet1.getRows(); i++)
{
sleep 1000
if (sheet1.getCell(0,i).getContents()=="")
{
i++
}
Cell clairance = sheet1.getCell(3,i)
Cell etatpatho = sheet1.getCell(2,i)
Cell idlReq = sheet1.getCell(1,i)
Cell idprod = sheet1.getCell(0,i)
Cell typeprod = sheet1.getCell(4,i)
testRunner.testCase.setPropertyValue( "clairance", clairance.getContents() )
testRunner.testCase.setPropertyValue( "etatpatho", etatpatho.getContents() )
testRunner.testCase.setPropertyValue( "idlReq", idlReq.getContents() )
testRunner.testCase.setPropertyValue( "idprod", idprod.getContents() )
testRunner.testCase.setPropertyValue( "typeprod", typeprod.getContents() )
sleep 500
def ExecuteQuery = testRunner.testCase.testSteps['ExecuteQuery']
ExecuteQuery.run( testRunner, context )
sleep 1000
groovyUtils = new com.eviware.soapui.support.GroovyUtils(context )
holder = groovyUtils.getXmlHolder ("ExecuteQuery#Response")
id_type_alerte = holder.getNodeValue("//id_type_alerte")
testRunner.testCase.setPropertyValue( "id_type_alerte", sheet1.getCell(5,i).getContents() )
idproduit = holder.getNodeValue("//idproduit")
testRunner.testCase.setPropertyValue( "idproduit", sheet1.getCell(6,i).getContents() )
typeproduit = holder.getNodeValue("//typeproduit")
testRunner.testCase.setPropertyValue( "typeproduit", sheet1.getCell(7,i).getContents() )
id_ter_per = holder.getNodeValue("//id_ter_per")
testRunner.testCase.setPropertyValue( "id_ter_per", sheet1.getCell(8,i).getContents() )
lib_ter_per = holder.getNodeValue("//lib_ter_per")
testRunner.testCase.setPropertyValue( "lib_ter_per", sheet1.getCell(9,i).getContents() )
id_ter_com = holder.getNodeValue("//id_ter_com")
testRunner.testCase.setPropertyValue( "id_ter_com",sheet1.getCell(10,i).getContents() )
id_typ_ter = holder.getNodeValue("//id_typ_ter")
testRunner.testCase.setPropertyValue( "id_typ_ter", sheet1.getCell(11,i).getContents() )
lib_ter = holder.getNodeValue("//lib_ter")
testRunner.testCase.setPropertyValue( "lib_ter", sheet1.getCell(12,i).getContents() )
id_nature_ci = holder.getNodeValue("//id_nature_ci")
testRunner.testCase.setPropertyValue( "id_nature_ci", sheet1.getCell(13,i).getContents() )
id_ter = holder.getNodeValue("//id_ter")
testRunner.testCase.setPropertyValue( "id_ter", sheet1.getCell(14,i).getContents() )
id_sequence_ter = holder.getNodeValue("//id_sequence_ter")
testRunner.testCase.setPropertyValue( "id_sequence_ter", sheet1.getCell(15,i).getContents() )
id_fic_ci = holder.getNodeValue("//id_fic_ci")
testRunner.testCase.setPropertyValue( "id_fic_ci", sheet1.getCell(16,i).getContents() )
sleep 1000
}
workbook1.close()
Thanks !
Seems that you want to get a next testCase from the current testSuite for each row in the your datasheet instead of performing the operation in the current testCase each time. I'm not sure that this is your goal, but you can collect all the testCases from the current testSuite and select the next one for each row, something like this can do the trick:
// get all testCases from the current testSuite as List
def allTestCases = testRunner.testCase.testSuite.testCases.collect{ name, testCase ->
return testCase
}
// row iteration
for (int i=6; i<sheet1.getRows(); i++)
{
// get a testCase
def testCase = allTestCases.take(1);
// drop the element from the list to change next iteration
allTestCases = allTestCases.drop(1);
...
...
// in the rest of your code use the testCase variable from the list
// instead of using testRunner.testCase which always take the current one
testCase.setPropertyValue("clairance", clairance.getContents())
testCase.setPropertyValue("etatpatho", etatpatho.getContents())
...
def ExecuteQuery = testCase.testSteps['ExecuteQuery']
ExecuteQuery.run( testRunner, context )
...
}
Hope it helps,

Need to Update XML Tag value at run time

In the code below I'm trying to update one of the tag value. My problem is that which tag value I need to update, I know only at run time.
Below code does not work to update the tag value even though I'm able to get the tag value by this code.
def temp1="""
<TradeRecord>
<TradeId>1000</TradeId>
<SecurityId>10382456</SecurityId>
<TradeType>SELLL</TradeType>
<TradeDate>2014-03-21</TradeDate>
<Broker>100</Broker>
<Exchange>1</Exchange>
<Status>INIT</Status>
<Quantity>12765</Quantity>
<ApprovedBy />
</TradeRecord>
"""
def records = new XmlParser().parseText(temp1)
childRecords = records.children()
j = childRecords.size()
def tagname = 'Quantity'
for (int i=0; i<j; i++){
if (childRecords[i].name() == tagname) {
log.info childRecords[i].text()
childRecords[i].text() = "9999"
log.info childRecords[i].text()
}
}
You can not assign to the text()-getter, but there is the value, which has a setter; e.g.:
childRecords[i].value = "9999"
But this also can be done more groovy:
def temp1="""
<TradeRecord>
<TradeId>1000</TradeId>
<SecurityId>10382456</SecurityId>
<TradeType>SELLL</TradeType>
<TradeDate>2014-03-21</TradeDate>
<Broker>100</Broker>
<Exchange>1</Exchange>
<Status>INIT</Status>
<Quantity>12765</Quantity>
<ApprovedBy />
</TradeRecord>
"""
def records = new XmlParser().parseText(temp1)
final tagname = 'Quantity'
records."$tagname".each{
it.value = '9999'
}
println groovy.xml.XmlUtil.serialize(records)

How to print out the values of variables in a valuebox in soot?

This is the related code fragment where I can't print out the values from valuebox. May I know what's the problem?
public GuaranteedDefsAnalysis(UnitGraph graph)
{
super(graph);
DominatorsFinder df = new MHGDominatorsFinder(graph);
unitToGenerateSet = new HashMap<Unit, FlowSet>(graph.size() * 2 + 1, 0.7f);
// pre-compute generate sets
for(Iterator unitIt = graph.iterator(); unitIt.hasNext();){
Unit s = (Unit) unitIt.next();
FlowSet genSet = emptySet.clone();
for(Iterator domsIt = df.getDominators(s).iterator(); domsIt.hasNext();){
Unit dom = (Unit) domsIt.next();
for(Iterator boxIt = dom.getDefBoxes().iterator(); boxIt.hasNext();){
ValueBox box = (ValueBox) boxIt.next();
box.getValue().toString(); // simply using toString does not work
if(box.getValue() instanceof Local)
genSet.add(box.getValue(), genSet);
}
}
unitToGenerateSet.put(s, genSet);
}
doAnalysis();
}
Can you maybe rephrase your question? What do you mean by "does not work"? Did you forget to add the println statement maybe?

Resources