Initializing AssetManager in Groovy Console - groovy

My goal is to programmatically move assets. I have found that AssetManager has a moveAsset method. However, I am having issues initializing an AssetManager object in my groovy script. Below is the code I am working with. How do I initialize a non-null AssetManager object?
import javax.jcr.query.*
import com.day.cq.dam.api.*
def query = createSQL2Query("/content/dam/3d-renders/application-notes/wcc-migration") //CHANGE THIS
def result = query.execute()
def rows = result.rows
rows.each { row ->
Resource res = resourceResolver.getResource(null,row.path)
AssetManager am = res.adaptTo(AssetManager.class)
am.getAsset('/content/dam/3d-renders/application-notes/wcc-migration/Q60_ILL000347_iAPP.psd')
println res.path + ' ' + am
//am.moveAsset('/content/dam/3d-renders/application-notes/wcc-migration/2015/Q3X-Color-Mark-Sensing.psd','/content/dam/3d-renders/test-folder/Q3X-Color-Mark-Sensing.psd')
}
def createSQL2Query(startPage) {
def queryManager = session.workspace.queryManager
def statement = "select * from [nt:base] as p where (isdescendantnode (p, '$startPage')) and p.[jcr:primaryType] = 'dam:Asset'"
def query = queryManager.createQuery(statement, Query.JCR_SQL2)
query
}

Try getting your asset manager like this:
AssetManager am = resourceResolver.adaptTo(AssetManager.class)
ResourceResolver implements Adaptable, the interface where the adaptTo(Class) method is defined.

Related

groovy: iterate functions over loops

Consider two collections:
collect1 = ['file.txt', 'file2.txt', 'file3.txt']
collect2 = ['/tmp/','/home/', '/dev/']
with:
def collection = new File("/path/to/file.txt").readLines()
def collection2 = { new File("/tmp/").listFiles }
How to iterate functions like def collection and def collection2 through those values from collect1 and collect2
Desired result:
def collection = new File("file.txt").readLines()
def collection2 = { new File("/tmp/").listFiles }
def collection = new File("file2.txt").readLines()
def collection2 = { new File("/home/").listFiles }
def collection = new File("file3.txt").readLines()
def collection2 = { new File("/dev/").listFiles }
You can collect over the collection, which is a "map" (often called
that in other programming languages). It transforms each item of the
collection and "collects" the results eagerly for you.
def collect2 = ['/tmp/','/home/', '/dev/']
def files = collect2.collect{ (it as File).listFiles().toList() }
println files*.take(2)
// → [[/tmp/.X11-unix, /tmp/.ICE-unix], [/home/user], [/dev/cpu, /dev/vcsa63]]
If you want to join the results, there is also collectMany, which will
give you a single collection with all the results concatted.
def collect2 = ['/tmp/','/home/', '/dev/']
def files = collect2.collectMany{ (it as File).listFiles().toList() }
println files.take(5)
// → [/tmp/.X11-unix, /tmp/.ICE-unix, /tmp/.XIM-unix, /tmp/.font-unix, /tmp/.Test-unix]

Trying to mock two classes with Groovy Spock Mock: GroovyCastException

I try to mock two classes in a Jenkins Pipeline var-script, but however I order the definition of the Mock I receive a GroovyCastException, while the mock for the second class is initiated
org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'Mock for type 'ClassA'' with class 'com.pipeline.ClassA$$EnhancerByCGLIB$$9b005c28' to class 'com.pipeline.DBReader'
This is how my Spock-Test looks like:
import com.homeaway.devtools.jenkins.testing.JenkinsPipelineSpecification
import com.pipeline.ClassA
import com.pipeline.DBReader
import groovy.sql.Sql
import org.jenkinsci.plugins.workflow.steps.FlowInterruptedException
import hudson.model.Result
class execScriptSpec extends JenkinsPipelineSpecification {
def execPipelineScript = null
def mockStage = [timeout: [time: 'mocktime']]
def mockScript = [...]
def setup() {
execPipelineScript = loadPipelineScriptForTest("vars/execScript.groovy")
}
def "Test Pipeline-Script"() {
setup:
GroovyMock(ClassA, global: true)
new ClassA(*_) >> Mock(ClassA) {
loadScope(_) >> null
loadJsonFromURL(_) >> null
}
GroovyMock(DBReader, global: true)
new DBReader(*_) >> Mock(DBReader) {
loadDBDriver(_) >> null
}
when:
execPipelineScript(mockScript, mockStage)
then:
true
And that is the code under test:
import com.pipeline.DBReader
import com.pipeline.ClassA
def call(script, stage) {
def pipelineConfig = script.pipelineConfig
def stageStatus = pipelineConfig.general.stageStatus
def projectName = script.env.project
// DB connection parameters
def dbName = script.deliveryConfig.system.dbName
def dbSchema = script.deliveryConfig.system.dbSchema
def dbServer = script.deliveryConfig.system.dbServer
def dbUser = script.deliveryConfig.system.dbUser
// DB Driver to use
def dbDriver = script.deliveryConfig.system.dbDriver
def dbPassword = script.env.password
// Create new DB-Client
DBReader dbClient = new DBReader(dbName, dbSchema, dbServer, dbUser, dbPassword, dbDriver)
dbClient.loadDBDriver()
def contextParameter = script.params['Context']
ClassA mapGavToVersionRange = new ClassA(projectName, contextParameter, script)
classAInstance.loadDeliveryScope( dbClient )
def url = 'https://some.valid.url'
classAInstance.loadJsonFromURL(url)
...
So don't get me wrong: The actual mocking of one or the other class works (if I put only one of them in my test), but as soon as I put both of them, the second one will not work. And I currently have no idea, why this happens.
Would be great, if anybody has an idea :-)
Thanks a lot!

groovy - replace values in json when loading from jmx

I have a piece a code as below. This is loading data from JMX to monitoring tool. Unfortunately, there are some 'NaN' values, which are not read properly by monitoring tool, and this interrupts transfer. My intention is to replace 'on fly' values 'NaN' to 'null'.
Has anybody any idea how to do it?
BR
import javax.security.auth.Subject;
import javax.security.auth.login.LoginContext;
import java.security.PrivilegedAction;
def hostName = hostProps.get("system.hostname")
def jmxPort = "10002"
def query = "Hadoop:service=hiveserver2,name=hiveserver2"
def metricsURL = "http://${hostName}:${jmxPort}/jmx?qry=${query}"
def ad = true
public class FetchMetrics implements PrivilegedAction {
def url;
public FetchMetrics(String url) {
this.url = url;
}
public Object run() {
URL urlObject = new URL(url);
def con = (HttpURLConnection) urlObject.openConnection();
return con.getInputStream();
}
}
lc = new LoginContext("Client");
lc.login();
Subject subject = lc.getSubject();
PrivilegedAction action = new FetchMetrics(metricsURL);
def metrics = Subject.doAsPrivileged(subject, action, null);
def jsonSlurper = new JsonSlurper()
def deviceMetrics = jsonSlurper.parse(metrics)
// Hit out endpoint and get our metrics
//deviceMetrics = jsonSlurper.parse(new URL(metricsURL))
deviceMetrics.'beans'[0].each {
println it
}
return 0
simplest way to use LAX json slurper, however it will parse NaN as a string "NaN"...
import groovy.json.JsonSlurper
import groovy.json.JsonParserType
import groovy.json.JsonBuilder
def jsonSlurper = new JsonSlurper().setType( JsonParserType.LAX )
def json = jsonSlurper.parseText('{ "a":111, "b": NaN}')
println new JsonBuilder(json).toPrettyString()
prints
{
"a": 111,
"b": "NaN"
}

Groovy throws MissingPropertyException when calling getter method

I'm writing a small Groovy script for Hybris.
For reasons unknown when I attempt to call .getCronExpression() Groovy tries to get a property named getCron.
Script execution has failed [reason: groovy.lang.MissingPropertyException: No such property: getCron for class: de.hybris.platform.cronjob.model.TriggerModel]
The getter which I try to call exists on the class.
def methods = TriggerModel.declaredMethods.findAll { !it.synthetic }.name
println methods;
//[getDaysOfWeek, getWeekInterval, setDaysOfWeek, setWeekInterval, getRelative, getJob, setActivationTime, setMaxAcceptableDelay, getTimeTable, setActive, setJob, getCronJob, getActivationTime, setDateRange, getDateRange, getMaxAcceptableDelay, getCronExpression, setCronExpression, setCronJob, getActive, setRelative, setDay, setHour, setMinute, setSecond, getHour, getMinute, getSecond, getYear, getMonth, setYear, setMonth, getDay]
Code part:
def currentDate = new Date();
def query = new FlexibleSearchQuery("SELECT {pk} FROM {cronjob} WHERE {active} IS true");
def result = flexibleSearchService.search(query).getResult();
for (cj in result) {
def activeTriggers = cj.getTriggers().stream().filter{p -> p.getActive()}.collect();
if (activeTriggers){
def at = activeTriggers.get(0);
def activationTS = at.getActivationTime(); // works
if (activationTS.before(currentDate)){
println cj.code + " has invalid next activation date set: " + activationTS;
}
def x = at.getCronExpression(); // error
}
Update: the project uses hybris 5.7
Replacing the getter with the variable name fixed the issue.
Replace-
def x = at.getCronExpression(); // error
with
def xam = at.cronExpression; // working
Complete working groovy-
import de.hybris.platform.servicelayer.search.FlexibleSearchQuery;
def currentDate = new Date();
def query = new FlexibleSearchQuery("SELECT {pk} FROM {cronjob} WHERE {active}='1'");
def result = flexibleSearchService.search(query).getResult();
for (cj in result) {
def activeTriggers = cj.getTriggers().stream().filter{p -> p.getActive()}.collect();
if (activeTriggers){
def at = activeTriggers.get(0);
def activationTS = at.getActivationTime(); // works
if (activationTS.before(currentDate)){
println cj.code + " has invalid next activation date set: " + activationTS;
}
def xam = at.cronExpression; // working
}
}
Can you share your groovy part where you are loading activeTriggers?
I created a sample groovy to load Triggers and print CronExpression for 1st object and it worked like a charm.
import de.hybris.platform.servicelayer.search.FlexibleSearchQuery;
flexibleQuery = new FlexibleSearchQuery("select {pk} from {Trigger}");
flexibleSearchService = spring.getBean("flexibleSearchService")
activeTriggers = flexibleSearchService.search(flexibleQuery).getResult();
def at = activeTriggers.get(0);
def x = at.getCronExpression();
OUTPUT
0 0 0/4 * * ? *
AFTER PO EDITED THE QUESTION I still don't see getCronExpression error, I believe you were calling the function on a different object then TriggerModel. Though there were some syntax errors in your groovy, a working version of the copy is as below. (Tested on 1905 version)
import de.hybris.platform.servicelayer.search.FlexibleSearchQuery;
def currentDate = new Date();
def query = new FlexibleSearchQuery("SELECT {pk} FROM {cronjob} WHERE {active} = true");
def result = flexibleSearchService.search(query).getResult();
for (cj in result) {
def activeTriggers = cj.getTriggers().stream().filter{p -> p.getActive()}.collect();
if (activeTriggers){
def at = activeTriggers.get(0);
def activationTS = at.getActivationTime(); // works
if (activationTS!=null && activationTS.before(currentDate)){
println cj.code + " has invalid next activation date set: " + activationTS;
}
def x = at.getCronExpression(); // error
println x;
}
}

Save test case properties if any of the assertions fail

How to save the test case properties if any of the assertions fail within this groovy script step?
Below is example code:
// define properties required for the script to run.
def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context)
def dataFolder = groovyUtils.projectPath
def vTIDAPI = testRunner.testCase.getPropertyValue("vTIDAPI")
def vTIDDB = testRunner.testCase.getPropertyValue("vTIDDB")
def RefAPI = testRunner.testCase.getPropertyValue("RefAPI")
def RefDB = testRunner.testCase.getPropertyValue("RefDB")
def AmountAPI = testRunner.testCase.getPropertyValue("AmountAPI")
def AmountDB = testRunner.testCase.getPropertyValue("AmountDB")
def CurrencyAPI = testRunner.testCase.getPropertyValue("CurrencyAPI")
def CurrencyDB = testRunner.testCase.getPropertyValue("CurrencyDB")
assert vTIDAPI == vTIDDB
assert RefAPI == RefDB
assert AmountAPI == AmountDB
assert CurrencyAPI == CurrencyDB
Here is the Groovy Script which does compare the given set of properties and on any of the assertion failure, writes the properties to a given file.
You need to change the value of property file name to be stored for variable propFileName variable.
Add more properties to be asserted in the form of key:value pairs format if needed
//Provide / edit the file name to store properties
def propFileName = '/tmp/testCase.properties'
//Define the properties to be matched or asserted ; add more properties if needed
def props = [ 'vTIDAPI':'vTIDDB', 'RefAPI':'RefDB', 'AmountAPI': 'AmountDB', 'CurrencyAPI': 'CurrencyDB']
/**
* Do not edit beyond this point
*/
def writeTestCasePropertiesToFile = {
//Get the test case properties as Properties object
def properties = context.testCase.properties.keySet().inject([:]){map, key -> map[key] = context.testCase.getPropertyValue(key); map as Properties}
log.info properties
assert properties instanceof Properties
properties?.store(new File(propFileName).newWriter(), null)
}
def myAssert = { arg1, arg2 ->
context.testCase.getPropertyValue(arg1) == context.testCase.getPropertyValue(arg2) ? null : "${arg1} value does not match with ${arg2}"
}
def failureMessage = new StringBuffer()
props.collect{ null == myAssert(it.key, it.value) ?: failureMessage.append(myAssert(it.key, it.value)).append('\n')}
if(failureMessage.toString()) {
log.error "Assertion failures:\n ${failureMessage.toString()}"
writeTestCasePropertiesToFile()
throw new Error(failureMessage.toString())
} else {
log.info 'Assertions passed'
}
EDIT: Based on the OP comments
Replace def myAssert = ... with below code fragment.
def myAssert = { arg1, arg2 ->
def actual = context.testCase.getPropertyValue(arg1)
def expected = context.testCase.getPropertyValue(arg2)
actual == expected ? null : "${arg1} value does not match with ${arg2} - api ${actual} vs db ${expected}"
}

Resources