I'm working with HashiCorp Vault and want to map the key-value from Vault json file to a application.yml placeholder, but catching the NPE when making request to call another service
that's my Vault secrets file
{
"vault": {
"region-location": {
"34": {
"latitude": 55.76593684245433,
"longitude": 37.62111491585245
},
"2397": {
"latitude": 53.3499441638952,
"longitude": 83.7835286298899
},
"6609": {
"latitude": 56.860216399045555,
"longitude": 53.22638189062013
},
"7011": {
"latitude": 43.02940154439686,
"longitude": 44.666051850849186
}
},
"security": {
"user": {
"name": "user",
"password": "password"
}
}
}
}
here is my bootstrap.yml
spring:
cloud:
vault:
enabled: true
fail-fast: true
uri: ******
authentication: approle
namespace: dom
application-name: atp
app-role:
role-id: ${SPRING_ROLE_ID} #from env var
secret-id: ${SPRING_SECRET_ID} #from env var
role: approle
generic:
enabled: false
kv:
enabled: true
backend: applications
default-context: common # not used for now
config:
lifecycle:
enabled: false
session:
lifecycle:
enabled: false
here is my application.yml
build.version: @project.version@
server:
port: ${PORT:8080}
shutdown: graceful
forward-headers-strategy: framework
servlet:
encoding:
charset: UTF-8
force-response: true
spring:
application:
name: @project.name@
security:
user:
name: ${vault.security.user.name}
password: ${vault.security.user.password}
springdoc:
default-produces-media-type: application/json
region-location: ${vault.region-location}
here is the service class
@Service
@RequiredArgsConstructor
public class AppointmentService {
private final AppointmentClient appointmentClient;
private final DataConfigProperties dataProperties;
public Map<String, OffsetDateTime> getHomeDeliveryStoreToNearestDate(String regionId, OffsetDateTime now,
Set<String> homeDeliveryEligibleStoresIds) {
if (homeDeliveryEligibleStoresIds.size() == 0) {
return emptyMap();
}
var request = makeHomeDeliveryAppointmentsRequest(regionId, homeDeliveryEligibleStoresIds, now);
var storeIds = request.getActualDates().stream().map(ActualDate::getStoreId).collect(Collectors.toSet());
var storeToNearestDate = new HashMap<String, OffsetDateTime>();
var response = appointmentClient.getHomeDeliveryAppointments(request);
for (String storeId : storeIds) {
var startDate = response.getAppointments()
.stream()
.filter(appointment -> appointment != null
&& appointment.getStart() != null
&& appointment.getAvailableStoreIds().contains(storeId))
.min(Comparator.comparing(Appointment::getStart));
startDate.ifPresent(appointment -> storeToNearestDate.put(storeId, appointment.getStart()));
}
return storeToNearestDate;
}
private AppointmentHomeDeliveryRequest makeHomeDeliveryAppointmentsRequest(String regionId, Set<String> storesIds,
OffsetDateTime now) {
var actualDates = storesIds
.stream()
.map(storeId -> new ActualDate(now.toZonedDateTime(), storeId))
.toList();
return new AppointmentHomeDeliveryRequest(
actualDates, dataProperties.getRegionLocation().get(regionId), regionId, PERSON, ONLINE, STANDARD);
}
}
When I try to call my endpoint, it creates request to another service and then NPE occurs:
java.lang.NullPointerException: Cannot invoke "java.util.Map.get(Object)" because the return value of "com.msk.someservice.client.config.properties.DataConfigProperties.getRegionLocation()" is null
@Data
@Component
@ConfigurationProperties(prefix = "region-location")
public class DataConfigProperties {
private Map<String, Location> regionLocation;
}
i tried to use the common configuration annotations and also the `@Value` annotation with `@PropertySource` - but in wont help, did you face the problem?
upd: Authorization credentials mapping works fine from Vault