Spring kafka not able to read truststore file from classpath - spring-boot

I am building an kafka consumer app which needs SASL_SSL config. Some how apache kafka is not recognizing truststore file located in classpath and looks like there is an open request to enhance it in kafka(KAFKA-7685).
In the mean time what would be the best way to solve this problem. Same app needs to deployed in PCF too so solution should work both during local windows based development and PCF (linux).
Any solution would be highly appreciated.
Here is the code which does file copy to java temp dir
String tempDirPath = System.getProperty("java.io.tmpdir");
System.out.println("Temp dir : " + tempDirPath);
File truststoreConf = ResourceUtils.getFile("classpath:Truststore.jks");
File truststoreFile = new File(tempDirPath + truststoreConf.getName());
FileUtils.copyFile(truststoreConf, truststoreFile);
System.setProperty("ssl.truststore.location", truststoreFile.getAbsolutePath());

You could use a ClassPathResource and FileCopyUtils to copy it from the jar to a file in a temporary directory in main() before creating the SpringApplication.

Root cause of this issue was resource filtering enabled. Maven during resource filtering corrupts the binary file. So if you have that enabled, disable it

Related

How to copy/access file in Kubernetes

Working on Spring boot microservice and we have file in the folder file/Service.wsdl
And we are accessing the file using
#Value("file:file/Service.wsdl")
String WSDL_LOCATION;
In Kubernetes, we are getting "file/directory not found"...How to solve this.
You can try this #Value("${file:file/Service.wsdl}")
String WSDL_LOCATION;
Or else you can create config map of using this file and use that path .

Spring application war - Google App Engine - How to specify Log location, profile, environment variab;les

I have a spring boot application bundled as war file , and able to push to App Engine
But I am getting problems starting app (I suspect there could be an issue with DB too...but couldnt remember where I saw...a nightmare)
java.lang.RuntimeException: java.lang.IllegalStateException: Logback
configuration error detected: ERROR in
ch.qos.logback.core.rolling.RollingFileAppender[FILE] - Failed to
create parent directories for
[/base/data/home/apps/e~pemy/20210716t001812.436581063072799646/logs/pynew.log]
ERROR in ch.qos.logback.core.rolling.RollingFileAppender[FILE] -
openFile(logs/pynew.log,true) call failed.
java.io.FileNotFoundException: logs/pynew.log (No such file or
directory)
I am using the below properties in my application props
> logging.file.path=logs
> logging.file.name=${logging.file.path}/pynew.log
I am finding it very hard to include google specific dependencies and properties , and making a mess of my project...created app.yaml, web-inf>> appengine-web xml, logging.properties (not sure why but added as told in a tutorial)
Question: How can I create parent directory or link to cloud storage folder etc?
I also want to specify a profile and I see I can do it in yaml file. Is this used only
env_variables:
JAVA_USER_OPTS: '-Dspring.profiles.active=prod'
But I would like to know how to connect to Cloud SQL
spring.datasource.url=jdbc:mysql:///mydb?cloudSqlInstance=myapp:europe-west2:dBinstancename&socketFactory=com.google.cloud.sql.mysql.SocketFactory
spring.datasource.username=${dbuser}
spring.datasource.password=ENC(${dbencpwd})
spring.cloud.gcp.sql.database-name=mydb
spring.cloud.gcp.sql.instance-connection-name=myapp:europe-west2:dBinstancename
It is so confusing that I keep forgetting which connection needs password and which wont. and keep breaking my local
Question
Assuming that I need to supply credentials, How can I supply - ${dbuser}
I used the default spring logger with logback-spring.xml for all my development, and this is not working on AppEngine
So I followed https://cloud.google.com/logging/docs/setup/java
and added logback.xml and the dependency
implementation 'com.google.cloud:google-cloud-logging-logback:0.121.3-alpha'

Cannot access pdf files in resources folder

i have a web app where i put some pdf files in the resources folder that are rendered to users when they click a download button, this is how i read the file
ClassLoader classloader = Thread.currentThread().getContextLoader();
File f = new File(classloader.getResource("pdf/report.pdf").getFile);
Then i render the file within a response, this works fine when i run it in eclipse.
But once i package it into a war file and deploy it using apache tomcat manager, i cannot access the file anymore it shows me a 500 ERROR that the specified access file is inaccessible.
If I understand your question correctly, then you need to get stream for the resource and serve response from that resource and not from the file. Classloader has function getResourceAsStream which should work with same parameter your are passing to getResource
ClassLoader classloader = Thread.currentThread().getContextLoader();
InputStream stream = classloader.getResourceAsStream("pdf/report.pdf")
// Copy resource stream to servlet response e.g. using Apache IOUTils
IOUtils.copy(stream, <servelet response stream>)
// Don't forget to close stream
Eclipse most like is resolving local file path which may not work in web applications environment in same way.
open your war file and check manually into "/WEB-INF/classes/" folder your file is exist into this folder or not.

wsadmin upload file from local machine to remote

I'm trying to automate process of deployment and I want to upload some files to WAS using wsadmin (jython). My question is if it is possible to upload file from my standalone wsadmin to remote WAS Server. And if so, is it possible to upload file somewhere out of application (fe. /opt/IBM/WebSphere/AppServer/temp)? I don't want to upload it to specific profile, but to server root.
When I'm deploying application it is copying war/ear file to WAS, so is it there some mechani to upload separate file?
many thanks
AntAgent allows you to upload any file, provided that the content of the file can fit in memory:
https://www.ibm.com/support/knowledgecenter/en/SSAW57_8.5.5/com.ibm.websphere.javadoc.doc/web/mbeanDocs/AntAgent.html
In wsadmin you'll need to use invoke_jmx method of AdminControl object.
from java.lang import String
import jarray
fileContent = 'hello!'
antAgent = AdminControl.makeObjectName(AdminControl.queryNames('WebSphere:*,type=AntAgent,process=dmgr'))
str = String(fileContent)
bytes = str.getBytes()
AdminControl.invoke_jmx(antAgent, 'putScript', [String('hello.txt'),bytes], jarray.array(['java.lang.String', '[B'], String))
Afterwards you'll find 'hello.txt' file in WAS profile's temp directory. You may use relative paths as well.

Embedded Glassfish v3: deploying sun-resources.xml programmatically fails

I would like to be able to package my jpa-ejb-web project as a standalone application, by using Glassfish embedded API.
To use the JPA layer, I need to deploy the sun-resource.xml configuration, which should be possible with the asadmin command add-resources path\to\sun-resources.xml. I've this code to do it:
String command = "add-resources";
ParameterMap params = new ParameterMap();
params.add("", "...\sun-resources.xml" );
CommandRunner runner = server.getHabitat().getComponent(CommandRunner.class);
ActionReport report = server.getHabitat().getComponent(ActionReport.class);
runner.getCommandInvocation(command, report).parameters(params).execute();
but Glassfish refuses it with:
15-Jul-2010 16:34:12 org.glassfish.admin.cli.resources.AddResources execute
SEVERE: Something went wrong in add-resources
java.lang.Exception: ...\gfembed6930201441546233570tmp\lib\dtds\sun-resources_1_4.dtd (The system cannot find the path specified)
at org.glassfish.admin.cli.resources.ResourcesXMLParser.initProperties(ResourcesXMLParser.java:163)
at org.glassfish.admin.cli.resources.ResourcesXMLParser.<init>(ResourcesXMLParser.java:109)
at org.glassfish.admin.cli.resources.ResourcesManager.createResources(ResourcesManager.java:67)
at org.glassfish.admin.cli.resources.AddResources.execute(AddResources.java:106)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$1.execute(CommandRunnerImpl.java:305)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:320)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1176)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$900(CommandRunnerImpl.java:83)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1235)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1224)
at javaapplication4.Main.main(Main.java:55)
and indeed, there is no lib directory on the indicated path ...
is there something wrong in my code? (I use glassfish-embedded-all-3.0.1.jar)
Thanks
I solved it by specifying an Embedded File System for the embedded Glassfish, and prepopulated the /path/to/my/glassfish/lib/dtds folder with the files which were missing.
EmbeddedFileSystem.Builder efsb = new EmbeddedFileSystem.Builder();
efsb.autoDelete(false);
efsb.installRoot(new File("/path/to/my/glassfish"), true);
EmbeddedFileSystem efs = efsb.build();
Server.Builder builder = new Server.Builder("test");
builder.embeddedFileSystem(efs);
builder.logger(true);
Server server = builder.build();
server.addContainer(ContainerBuilder.Type.all);
server.start();
and asking Glassfish not to delete the folder at the end of the execution.
I'm not sure this is possible, Running asadmin Commands Using the Sun GlassFish Embedded Server API doesn't mention such a use case (passing a sun-resources.xml).
But I would use a preconfigured domain.xml instead of trying to deploy a sun-resource.xml file, the result should be similar. From the Sun GlassFish Enterprise Server v3 Embedded Server Guide:
Using an Existing domain.xml File
Using an existing domain.xml file
avoids the need to configure embedded
Enterprise Server programmatically in
your application. Your application
obtains domain configuration data from
an existing domain.xml file. You can
create this file by using the
administrative interfaces of an
installation of nonembedded Enterprise
Server. To specify an existing
domain.xml file, invoke the
installRoot, instanceRoot, or
configurationFile method of the
EmbeddedFileSystem.Builder class or
a combination of these methods.
The documentation provides code samples showing how to do this (should be pretty straightforward).

Resources