I am learning Spring Boot v.2.3.9.RELEASE + Microservices project from here - https://www.youtube.com/watch?v=Z7A_M8HkJG0
In this example, I am unable to fetch the details from the properties file using spring-cloud-config.
spring-config-server
application.yml
spring:
application:
name: config-server
cloud:
config:
server:
git:
uri: https://github.com/techefx/environment-variable-repo.git
server:
port: ${port:8888}
ConfigServerApplication.java
#SpringBootApplication
#EnableConfigServer
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
property-access-service
PropertyAccessBean.java
#Component
#ConfigurationProperties(prefix = "property-file")
#Builder
#Data
#NoArgsConstructor
#AllArgsConstructor
public class PropertyAccessBean {
private String name;
private String description;
}
PropertyAccessValue.java
#Builder
#Data
#NoArgsConstructor
#AllArgsConstructor
public class PropertyAccessValue {
private String name;
private String description;
}
PropertyAccessServiceApplication.java
#SpringBootApplication
public class PropertyAccessServiceApplication {
public static void main(String[] args) {
SpringApplication.run(PropertyAccessServiceApplication.class, args);
}
}
put (default-label: main) in yml file:
spring:
application:
name: techefx-spring-cloud-config-server
cloud:
config:
server:
git:
uri: https://github.com/techefx/environment-variable-repo.git
default-label: main
server:
port: ${port:8888}
Related
I'm trying to inject Bean of properties within context Bean.
(Spring-boot 2.7.3 / Java 11)
My application.yml is like below:
spring:
config:
active: dev
---
spring:
config:
activate:
on-profile: dev
keycloak:
username: "local"
password: "local"
---
spring:
config:
activate:
on-profile: stg
keycloak:
username: "stg"
password: "stg"
---
spring:
config:
activate:
on-profile: prod
keycloak:
username: "prod"
password: "prod"
and my KafkaProducerConfig.java code like below:
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.ConstructorBinding;
import org.springframework.stereotype.Component;
import lombok.Getter;
#Getter
#Component
#ConstructorBinding
#ConfigurationProperties("keycloak")
public class KafkaProducerConfig {
private final String username;
private final String password;
public KafkaProducerConfig(String username, String password) {
this.username = username;
this.password = password;
}
}
and finally I failed to inject within another class.
Actually, UserDataProducer class extended in a context bean class which means UserDataProducer class also instanciated by spring IoC Container as I know.
I also tried #DependsOn which doesn't work.
#Slf4j
#DependsOn(value = {"KafkaProducerConfig"})
public class UserDataProducer {
#Autowired
KafkaProducerConfig kafkaProducerConfig;
private final String topicName;
public UserDataProducer() {
log.info("===========================================================");
log.info("Initializing UserDataProducer ...");
System.out.println(kafkaProducerConfig.getPassword());
log.info("===========================================================");
// additional properties for transactional producing
topicName = ProducerConfig.PRODUCER_PROPS.getProperty("default.topic");
}
#Slf4j
#Component
public class UserDataProducer {
// use static initializer block to initialize your static fields
// private static final Producer<String, Object> producer;
// initialzer order : static{} -> instance block {} -> constructor
private final String topicName;
public UserDataProducer(KafkaProducerConfig kafkaProducerConfig) {
log.info("===========================================================");
log.info("Initializing UserDataProducer ...");
System.out.println(kafkaProducerConfig.getPassword());
log.info("===========================================================");
// additional properties for transactional producing
topicName = ProducerConfig.PRODUCER_PROPS.getProperty("default.topic");
}
When I update a property in the vault and call actuator / refresh, it still shows an older value.
I use spring boot and spring cloud.
<spring-cloud-dependencies.version>2020.0.3</spring-cloud-dependencies.version>
<spring-boot-dependencies.version>2.5.3</spring-boot-dependencies.version>
#SpringBootApplication
#EnableEurekaClient
#VaultPropertySource(value = "secret/services/${spring.application.name}/config", propertyNamePrefix = "", renewal = VaultPropertySource.Renewal.RENEW)
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
#RestController
public class ErrorControllerImpl implements ErrorController {
#Value("${gateway.prefix}")
private String prefixPath;
#Override
public Mono<String> errorPost(String serviceName) {
return errorResponse(serviceName);
}
#Override
public Mono<String> errorGet(String serviceName) {
System.out.println(prefixPath);
return errorResponse(serviceName);
}
Yml
spring:
application:
name: ${APP_NAME}
profiles:
active: ${PROFILE:dev}
cloud:
config:
enabled: ${CONFIG_SERVER_ENABLED:false}
vault:
uri: https://localhost:8200
authentication: APPROLE
app-role:
role-id: ${VAULT_SERVICE_ROLE_ID}
secret-id: ${VAULT_SERVICE_SECRET_ID}
scheme: http
fail-fast: true
kv:
enabled: false
The prefixPath in the controller does not change after refresh.
What would be the reason ?
Thanks for your help.
My spring boot application can not get configuration parameters from application.yml file. My main class as following:
#SpringBootApplication(scanBasePackages={"com.test"})
public class Main {
#Bean
public Validator validator(){
return new org.springframework.validation.beanvalidation.CustomValidatorBean();
}
public static void main(String[] args) throws IOException {
new SpringApplicationBuilder(Main.class)
.properties("application.yml")
.build()
.run(args);
}
}
My controller class as following:
#RestController
#RequestMapping("/test_traffic")
#Component
public class AnycastTrafficController {
#Autowired
TestService testService;
#GetMapping("/test")
public Object component() {
return testService.getTraffic();
}
}
My Service class as following:
#Service
public class TestService {
#Autowired
TestDao testDao;
public Object getTraffic() {
testDao.getTraff();
}
}
My Dao class as following:
#Component
public class TestDao {
#Autowired
MyDBConfig mydbConfig;
public DB getMyDBConfig () {
DB db = new DB(mydbConfig.id, mydbConfig.key);
return db;
}
}
My Config class as following:
#Configuration
#EnableConfigurationProperties
#ConfigurationProperties(prefix = "mydb")
public class MyDBConfig {
public String id;
public String key;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
}
My application.yml (which located at /src/main/resources)as following:
server:
port: 8003
context-path: /
logging:
level:
ROOT: INFO
org.springframework: INFO
org.springframework.data: INFO
com.alibaba: INFO
file: log/
docserver:
accessKeyId: 1111
accessKeySecret: 2222
---
spring:
profiles: dev
application:
name: test-application
mydb:
id: 1111111
key: 2222222
But when I started the Main class and request the url, it threw exception as following:
the id should not be empty.
that mean my Configuration class didn't get the configure data from yml file, so where I did wrong please. p.s(but the server port 8003 could be found by application). Thanks!
Your application.yml contains an invalid property option.
Instead of
spring:
profiles: dev
you should use
spring:
profiles:
active: dev
After correcting this this, the configuration processor should work properly.
I am working with Consul using spring-cloud-consul and currently have this problem. I create a key in consul as config/ConsulServer/my/username with value as "bob". In my controller, i return this value if a API call "/foo" is made. When i modified it the first time to "steve" the value is updated and i get "steve". However, it does not work the second time. The value is still "steve". Could anyone please help on what I did wrong ? My codes are
#SpringBootApplication
#EnableDiscoveryClient
public class ConsulServer {
public static void main(String[] args) {
SpringApplication.run(ConsulServer.class, args);
}
}
#Component
#RefreshScope
#ConfigurationProperties("my")
public class SampleProperties {
private String username;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username= username;
}
}
#RestController
public class ConsulController {
#Autowired
private SampleProperties consulConfig;
#GetMapping("/foo")
public String prop() {
return this.consulConfig.getUsername();
}
}
My bootstrap.yml is
spring:
application:
name: ConsulServer
cloud:
consul:
host: localhost
port: 8500
config:
enabled: true
fail-fast: true
watch:
enabled: true
discovery:
register: true
My application.yml is
spring:
application:
name: ConsulServer
I am using spring-cloud-starter-consul-all version 2.1.0.RC3
I'm using Spring boot.
I have an application.yml in src/main/resources. I then have a Configuration class that I am trying to get to load the application.yml. However, when I try to use the configuration class in another bean, the values are null. See the ApiHelper.java as to where the values are null.
I'm attempting to run the jar as so:
java -jar build/libs/app.jar
Am I doing something wrong? I've also tried using a properties file instead. When I unzip the jar file the configuration files are in the root.
src/main/resources/application.yml
spring:
profiles.active: default
---
spring:
profiles: default
api:
path: http://some-path
---
spring:
profiles: qa
api:
path: http://some-path2
src/main/java/AppConfig.java
#Configuration
#EnableConfigurationProperties(ApiConfig.class)
public class AppConfig {
#Autowired
private ApiConfig apiConfig;
#ConfigurationProperties(value = "api", exceptionIfInvalid=true)
public static class ApiConfig {
private String path;
public ApiConfig() {
System.out.println("Am I getting called?"); // yes it is
}
public String getPath() {
return path;
}
}
#Bean
public ApiHelper getApiHelper() {
return new ApiHelper();
}
}
src/main/java/ApiHelper.java
public class ApiHelper {
#Autowired
private ApiConfig apiConfig;
#PostConstruct
private void init() {
System.out.println(apiConfig); // prints ApiConfig#168498d6
System.out.println(apiConfig.getPath()); // prints null
}
}
It turns out that you need a setter to make it work:
#ConfigurationProperties(value = "api", exceptionIfInvalid=true)
public static class ApiConfig {
...
public void setPath(String path) {
this.path = path;
}
}