springBootVersion = '2.1.1.RELEASE'
springCloudVersion = 'Greenwich.RC2'
Using org.springframework.boot.actuate.health.Health
as DTO:
@FeignClient("foo-service")
public interface FooClient {
@GetMapping(path = "actuator/health", produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
Health health();
}
leads to this error:
feign.codec.DecodeException: Type definition error: [simple type, class org.springframework.boot.actuate.health.Health]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `org.springframework.boot.actuate.health.Health` (no Creators, like default construct, exist): no default no-arguments constructor found
at [Source: (PushbackInputStream); line: 2, column: 3]
at feign.SynchronousMethodHandler.decode(SynchronousMethodHandler.java:180) ~[feign-core-10.1.0.jar:na]
at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:140) ~[feign-core-10.1.0.jar:na]
at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:78) ~[feign-core-10.1.0.jar:na]
at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:103) ~[feign-core-10.1.0.jar:na]
at com.sun.proxy.$Proxy144.health(Unknown Source) ~[na:na]
Comment From: snicoll
Feign usage is not handled in this project so please do not report an issue against it here. Health
is not a DTO and is not supposed to be used as such. If you have more questions, please ask on StackOverflow: as mentioned in the guidelines for contributing, we prefer to use GitHub issues only for bugs and enhancements.
Comment From: octopus-prime
Health
is not a DTO and is not supposed to be used as such.
@JsonInclude(Include.NON_EMPTY)
public final class Health {
private final Status status;
private final Map<String, Object> details;
/**
* Create a new {@link Health} instance with the specified status and details.
* @param builder the Builder to use
*/
private Health(Builder builder) {
Assert.notNull(builder, "Builder must not be null");
this.status = builder.status;
this.details = Collections.unmodifiableMap(builder.details);
}
/**
* Return the status of the health.
* @return the status (never {@code null})
*/
@JsonUnwrapped
public Status getStatus() {
return this.status;
}
Note the JSON annotaions! May be it's a DTO and produces JSON like
{
"status": "DOWN"
}
when calling the actuator health endpoint?!
Comment From: octopus-prime
Workaround because org.springframework.boot.actuate.health.Health
is not reusable:
@Data
public class Health {
private Status status;
}
But the own Health class is not usable in e.g. HealthAggregator
.
Comment From: TehBakker
Was surprised to have the same issue when fetching from RestTemplate with jackson.
org.springframework.http.converter.HttpMessageConversionException: Type definition error: [simple type, class org.springframework.boot.actuate.health.Health]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of
org.springframework.boot.actuate.health.Health(no Creators, like default construct, exist): no default no-arguments constructor found
Feels weird to have to go through a homemade bean to be able to fetch subsystems health in tbheir HealthIndicator no?
Comment From: wilkinsona
@TehBakker As @snicoll said above, Health
isn't intended to be used as a client-side DTO.