[ 
https://issues.apache.org/jira/browse/CAMEL-22936?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Michael Kroll updated CAMEL-22936:
----------------------------------
    Description: 
Hi there,

after activating the healthcheck endpoint in our camel spring boot application 
with a dozen routes, i noticed the following error when calling the endpoint:
{code:java}
11:56:56.981 [http-nio-8081-exec-3] WARN  
o.a.c.s.b.a.h.CamelHealthCheckIndicator Health check failed
java.lang.IllegalArgumentException: 'value' must not be null
     at org.springframework.util.Assert.notNull(Assert.java:181)
     at 
org.springframework.boot.actuate.health.Health$Builder.withDetail(Health.java:247)
     at 
org.apache.camel.spring.boot.actuate.health.CamelHealthHelper.lambda$applyHealthDetail$1(CamelHealthHelper.java:63)
{code}
Looking at the last line in this stacktrace, this is the source in 4.14.4:
{code:java}
builder.withDetail("error.message", error.getMessage());
{code}
Now, error is a Throwable. The javadoc/contract of Throwable#getMessage() says:
{quote}Returns: the detail message string of this Throwable instance {*}(which 
may be null){*}.
{quote}
I highlighted the important part.

Now let's have a look at the called 
org.springframework.boot.actuate.health.Health$Builder.withDetail() method:
{code:java}
                public Builder withDetail(String key, Object value) {
                        Assert.notNull(key, "'key' must not be null");
                        Assert.notNull(value, "'value' must not be null");
                        this.details.put(key, value);
                        return this;
                }
{code}
Both parameters are not allowed to be null. Which may crash when 
Throwable#getMessage returns null and is used as value.

Now for the bad news: the resulting RuntimeException not only breaks the health 
report on a single component. But it is thrown into the caller 
org.apache.camel.spring.boot.actuate.health.CamelHealthCheckIndicator#doHealthCheck,
 where it {*}aborts the whole CamelHealthCheckIndicator, for all camel 
components{*}.

For me, this is pretty serious: one Consumer that throws an exception without 
message is enough for the whole healthceck result to collapse.

I think the two colliding contracts above are enough to declare this as a bug, 
i hope you think so, too. Sadly i don't have time to build a reproducer.
But just to give an example, my WebDavConsumer breaks with the following 
stacktrace:
{code:java}
11:56:55.062 [http-nio-8081-exec-1] WARN  
o.a.c.s.b.a.h.r.CamelReadinessStateHealthIndicator null
org.apache.http.client.ClientProtocolException 
at 
org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:187)
 
at 
org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:72)
 
at 
org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:221)
 
at 
org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:165)
 
at com.github.sardine.impl.SardineImpl.execute(SardineImpl.java:1080) 
at com.github.sardine.impl.SardineImpl.execute(SardineImpl.java:1049) 
at com.github.sardine.impl.SardineImpl.propfind(SardineImpl.java:424) 
at com.github.sardine.impl.SardineImpl.list(SardineImpl.java:357) 
at com.github.sardine.impl.SardineImpl.list(SardineImpl.java:347) 
at com.github.sardine.impl.SardineImpl.list(SardineImpl.java:341) 
at 
org.example.webdav.adapter.AdapterFactory$SardineWrapper.list(AdapterFactory.java:72)
 
at 
org.example.webdav.component.WebDavConsumer.getWebDavFiles(WebDavConsumer.java:85)
 
at org.example.webdav.component.WebDavConsumer.poll(WebDavConsumer.java:37)
{code}
{*}Proposed fix{*}:
{code:java}
- builder.withDetail("error.message", error.getMessage());
+ builder.withDetail("error.message", error.getMessage() == null ? "" : 
error.getMessage());
{code}
 

As a side note, why does calling the health endpoint make all my 
org.apache.camel.support.ScheduledPollConsumer implementations poll? They have 
a startupDelay configured, which is broken by calling the health endpoint. 
Sounds strange to me.

  was:
Hi there,

when activating the healthcheck endpoint in our camel spring boot application 
with a dozen routes, i noticed the following error:
{code:java}
11:56:56.981 [http-nio-8081-exec-3] WARN  
o.a.c.s.b.a.h.CamelHealthCheckIndicator Health check failed
java.lang.IllegalArgumentException: 'value' must not be null
     at org.springframework.util.Assert.notNull(Assert.java:181)
     at 
org.springframework.boot.actuate.health.Health$Builder.withDetail(Health.java:247)
     at 
org.apache.camel.spring.boot.actuate.health.CamelHealthHelper.lambda$applyHealthDetail$1(CamelHealthHelper.java:63)
{code}
Looking at the last line in this stacktrace, this is the source in 4.14.4:
{code:java}
builder.withDetail("error.message", error.getMessage());
{code}
Now, error is a Throwable. The javadoc/contract of Throwable#getMessage() says:
{quote}Returns: the detail message string of this Throwable instance {*}(which 
may be null){*}.
{quote}
I highlighted the important part.

Now let's have a look at the called 
org.springframework.boot.actuate.health.Health$Builder.withDetail() method:
{code:java}
                public Builder withDetail(String key, Object value) {
                        Assert.notNull(key, "'key' must not be null");
                        Assert.notNull(value, "'value' must not be null");
                        this.details.put(key, value);
                        return this;
                }
{code}
Both parameters are not allowed to be null. Which may crash when 
Throwable#getMessage returns null and is used as value.

Now for the bad news: the resulting RuntimeException not only breaks the health 
report on a single component. But it is thrown into the caller 
org.apache.camel.spring.boot.actuate.health.CamelHealthCheckIndicator#doHealthCheck,
 where it {*}aborts the whole CamelHealthCheckIndicator, for all camel 
components{*}.

For me, this is pretty serious: one Consumer that throws an exception without 
message is enough for the whole healthceck result to collapse.

I think the two colliding contracts above are enough to declare this as a bug, 
i hope you think so, too. Sadly i don't have time to build a reproducer.
But just to give an example, my WebDavConsumer breaks with the following 
stacktrace:
{code:java}
11:56:55.062 [http-nio-8081-exec-1] WARN  
o.a.c.s.b.a.h.r.CamelReadinessStateHealthIndicator null
org.apache.http.client.ClientProtocolException 
at 
org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:187)
 
at 
org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:72)
 
at 
org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:221)
 
at 
org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:165)
 
at com.github.sardine.impl.SardineImpl.execute(SardineImpl.java:1080) 
at com.github.sardine.impl.SardineImpl.execute(SardineImpl.java:1049) 
at com.github.sardine.impl.SardineImpl.propfind(SardineImpl.java:424) 
at com.github.sardine.impl.SardineImpl.list(SardineImpl.java:357) 
at com.github.sardine.impl.SardineImpl.list(SardineImpl.java:347) 
at com.github.sardine.impl.SardineImpl.list(SardineImpl.java:341) 
at 
org.example.webdav.adapter.AdapterFactory$SardineWrapper.list(AdapterFactory.java:72)
 
at 
org.example.webdav.component.WebDavConsumer.getWebDavFiles(WebDavConsumer.java:85)
 
at org.example.webdav.component.WebDavConsumer.poll(WebDavConsumer.java:37)
{code}
{*}Proposed fix{*}:
{code:java}
- builder.withDetail("error.message", error.getMessage());
+ builder.withDetail("error.message", error.getMessage() == null ? "" : 
error.getMessage());
{code}
 

As a side note, why does calling the health endpoint make all my 
org.apache.camel.support.ScheduledPollConsumer implementations poll? They have 
a startupDelay configured, which is broken by calling the health endpoint. 
Sounds strange to me.


> camel health check breaks if one component has exception without message
> ------------------------------------------------------------------------
>
>                 Key: CAMEL-22936
>                 URL: https://issues.apache.org/jira/browse/CAMEL-22936
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-spring-boot
>    Affects Versions: 4.14.4
>            Reporter: Michael Kroll
>            Priority: Major
>
> Hi there,
> after activating the healthcheck endpoint in our camel spring boot 
> application with a dozen routes, i noticed the following error when calling 
> the endpoint:
> {code:java}
> 11:56:56.981 [http-nio-8081-exec-3] WARN  
> o.a.c.s.b.a.h.CamelHealthCheckIndicator Health check failed
> java.lang.IllegalArgumentException: 'value' must not be null
>      at org.springframework.util.Assert.notNull(Assert.java:181)
>      at 
> org.springframework.boot.actuate.health.Health$Builder.withDetail(Health.java:247)
>      at 
> org.apache.camel.spring.boot.actuate.health.CamelHealthHelper.lambda$applyHealthDetail$1(CamelHealthHelper.java:63)
> {code}
> Looking at the last line in this stacktrace, this is the source in 4.14.4:
> {code:java}
> builder.withDetail("error.message", error.getMessage());
> {code}
> Now, error is a Throwable. The javadoc/contract of Throwable#getMessage() 
> says:
> {quote}Returns: the detail message string of this Throwable instance 
> {*}(which may be null){*}.
> {quote}
> I highlighted the important part.
> Now let's have a look at the called 
> org.springframework.boot.actuate.health.Health$Builder.withDetail() method:
> {code:java}
>               public Builder withDetail(String key, Object value) {
>                       Assert.notNull(key, "'key' must not be null");
>                       Assert.notNull(value, "'value' must not be null");
>                       this.details.put(key, value);
>                       return this;
>               }
> {code}
> Both parameters are not allowed to be null. Which may crash when 
> Throwable#getMessage returns null and is used as value.
> Now for the bad news: the resulting RuntimeException not only breaks the 
> health report on a single component. But it is thrown into the caller 
> org.apache.camel.spring.boot.actuate.health.CamelHealthCheckIndicator#doHealthCheck,
>  where it {*}aborts the whole CamelHealthCheckIndicator, for all camel 
> components{*}.
> For me, this is pretty serious: one Consumer that throws an exception without 
> message is enough for the whole healthceck result to collapse.
> I think the two colliding contracts above are enough to declare this as a 
> bug, i hope you think so, too. Sadly i don't have time to build a reproducer.
> But just to give an example, my WebDavConsumer breaks with the following 
> stacktrace:
> {code:java}
> 11:56:55.062 [http-nio-8081-exec-1] WARN  
> o.a.c.s.b.a.h.r.CamelReadinessStateHealthIndicator null
> org.apache.http.client.ClientProtocolException 
> at 
> org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:187)
>  
> at 
> org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:72)
>  
> at 
> org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:221)
>  
> at 
> org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:165)
>  
> at com.github.sardine.impl.SardineImpl.execute(SardineImpl.java:1080) 
> at com.github.sardine.impl.SardineImpl.execute(SardineImpl.java:1049) 
> at com.github.sardine.impl.SardineImpl.propfind(SardineImpl.java:424) 
> at com.github.sardine.impl.SardineImpl.list(SardineImpl.java:357) 
> at com.github.sardine.impl.SardineImpl.list(SardineImpl.java:347) 
> at com.github.sardine.impl.SardineImpl.list(SardineImpl.java:341) 
> at 
> org.example.webdav.adapter.AdapterFactory$SardineWrapper.list(AdapterFactory.java:72)
>  
> at 
> org.example.webdav.component.WebDavConsumer.getWebDavFiles(WebDavConsumer.java:85)
>  
> at org.example.webdav.component.WebDavConsumer.poll(WebDavConsumer.java:37)
> {code}
> {*}Proposed fix{*}:
> {code:java}
> - builder.withDetail("error.message", error.getMessage());
> + builder.withDetail("error.message", error.getMessage() == null ? "" : 
> error.getMessage());
> {code}
>  
> As a side note, why does calling the health endpoint make all my 
> org.apache.camel.support.ScheduledPollConsumer implementations poll? They 
> have a startupDelay configured, which is broken by calling the health 
> endpoint. Sounds strange to me.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to