I am working on spring boot application where I want to completely externalize my environment variables dynamically by config server.
So below is the code I have written.
Application.java
package com.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
#Configuration
#SpringBootApplication
#EnableAutoConfiguration
#ComponentScan("com.myPackage, com.util")
#PropertySource("classpath:application.properties")
public class Application extends SpringBootServletInitializer {
static final Logger logger = LoggerFactory.getLogger(Application.class);
public static ApplicationContext ctx;
public static void main(String[] args) throws Exception {
logger.info("Application starting....");
ctx = SpringApplication.run(Application.class, args);
logger.info("Application started successfully....");
}
#Bean
public static PropertySourcesPlaceholderConfigurer
propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
application.properties
server.port=${server.port}
ENDPOINT_SHAN=${name.mya}
Config Server:
APPLICATION_NAME=myapp
server.port=8081
name.mya=myName
To Read Properties
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import com.apptium.Application;
#Component("configurationProperties")
public class ConfigurationProperties {
private static Environment prop;
public static String getConfigValue(String key) {
String value = null;
if (prop == null) {
prop = Application.ctx.getBean(Environment.class);
}
if (prop.getProperty(key) != null) {
value = prop.getProperty(key).trim();
}
if (value == null && System.getenv(key) !=null) {
value = System.getenv(key).trim();
}
return value;
}
}
so, when I try to get the property ENDPOINT_SHAN, it is returning
ENDPOINT_SHAN==${name.mya} but it needs to return ENDPOINT_SHAN==myName
And also am wondering how the property for server.port is taken correctly.
Anyways, I would like to know, how to get an actual property for ENDPOINT_SHAN.
You said that name.mya is defined in a "Config Server" but your code doesn't show any connection being established to this server. You need to read it from the server before ${name.mya} becomes resolvable.
Related
https://ibb.co/Rjhwzfm
So i have to create a fetch service to retrieve sprint reports(basically data) from JIRA using the JIRA rest api so far have done this using REST template in springboot
SpringBootApplication.java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
#SpringBootApplication
public class SprintBootApplication {
private static final Logger log = LoggerFactory.getLogger(SprintBootApplication.class);
public static void main(String args[]) {
SpringApplication.run(SprintBootApplication.class);
}
#Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
#Bean
public CommandLineRunner run(RestTemplate restTemplate) throws Exception {
return args -> {
JiraDataFields data = restTemplate.getForObject(
"https://jira.mtvi.com/rest/api/2/search?fields=issuetype,customfield_10280,parent,key,summary,status,timeestimate,aggregatetimeoriginalestimate,assignee,subtasks&jql=project", JiraDataFields.class);
log.info(data.toString());
};
}
}```
JiraDataFields.class
```package com.sprint.SprintBoot;
public class JiraDataFields {
private int id;
private String workedBy;
}```
Can you please provide me with an example of primitive type dependency injection in spring boot. I have tried once but TestConfiguration which is my custom bean definition class does not detect or does not recognize by spring boot application.
here is my code,
//Engine class
package com.test2.projectTest;
import org.springframework.stereotype.Component;
#Component
public class Engine {
private String msg;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
//Test Configuration
package com.test2.projectTest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
#Configuration
public class TestConfiguration {
#Bean("engine")
public Engine engine(){
Engine engine = new Engine();
engine.setMsg("Message is injected");
return engine;
}
}
//spring main application
package com.test2.projectTest;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
#SpringBootApplication
public class ProjectTestApplication {
public static void main(String[] args) {
SpringApplication.run(ProjectTestApplication.class, args);
}
}
//JUnit Test
package com.test2.projectTest;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.ApplicationContext;
import
org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.test.context.junit4.SpringRunner;
#RunWith(SpringRunner.class)
#SpringBootTest
public class ProjectTestApplicationTests {
#Test
public void contextLoads() {
ApplicationContext apc = new
AnnotationConfigApplicationContext(TestConfiguration.class);
Engine e = (Engine) apc.getBean("engine");
e.getMsg();
}
}
// Output - org.springframework.beans.factory.NoSuchBeanDefinitionException:
No bean named 'engine' available
Please suggest any solution to above issue
Add #componentscan annotation in main class and provide engine class package and it should work
I have email.properties file under /src/main/resources/ and also in /src/test/resources/ folder.
I am trying to read the properties using #PropertyValue annotation.
I have registered the Bean in my SpringConfig.java file.
Inside SpringConfig.java :
public class SpringConfig extends WebMvcConfigurerAdapter {
#Bean
public static PropertySourcesPlaceholderConfigurer propertyConfigInDev() {
return new PropertySourcesPlaceholderConfigurer();
}
}
Inside EmailConfig.java :
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
#Configuration
#PropertySource("classpath:/src/main/resources/email.properties")
public class EmailConfig {
#Value("${smtp_userName}")
private String smtp_userName;
#Value("${forgotPasswordTemplate}")
private String forgotPasswordTemplate;
#Value("${forgotPasswordSubject}")
private String forgotPasswordSubject;
// corresponding getter, setters and constructors ()
}
I wrote a unit test for the above piece which is not working!
Inside my EmailConfigTest.java :
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.testng.Assert;
import org.testng.annotations.Test;
import com.time.dal.config.EmailConfig;
public class EmailConfigTest {
#Autowired
EmailConfig emailConfig;
#Value("${smtp_userName}")
private String smtp_userName;
#Value("${forgotPasswordTemplate}")
private String forgotPasswordTemplate;
#Value("${forgotPasswordSubject}")
private String forgotPasswordSubject;
#Test
public void testEmailConfig(){
System.out.println("SMTP User Name is "+smtp_userName);
Assert.assertNotNull(smtp_userName);
}
Here's my error :
SMTP User Name is null FAILED: testEmailConfig
java.lang.AssertionError: expected object to not be null at
com.time.dal.utils.EmailConfigTest.testEmailConfig(EmailConfigTest.java:31)
I am trying to read in a simple yml file for a Spring Boot application located at resources/wtf.yml. The following application works if the default application.yml filename is used, but not if I change the filename. Anyone know why this doesn't work?
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import javax.annotation.PostConstruct;
#EnableConfigurationProperties
#SpringBootApplication
#ConfigurationProperties(locations = {"wtf.yml"}) //classpath:wtf.yml
public class SomeApp {
public static void main(final String[] args) {
SpringApplication.run(SomeApp.class, args);
}
#PostConstruct
public void init() {
System.out.println(readTimeout);
}
#Value("${readTimeout}")
public int readTimeout;
}
You can use spring.config.name or spring.config.location properties as described in Spring Boot guide.
I am having an issue since I moved to version 1.1.4.RELEASE of Spring Boot.
My variables that are annotated with #Value are presently not being populated with values despite them being present in the application.properties. Prior to this I was using Spring Boot # version 1.0.2, and that was working fine.
It all started since the upgrade, and I made no code change.
SampleApplication.java
package org.sample;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
#Configuration
#ComponentScan
#EnableAutoConfiguration
#PropertySource(value = "classpath:application.properties")
public class SampleApplication {
private static Logger logger = LoggerFactory
.getLogger(TaskManagerApplication.class);
#Value("${org.sample.sampleProperty}")
private static String sampleProperty;
public static void main(String[] args) {
SpringApplication.run(SampleApplication.class, args);
System.out.print("SampleApplication started: " + sampleProperty);
}
#Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
application.properties
spring.datasource.url: jdbc:mysql://127.0.0.1:3306/mydb
spring.datasource.username: root
spring.datasource.password: root
spring.datasource.driverClassName: com.mysql.jdbc.Driver
spring.jpa.show-sql: true
#Disable the ddl-auto:create once tables have been created
#spring.jpa.hibernate.ddl-auto: create
org.sample.sampleProperty=This is a sample property
photos.upload.dir=C:/temp/UserPhotos/
# Server port
server.port=8081
I have tried to add a PropertySourcesPlaceholderConfigurer bean and even PropertySourcesPlaceholderConfigurer but still the issue persists.
Anyone experienced this ? Or is there a new way to load the properties file ?
Please note that my db connection and server port are being read properly since my application can connect to db and I have to access it through the specified port.
sampleProperty variable remains null though.
#Value is not meant to work on static fields
Properties from application.properties are available automatically without specifying #PropertySource for it.
Instead of printing out property in main() method, you should do it after bean is constructed, for example by using #PostConstruct
Fully working example:
package demo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
#Configuration
#ComponentScan
#EnableAutoConfiguration
public class Application {
#Value("${org.sample.sampleProperty}")
private String sampleProperty;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#PostConstruct
public void postConstruct() {
System.out.print("SampleApplication started: " + sampleProperty);
}
}