Spring boot. Reading MANIFEST.MF using jcabi manifests - spring-boot

I'm trying to add AppName and Version to actuator's /info endpoint using jcabi-manifests https://github.com/jcabi/jcabi-manifests library. Code snippet is below:
#Component
public class VersionInfoContributor implements InfoContributor {
#Override
public void contribute(Info.Builder builder) {
String artifactName = Manifests.read("Artifact-Name");
builder.withDetail("Artifact-Name", artifactName);
}
Artifact-Name is set in build.gradle file next way:
jar {
manifest {
attributes("Artifact-Name": "TestActuator")
}
}
The attribute IS present in META-INF/MANIFEST.MF file inside result .jar file but when trying to access /info endpoint getting error:
Attribute 'Artifact-Name' not found in MANIFEST.MF file(s) among 46 other attribute(s)
I know there is BuildProperties bean in Spring-boot actuator but won't like idea to expose all these fields - AppName and Version more than enough.

Related

Spring boot: external properties file an PropertySource

I am developing a spring boot application with gradle.
I would love to tell spring where to read .properties files with a parameter. Since I am still running it via gradle, I have added this to my build.gradle
bootRun {
args = [
"--spring.config.additional-location=file:/path/to/my/props/folder/,file:/path/to/another/props/folder/"
]
}
into /path/to/my/props/folder/ I have created a file remote-connection.properties:
### remote-connection
remote.ip.address=127.0.0.1
remote.ip.port=5001
and I am trying to load those props like this
#RestController
#PropertySource("file:remote-connection.properties")
public class MyController {
#Value("${remote.ip.address}")
private String remoteIpAddress;
}
When i run ./gradlew bootRun i have the following error
org.springframework.beans.factory.BeanDefinitionStoreException: Failed to parse configuration class [my.package.MyApplication]; nested exception is java.io.FileNotFoundException: remote-connection.properties (No such file or directory)
(I have also tried #PropertySource("classpath:remote-connection.properties") and #PropertySource("remote-connection.properties"))
It works flawlessly if I place remote-connection.properties into src/main/resources, but I want that config file to be outside the resulting jar, being able to run it with
java -jar my-application.jar --spring.config.additional-location=file:/path/to/my/props/folder/,file:/path/to/another/props/folder/
What am I missing?
Thanks in advance.
Answering my own question.
Following this guide https://mkyong.com/spring/spring-propertysources-example/ I have changed my run args to
bootRun {
args = [
"--my.props.folder=/path/to/my/props/folder",
"--my.other.props.folder=/path/to/another/props/folder",
]
}
and loading props like this
#RestController
#PropertySource("file:${my.props.folder}/remote-connection.properties")
#PropertySource("file:${my.other.props.folder}/some-more.properties")
public class MyController {
#Value("${remote.ip.address}")
private String remoteIpAddress;
}
This way, it works!!

Share application.properties files in different project

Below showing the project structure
Core Project
|-config project
|
|-Service project
After building the core project we get Service.jar file.
While running the service.jar am passing spring.config.additional.location as command line argument.
java -jar Service-1.0.jar --spring.config.additional-location=C:/Users/Administrator/Desktop/Springboot/
above spring.config.additional.location path having application.property file and some xml files.
I can able to read application property file in service project ,following logic
Application.propertes
external.config=C:/Users/Administrator/Desktop/Springboot/config/
Mian Class
#ImportResource(locations = {
"${external.config}"+"/spring/service-config.xml",
"${external.config}"+"/spring/datasource-config.xml"
})
public class ServiceMain {
public static void main(String[] args) {
ConfigurableApplicationContext applicationContext = new SpringApplicationBuilder(ServiceMain.class)
.build()
.run(args);
for (String name : applicationContext.getBeanDefinitionNames()) {
}
}
}
Similar kind of logic applied in config project is given below,its not working
#Configuration
public class ConfigurationFactory
{
#Value("${external.config}")
public String extConfPath;
public String REQ_CONF = extConfPath+"/Configuration.xml";
public static final String FILTER_XML_CONF = extConfPath+"/DocFilter.xml";
}
Is there any better way to do this? How can i read external application.properties in config project
Do we have any better way to do this in spring boot
As you are cleary developing a distributed web system the best practice is to used externalised configuration used by your different services allowing you to update settings without redeployment. Take a look at Spring Cloud Config

SpringCloud's /refresh not effective on properties used in camel routes

Camel version : 2.22.0
SpringBoot Version : 2.0.2.RELEASE
Observation: the config properties, which ideally have to be updated as they are changed in the configuration service and when a refresh is done at the Client service, does not take effect in case of properties that are used inside a Camel Route.
Note: there is a ticket in Jira whihc says fixed. but which release has this? https://issues.apache.org/jira/browse/CAMEL-8482
Adding the code segment:
The class which contains below code segment is annotated with #Component and #RefreshScope
#Value("${prop}")
String prop;
#Override
public void configure() throws Exception {
from("direct:route1").routeId("Child-1")
.setHeader( Exchange.CONTENT_ENCODING, simple("gzip"))
.setBody(simple("RESPONSE - [ { \"id\" : \"bf383eotal length is 16250]]"))
.log(prop + "${body}")
;

Amazon Web Services - Deploy Spring Boot Application

I have a spring boot application that I am deploying onto EB (Elastic Beanstalk) AWS. The app works fine locally, however, I get a 404 on all pages I try to access on the deployed version. Also, I can't access any of the static content under the static folder either. All REST endpoints work fine.
My project structure is as follows
-- src
-- main
-- kotlin
-- resources
-- static
-- css
-- fonts
-- images
-- js
-- templates (contains html files)
I've tried defining option_settings in a .config file under a .ebextensions folder
option_settings
aws:elasticbeanstalk:container:java:staticfiles:
/public/: WEB-INF/classes/static
/static/: WEB-INF/classes/staticenter code here
I've also tried adding the following to my spring configuration class
#Configuration open class MvcConfig : WebMvcConfigurerAdapter() {
override fun addViewControllers(registry: ViewControllerRegistry) {
registry.addViewController("/").setViewName("homepage")
registry.addViewController("/index").setViewName("homepage")
registry.addViewController("/home").setViewName("homepage")
registry.addViewController("/homepage").setViewName("homepage")
registry.addViewController("/login").setViewName("login")
registry.addViewController("/products").setViewName("productsList")
registry.addViewController("/productdetail").setViewName("productDetail")
}
#Bean
open fun viewResolver(): ViewResolver {
val bean = InternalResourceViewResolver()
bean.setPrefix("/templates/")
bean.setSuffix(".html")
return bean
}
override fun addResourceHandlers(registry: ResourceHandlerRegistry?) {
// Register resource handler for all static folders
registry!!.addResourceHandler("/resources/**").addResourceLocations("classpath:/statics/")
.setCacheControl(CacheControl.maxAge(2, TimeUnit.HOURS).cachePublic())
}
#Bean
open fun errorPageFilter(): ErrorPageFilter {
return ErrorPageFilter()
}
#Bean
open fun disableSpringBootErrorFilter(filter: ErrorPageFilter): FilterRegistrationBean {
val filterRegistrationBean = FilterRegistrationBean()
filterRegistrationBean.filter = filter
filterRegistrationBean.isEnabled = false
return filterRegistrationBean
}
I am deploying onto tomcat8 that sits behind an Apache proxy server.
My EB settings are correct as I tried to deploy a simpler application onto the instance, which worked fine.
Please let me know if there are any further details I need to provide
The issue was related to the resourceHandler, the classpath it self was never added to the resource handler, even though servlet logging was indicating it was.
Spring by default maps the following paths
classpath:META-INF/resources/
classpath:resources/
classpath:static/
classpath:public/
needed to add the /** to the mapping. The solution was to modify the code to the following
override fun addResourceHandlers(registry: ResourceHandlerRegistry?) {
registry!!.addResourceHandler("/**", "/static/**")
.addResourceLocations("classpath:/templates/", "classpath:/static/").setCacheControl(CacheControl.maxAge(2,TimeUnit.HOURS).cachePublic())
}
#Bean
open fun viewResolver(): ViewResolver {
val bean = InternalResourceViewResolver()
bean.setSuffix(".html")
return bean
}

Log4j2 in a spring web app with servlet 3.0

I need to change the default location of log4j2 configuration file. I followed the documentation here
https://logging.apache.org/log4j/2.x/manual/webapp.html
But the only file log4j2 can see is log4j2.xml in the classpath. otherwise I get "no log4j2 configuration file found"
I tried:
-1 setting context parameters
-2 setting system property Log4jContextSelector to "org.apache.logging.log4j.core.selector.JndiContextSelector". and using the JNDI selector
as described here
https://logging.apache.org/log4j/2.x/manual/webapp.html#ContextParams
-3 lookups: web, env, sys, ctx and bundle. the first 4 failed only bundle worked but you can only lookup inside the classpath.
-4 set isLog4jAutoInitializationDisabled to true, and I am not sure how to configure the filter in this case. If I include them in the web.xml the app will not deploy.
jar in the project
./WEB-INF/lib/log4j-jcl-2.4.1.jar
./WEB-INF/lib/log4j-core-2.4.1.jar
./WEB-INF/lib/log4j-slf4j-impl-2.4.1.jar
./WEB-INF/lib/log4j-api-2.4.1.jar
In my situation with .propeties file I use code shown below
#Plugin(name = "LogsConfigurationFactory", category = ConfigurationFactory.CATEGORY)
public class CustomLogsConfigurationFactory extends PropertiesConfigurationFactory {
#Override
public Configuration getConfiguration(String name, URI configLocation) {
File propFile = new File("/path_to/log4j2.properties");
return super.getConfiguration(name, propFile.toURI());
}
#Override
protected String[] getSupportedTypes() {
return new String[] {".properties", "*"};
}
}
I think you can change CustomLogsConfigurationFactory on XmlConfigurationFactory, and change return typse in getSupportedTypes method. I hope this will help you.

Resources