aatuc210
aatuc210

Reputation: 1868

Spring: Can't map YAML to list of objects

I have a yaml file with errors and error messages. I'm attempting to load them into a class, RefreshErrors within a common jar used by my Spring Boot microservices. The common jar does have Spring Boot on the classpath, but there is no SpringBootApplication - it's simply included by other applications. So that may be why I'm not getting any values in RefreshErrors?

Here's the yaml, which is in application.yml, located under src/main/resources:

refreshErrorsProperties:
  refreshErrors:
    -
      recordStatus: "Error"
      errorCode: "502 Bad Gateway"
      errorMessage: "AWS service is tempoarily not available. ESS has been notified. Please try refreshing again after the service becomes available."
    -
      recordStatus: "Error"
      errorCode: "503 Service Temporarily Unavailable"
      errorMessage: "AWS service is tempoarily not available. ESS has been notified. Please try refreshing again after the service becomes available."
    -
...

And here's my configuration for the class I want the yaml mapped to:

@Data
@Component
@ConfigurationProperties(prefix="refreshErrors")
public class RefreshErrorsProperties {
    private List<RefreshErrors> refreshErrors = new ArrayList<>();
}

The RefreshErrors class:

@Data
@AllArgsConstructor
public class RefreshErrors {
    private String errorCode;
    private String recordStatus;
    private String errorMessage;
}

I autowire RefreshErrors in another class (see below) and I do get an object reference, but all the values inside (like errorCode etc) are empty. Any help would be appreciated!

@Autowired
public void setRefreshErrorsProperties(RefreshErrorsProperties refreshErrorsProperties) {
    RefreshJobDetailHelper.refreshErrorsProperties = refreshErrorsProperties;
}
...
    RefreshErrors error;
    if (exception != null) {
        String fullException = ExceptionUtils.getStackTrace(exception);
        error = refreshErrorsProperties.getRefreshErrors().stream()
                .filter(f -> fullException.contains(f.getErrorCode()))
                .findAny()
                .orElseGet((Supplier<? extends RefreshErrors>) new RefreshErrors("Error", ERROR.getValue(), "An error has occurred while refreshing this record. ESS has been notified. Please try refreshing again after the issue has been resolved."));
    } else {
       error =  new RefreshErrors("No data", ERROR_NO_DATA.getValue(), "Data is not available in the source for this product, domain, and effective date.");
    }

Upvotes: 0

Views: 1885

Answers (2)

user1856856
user1856856

Reputation: 31

if you don't change your annotation,the yaml file node refreshErrors's attribute should not be a list, the yaml file should be

refresh-errors:
  record-status: "Error"
  error-code: "502 Bad Gateway"
  error-message: "AWS service ..."

which may not be what you want, if you don't change your yaml file, the code should be like Mohit Singh shows

Upvotes: 0

Mohit Singh
Mohit Singh

Reputation: 524

The issue here is with the prefix @ConfigurationProperties(prefix = "refreshErrors"). It should be like @ConfigurationProperties, with no prefix, the prefix is required when you need to map properties under the prefix, but refreshErrors is the property you want to map and not the prefix. The below code works fine. I have refactored a bit :

properties file:

    refresh-errors:
      -
        record-status: "Error"
        error-code: "502 Bad Gateway"
        error-message: "AWS service is tempoarily not available. ESS has been notified. Please try refreshing again after the service becomes available."
      -
        record-status: "Error"
        error-code: "503 Service Temporarily Unavailable"
        error-message: "AWS service is tempoarily not available. ESS has been notified. Please try refreshing again after the service becomes available."

PropertiesMapperClass :

@Data
@Component
@ConfigurationProperties
public class RefreshErrorsProperties {
    private List<RefreshErrors> refreshErrors = new ArrayList<>();

    @Data
    public static class RefreshErrors {
        private String errorCode;
        private String recordStatus;
        private String errorMessage;
    }
}

Upvotes: 1

Related Questions