Spring Boot Resources in Docker container - docker

I'm using Docker for a Spring Boot application and so far everything is working.
I have a resource file in src/main/resources/db/data/dummydata.csv
In a bootstrap class this file is used to import the dummy data into the database.
private fun getDummyData(): List {
var fileReader: BufferedReader? = null
val dummyData = ArrayList<DummyDataEntity>()
try {
var line: String?
val res = ResourceUtils.getFile("classpath:db/data/dummydata.csv")
fileReader = BufferedReader(FileReader(res.path))
// Read CSV header
fileReader.readLine()
... Processing the data ...
} catch (e: Exception) {
e.printStackTrace()
} finally {
try {
fileReader!!.close()
} catch (e: Exception) {
e.printStackTrace()
}
return dummyData
}
}
When I run the application in IntelliJ, everything works just fine, but when I'm running it in Docker it cannot be found.
The Jar and the Docker image are created using Kotlin DSL Gradle.
import com.palantir.gradle.docker.DockerExtension
import io.spring.gradle.dependencymanagement.dsl.DependencyManagementExtension
import org.gradle.tooling.model.GradleTask
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.springframework.boot.gradle.tasks.bundling.BootJar
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath(Libs.springBootGradlePlugin)
classpath(Libs.kotlinGradlePlugin)
classpath(Libs.kotlinAllOpen)
classpath(Libs.gradleDocker)
}
}
plugins {
// Apply the java-library plugin to add support for Java Library
`java-library`
}
apply {
plugin("kotlin")
plugin("kotlin-spring")
plugin("org.springframework.boot")
plugin("io.spring.dependency-management")
plugin("com.palantir.docker")
}
repositories {
mavenCentral()
}
dependencies {
compile(Libs.kotlinReflect)
// Spring Boot
compile(Libs.springBootStarterDataJpa)
}
configure<DependencyManagementExtension> {
imports {
mavenBom(Libs.vaadinBom)
}
}
val bootJar: BootJar by tasks
bootJar.baseName = "reporting-app-site"
bootJar.version = "0.0.1"
configure<DockerExtension> {
name = "brabantia/${bootJar.baseName}"
files(bootJar.archivePath)
buildArgs(mapOf("JAR_FILE" to bootJar.archiveName))
dependsOn(tasks["build"])
}
val compileKotlin: KotlinCompile by tasks
compileKotlin.kotlinOptions.jvmTarget = "1.8"
The Jar does contain BOOT-INF/classes/db/data/dummyData.csv but when the application is run the error that is thrown is
java.io.FileNotFoundException: class path resource [db/data/dummydata.csv] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/app.jar!/BOOT-INF/classes!/db/data/dummydata.csv
What am I missing here?

The below worked for me.., you need to use an InputStream and not a File.
...
#Autowired
private ResourceLoader resourceLoader;
...
Resource resource= resourceLoader.getResource("classpath:/account_info.html");
InputStream inputStream= resource.getInputStream();
Assert.notNull(inputStream,"Could not load template resource!");
String email = null;
try {
byte[] bdata = FileCopyUtils.copyToByteArray(inputStream);
email = new String(bdata, StandardCharsets.UTF_8);
} catch (IOException e) {
logger.warn("IOException", e);
}finally {
if ( inputStream != null) {
IOUtils.closeQuietly(inputStream);
}
}

Related

Groovy code works, Then in Jenkins it doesn't. How can I make this work?

I am trying to augment the 'load' pipeline step function and I keep getting an error. I have found the code it executes based on the stack trace but I can't for the life of me figure out why it wouldn't just call the code as written.
I have written lots-and-lots of Java code so I know what it's trying to do. I just don't understand why it's trying to do it or how to convince it to stop! The groovy sample works perfectly! BTW: if there is an idiomatic way to do this in groovy/jenkins, I am all in.
Jenkins version: 2.176.1
Groovy plugin: 2.2
test.groovy
def someFunction(def params){
println("someFunction ${params}")
}
def someFunction2(def params){
println("someFunction2 ${params}")
}
def mainFunc(def stuff){
}
def somemainThingrunFunmain(){
}
def ___cps___21685(){
}
def ___cps___21688(){
}
this
main.groovy
def loaded = evaluate('test.groovy' as File)
def toAugment = loaded.class.declaredMethods*.name.findAll { !(it =~ '^(main|run)$|^[$]|^(___cps___)') }
def proxy = new Script(this.binding) {
#Override
Object run() {
monad.run()
}
}
toAugment.each {
proxy.metaClass."${it}" = { "logging ${it}".tap { println(it)} } >> loaded.&"${it}"
}
proxy.someFunction('hello world1')
proxy.someFunction2('hello world2')
outputs:
called
someFunction hello world1
called
someFunction2 hello world2
Now in Jenkins:
Jenkinsfile:
library 'common-libraries#chb0'
node('java') {
stage('SCM') {
checkout scm
}
def loaded = load('test.groovy')
stage('experiment') {
loaded.someFunction('hello world1')
loaded.someFunction2('hello world2')
}
}
adapted library (in common-library:vars/load.groovy):
def call(String path) {
def loaded = steps.load(path)
def proxy = new Script(this.getBinding()) { // error here
#Override
Object run() {
loaded.run()
}
}
// remove groovy and jenkins generated functions. Don't touch those
def toAugment = loaded.class.declaredMethods*.name.findAll { !(it =~ '^(main|run)$|^[$]|^(___cps___)') }
toAugment.each {
proxy.metaClass."${it}" = { "logging ${it}".tap { println(it) } } >> loaded.&"${it}"
}
}
exception:
groovy.lang.GroovyRuntimeException: Could not find matching constructor for: load$1(load, Script1, groovy.lang.Binding)
at groovy.lang.MetaClassImpl.invokeConstructor(MetaClassImpl.java:1732)
at groovy.lang.MetaClassImpl.invokeConstructor(MetaClassImpl.java:1532)
at org.codehaus.groovy.runtime.callsite.MetaClassConstructorSite.callConstructor(MetaClassConstructorSite.java:49)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:60)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:235)
at com.cloudbees.groovy.cps.sandbox.DefaultInvoker.constructorCall(DefaultInvoker.java:25)

Archive File is corrupt after Groovy FTP upload

I want to try an FTP upload from Jenkins to my FTP server with a groovy script.
After the upload, the archive file is corrupt and can not be opened.
I downloaded my archive from the workspace of Jenkins. There is all correct.
import org.apache.commons.net.ftp.FTPClient
import org.apache.commons.net.ftp.FTPFile
import org.apache.commons.net.ftp.FTPF
import java.io.InputStream
#Grab(group='commons-net', module='commons-net', version='3.6')
def upload(){
String ftpServer = "ftp.my-domain.com";
String folder = "/";
def ftpClient = new FTPClient()
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
try {
InputStream is = classLoader.getResourceAsStream("deployment.tar.gz")
ftpClient.connect(ftpServer)
ftpClient.enterLocalPassiveMode()
ftpClient.login("jenkins#my-domain.com","JenkisPassword")
ftpClient.setFileType(FTP.BINARY_FILE_TYPE)
// Store file to server
ftpClient.storeFile("deployment.tar.gz", is);
ftpClient.logout();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
ftpClient.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
upload();
Is there any solution for groovy ? or is it a bad way ?
You probably need to call setFileType(FTP.BINARY_FILE_TYPE) before sending the file

grails kickstart plugin KickstartFilters how to prevent password information on logs

I am using Grails version 2.2.4 and I have installed kickstart plugin as compile ":kickstart-with-bootstrap:0.9.6".
BuildConfig.groovy
plugins {
runtime ":hibernate:$grailsVersion"
runtime ":jquery:1.8.3"
runtime ":resources:1.1.6"
compile ":kickstart-with-bootstrap:0.9.6"
build ":tomcat:$grailsVersion"
runtime ":database-migration:1.3.2"
compile ':cache:1.0.1'
}
I found "KickstartFilters.groovy" filter with following directory structure
plugin
-> kickstart-with-bootstrap:0.9.6
-> conf
-> kickstart
-> KickstartFilters.groovy
my "KickstartFilters.groovy" file contains following information
package kickstart
class KickstartFilters {
def filters = {
all() {
before = {
// Small "logging" filter for controller & actions
log.info(!params.controller ? '/: ' + params : params.controller +"."+(params.action ?: "index")+": "+params)
}
after = {
}
afterView = {
}
}
}
}
while log.info are printed in logs at that time if password is passed as params then password information are visible on log so how can I prevent only password Information?
I have a work around for this...
https://github.com/joergrech/KickstartWithBootstrap/issues/84
Basically create your filter under conf/kickstart/YourAppFilters.groovy
package kickstart
class YourAppFilters extends KickstartFilters {
def filters = {
kickstartLogger() {
before = {
// Small "logging" filter for controller & actions
if (log.infoEnabled) {
if (!params.controller.equals('chat')) {
if (!params.password ) {
log.info(!params.controller ? '/: ' + params : params.controller +"."+(params.action ?: "index")+": "+params)
}else{
log.info (params.controller+","+params.action+":"+params?.username)
}
}
}
}
}
}
}
Now under conf/spring/resources.groovy under beans add:
yourAppFilters(KickstartFilters)
This should now override kickstarts filter

Grails with Geb/Spock : Grails doesn't take my baseUrl

I'm using Grails 2.2.1 with the recent Geb version. My Spec test files are under
functional/com.geb.mytest/
My GebConfig is on the same package as my Specs..
import org.openqa.selenium.firefox.FirefoxDriver
import org.openqa.selenium.firefox.FirefoxProfile
driver = {
FirefoxProfile firefoxProfile = new FirefoxProfile()
new FirefoxDriver(firefoxProfile)
}
reportsDir = "target/test-reports"
baseUrl = 'http://myserver.com'
waiting {
timeout = 5
retryInterval = 0.5
presets {
slow {
timeout = 20
retryInterval = 1
}
quick {
timeout = 1.5
retryInterval = 0.3
}
}
}
environments {
}
When I run grails test-app -functional my baseUrl is not taken in consideration...instead I have a localhost url..
Is there a way to avoid putting the baseUrl as an argument in the grails test-app command?
Any idea?
Thanks in advance
Try setting up baseUrl in class which is extended for every test class you have:
class BaseUrlTest extends GroovyTestCase {
def baseURL
#Override
protected void setUp() throws Exception {
super.setUp();
baseURL = 'your url here'
}
}
then your test class looks like this
class myTests extends BaseUrlTest {
void testSomething() {}
}

How do I completely bootstrap a grails environment?

I have the included grails script that I found in some random place on the internet and it works pretty well for firing up scripts in a bootstrapped grails env. The only thing it doesn't seem to do is kick off my conf/*Bootstrap.groovy scripts like when I do run-app.
Is there another function like loadApp() and configureApp() that will do that for me?
import org.codehaus.groovy.grails.support.PersistenceContextInterceptor
Ant.property(environment: "env")
grailsHome = Ant.antProject.properties."env.GRAILS_HOME"
includeTargets << new File("${grailsHome}/scripts/Bootstrap.groovy")
target('default': "Runs scripts in the test/local directory") {
if (!args) { throw new RuntimeException("[fail] This script requires an argument - the script to run.") }
depends(configureProxy, packageApp, classpath)
classLoader = new URLClassLoader([classesDir.toURI().toURL()] as URL[], rootLoader)
Thread.currentThread().setContextClassLoader(classLoader)
loadApp()
configureApp()
def interceptor = null
def beanNames = appCtx.getBeanNamesForType(PersistenceContextInterceptor)
if (beanNames && beanNames.size() == 1) {
interceptor = appCtx.getBean(beanNames[0])
}
try {
interceptor?.init()
new GroovyScriptEngine(Ant.antProject.properties."base.dir", classLoader).run("scripts/${args}.groovy", new Binding(['appCtx':appCtx]))
interceptor?.flush()
} catch (Exception e) {
e.printStackTrace()
interceptor?.clear()
} finally {
interceptor?.destroy()
}
}
Yes, try
new BootStrap().init()

Resources