How do I import a Groovy class into a Jenkinfile? - jenkins

How do I import a Groovy class within a Jenkinsfile? I've tried several approaches but none have worked.
This is the class I want to import:
Thing.groovy
class Thing {
void doStuff() { ... }
}
These are things that don't work:
Jenkinsfile-1
node {
load "./Thing.groovy"
def thing = new Thing()
}
Jenkinsfile-2
import Thing
node {
def thing = new Thing()
}
Jenkinsfile-3
node {
evaluate(new File("./Thing.groovy"))
def thing = new Thing()
}

You can return a new instance of the class via the load command and use the object to call "doStuff"
So, you would have this in "Thing.groovy"
class Thing {
def doStuff() { return "HI" }
}
return new Thing();
And you would have this in your dsl script:
node {
def thing = load 'Thing.groovy'
echo thing.doStuff()
}
Which should print "HI" to the console output.
Would this satisfy your requirements?

Related

Get config of other environment in Grails 2.*

I'm running Grails 2.1.1, and i'm looking for a way to get the value of variable set in production while i'm running on test environment.
The config file :
development {
config.url = "http://local"
}
test {
config.url = "http://test.lan"
}
production {
config.url = "http://prod.lan"
}
The only way i know to get config variables is grailsApplication.config.url
The standard config setup only looks at the current environment. Holders has the same current config as grailsApplication. You have to slurp the config again. Try using ConfigurationHelper. A spock test is below. (Note the sometimes doubled config.config is because the first config is the property (or short name for getConfig() method) and your key contains the second config.)
import grails.test.mixin.TestMixin
import grails.test.mixin.support.GrailsUnitTestMixin
import spock.lang.Specification
import org.codehaus.groovy.grails.commons.cfg.ConfigurationHelper
#TestMixin(GrailsUnitTestMixin)
class ConfigSpec extends Specification {
void "test prod config"() {
def configSlurper = ConfigurationHelper.getConfigSlurper('production',null)
def configObject = configSlurper.parse(grailsApplication.classLoader.loadClass(grailsApplication.CONFIG_CLASS))
expect:
configObject.config.url == "http://prod.lan"
}
void "test dev config"() {
def configSlurper = ConfigurationHelper.getConfigSlurper('development',null)
def configObject = configSlurper.parse(grailsApplication.classLoader.loadClass(grailsApplication.CONFIG_CLASS))
expect:
configObject.config.url == "http://local"
}
void "test grailsApplication config"() {
expect:
grailsApplication.config.config.url == "http://test.lan"
}
void "test Holders config"() {
expect:
grails.util.Holders.config.config.url == "http://test.lan"
}
}
Check out Holders: https://gist.github.com/mathifonseca/ab443f1502bfd9461943
import grails.util.Holders
class FooService {
def foo() {
def devUrl = Holders.config.url
assert devUrl == "http://local"
}
}

Gpars withPool method called from Pipeline

I have my GParsPool.withPool implemented in 'PreVerifymanager.groovy' as below.
import groovyx.gpars.GParsPool
public class PreVerifyManager {
static final THREADS = 3;
public void callMe() {
PreVerifyManager pf = new PreVerifyManager()
def apps = ["App1","App2","App3"]
GParsPool.withPool(PreVerifyManager.THREADS) {
apps.eachParallel {
pf.CreateFile(it)
}
}
}
public void CreateFile(String path){
path = "D:\\"+path+".txt";
println(path)
File file = new File(path)
file.write("Some text")
}
}
This works fine in my IDE with main method of PreVerifyManager. But when I remove the main method and call the method callMe on the object of PreVerifyManager created in Pipeline script, its not working.
Pipeline script as below:
node {
def PreVerifyManagerObj
stage 'TibcoConfig'
echo 'Reading Tibco configuration!'
println "****************INSIDE PIPELINE****************"
def parent = getClass().getClassLoader()
def loader = new GroovyClassLoader(parent)
PreVerifyManagerObj = loader.parseClass(new File("D://Tibco_Automation//src//com//meet//PreVerifyManager.groovy")).newInstance()
PreVerifyManagerObj.callMe()
}
Its basically, I'm integrating the GParsPool.withPool implementation with Pipeline scripting. Any input is appreciated.
The issue got resolved. You have to load all objects referred in your class into Pipeline script box, before you call your actual method.

How to wrap all Grails service methods with a Groovy closure?

Grails 2.4.x here.
I have a requirement that all the methods of all my Grails services, generated by grails create-service <xyz>, be "wrapped"/intercepted with the following logic:
try {
executeTheMethod()
} catch(MyAppException maExc) {
log.error(ExceptionUtils.getStackTrace(maExc))
myAppExceptionHandler.handleOrRethrow(maExc)
}
Where:
log.error(...) is the SLF4J-provided logger you get when you annotate your class with the #Slf4j annotation; and
ExceptionUtils is the one from org.apache.commons:commons-lang3:3.4; and
myAppExceptionHandler is of type com.example.myapp.MyAppExceptionHandler; and
This behavior exists (or has the option to exist in the event that it needs to be explicitly called somehow) for each method defined in a Grails service
So obviously this wrapper code needs to include import statements for those classes as well.
So for example if I have a WidgetService that looks like this:
class WidgetService {
WidgetDataService widgetDataService = new WidgetDataService()
Widget getWidgetById(Long widgetId) {
List<Widget> widgets = widgetDataService.getAllWidgets()
widgets.each {
if(it.id.equals(widgetId)) {
return it
}
}
return null
}
}
Then after this Groovy/Grails/closure magic occurs I need the code to behave as if I had written it like:
import groovy.util.logging.Slf4j
import org.apache.commons.lang3.exception.ExceptionUtils
import com.example.myapp.MyAppExceptionHandler
#Slf4j
class WidgetService {
WidgetDataService widgetDataService = new WidgetDataService()
MyAppExceptionHandler myAppExceptionHandler = new MyAppExceptionHandler()
Widget getWidgetById(Long widgetId) {
try {
List<Widget> widgets = widgetDataService.getAllWidgets()
widgets.each {
if(it.id.equals(widgetId)) {
return it
}
}
return null
} catch(MyAppException maExc) {
log.error(ExceptionUtils.getStackTrace(maExc))
myAppExceptionHandler.handleOrRethrow(maExc)
}
}
}
Any ideas as to how I might be able to achieve this? I'm worried that a pure Groovy closure might interfere somehow with whatever Grails is doing to its services under the hood at runtime (since they are all classes that don't explicitly extend a parent class).
Here is what I was trying to pin point in my comment:
package com.example
import groovy.util.logging.Log4j
#Log4j
trait SomeTrait {
def withErrorHandler(Closure clos) {
try {
clos()
} catch(Exception e) {
log.error e.message
throw new ApplicationSpecificException(
"Application Specific Message: ${e.message}"
)
}
}
}
Service class:
package com.example
class SampleService implements SomeTrait {
def throwingException() {
withErrorHandler {
throw new Exception("I am an exception")
}
}
def notThrowingException() {
withErrorHandler {
println "foo bar"
}
}
}
Test:
package com.example
import grails.test.mixin.TestFor
import spock.lang.Specification
#TestFor(SampleService)
class SampleServiceSpec extends Specification {
void "test something"() {
when:
service.throwingException()
then:
ApplicationSpecificException e = thrown(ApplicationSpecificException)
e.message == "Application Specific Message: I am an exception"
}
void "test something again"() {
when:
service.notThrowingException()
then:
notThrown(Exception)
}
}
Here is the sample app.
Grails 3.0.9 but it should not matter. this is applicable for Grails 2.4.*
You can intercept the calls to your Service class methods either using MetaInjection or Spring AOP. So you don't have to write closure in each Service class. You can look into this blog that explains both the approaches with examples.

How to get the spring bean instance of a service, added via dependency injection in webflow

I would like to mock a service method in an integration test for one test, however I don't know how to get a reference to the service as it's added to the controller via dependency injection. To further complicate things the service is in a webflow, but I know it's not stored in the flow as the service is not serialized.
Ideal mocking scenario:
Get reference to the service
Mock the method via the metaClass
Main test
Set the metaClass to null so it's replaced with the original
Methods like mockFor so far don't seem to effect the service.
Example of the setup:
Controller:
package is.webflow.bad
import is.webflow.bad.service.FakeService
class FakeController
{
def index = {
redirect(action: 'fake')
}
def fakeFlow = {
start {
action {
flow.result = fakeService.fakeCall()
test()
}
on('test').to('study')
}
study {
on('done').to('done')
}
done {
System.out.println('done')
}
}
}
Service:
package is.webflow.bad.service
class FakeService
{
def fakeCall()
{
return 'failure'
}
}
Test:
package is.webflow.bad
import static org.junit.Assert.*
import grails.test.WebFlowTestCase
import is.webflow.bad.service.FakeService
import org.junit.*
class FakeControllerFlowIntegrationTests extends WebFlowTestCase
{
def controller = new FakeController()
def getFlow() { controller.fakeFlow }
String getFlowId() { "fake" }
#Before
void setUp() {
// Setup logic here
super.setUp()
}
#Test
void testBasic()
{
startFlow()
assertCurrentStateEquals 'study'
assertEquals 'failure', getFlowScope().result
}
#Test
void testServiceMetaClassChange()
{
// want to modify the metaClass here to return success
startFlow()
assertCurrentStateEquals 'study'
assertEquals 'success', getFlowScope().result
}
}
You can inject the service into your Integration test using "#AutoWired" or using application context you get reference. Am i missing something?
#Autowired
private YourService yourservice;
or
#Autowired
private ApplicationContext appContext;
YourService yourService = (YourService)appContext.getBean("yourService");
Here you go:
void "test something"() {
given: "Mocked service"
someController.someInjectedService = [someMethod: { args ->
// Mocked code
return "some data"
] as SomeService
when: "Controller code is tested"
// test condition
then: "mocked service method will be called"
// assert
}

Grails- Criteria builders - createCriteria

The Scenario is like this:
Every Process has multiple ProcessingSteps
The code that I have written is able to fetch all the processes without correspondence to ProcessingSteps.
I know that I am missing a where clause, I want to ask how do we do that in Grails.
I only want to fetch for each Process the corresponding ProcessingStepUpdate
I have two domain classes ProcessingStep and ProcessingStepUpdate
package a.b.c
public class ProcessingStep {
Process process
}
public class ProcessingStepUpdate{
static belongsTo = [processingStep: ProcessingStep]
ProcessingStep processingStep
}
Here is the script that I was writing
Process.list(max:1).each {
//List<ProcessingStep> test2= ProcessingStep.findAllByProcess(it)
//println it
def test3 = ProcessingStep.createCriteria().list() {
eq("process",it)
}
println it
it.list().each {
//not telling it where to get the list from
ProcessingStep.list().each { pstep ->
def test4 = ProcessingStepUpdate.createCriteria().list() {
eq("processingStep",pstep)
// Projections are aggregating, reporting, and
// filtering functions that can be applied after
// the query has finished.
// A common use for projections is to summarize data
// in a query
/* projections{
groupProperty("processingStep")
}*/
}
println pstep
//List<ProcessingStepUpdate> test = ProcessingStepUpdate.findAllByProcessingStep(it)
//List<ProcessingStepUpdate> test = ProcessingStepUpdate.findWhere()
//println "it"
}
}
}
I have been stuck on this problem in one day.. new to OOPS world!
I'll try to guesss that the task is only to iterate children of children. Then it is like this:
public class Process {
static hasMany = [processingSteps: ProcessingStep]
}
public class ProcessingStep {
static belongsTo = [process: Process]
static hasMany = [updates: ProcessingStepUpdate]
}
public class ProcessingStepUpdate {
static belongsTo = [processingStep: ProcessingStep]
}
Process.list().each{ process ->
process.processingSteps.each { step ->
step.updates.each {
println "Process: $process, Update: $it"
}
}
}
Or even
def updates = Process.list()*.processingSteps.flatten()*.updates.flatten()
println updates.join('\n')
Take a look a Groovy Collections, especially at "star-dot '*.' operator" section.

Resources