Jhipster Health Endpoint fails when mailserver not connected - spring-boot

JHipster / Spring boot provides a nice endpoint /management/health, where it aggregates health information for subsystems like db, disk, and mail.
Unfortunately, when the connection to the mail server fails, the whole endpoint fails. So you do not get information what has failed.
I get a strack trace like this:
o.s.b.a.health.MailHealthIndicator : Health check failed
com.sun.mail.util.MailConnectException: Couldn't connect to host, port: XXXX, NNNN25025; timeout -1
...
at org.springframework.boot.actuate.health.MailHealthIndicator.doHealthCheck(MailHealthIndicator.java:40)
at org.springframework.boot.actuate.health.AbstractHealthIndicator.health(AbstractHealthIndicator.java:43)
at org.springframework.boot.actuate.health.CompositeHealthIndicator.health(CompositeHealthIndicator.java:68)
at org.springframework.boot.actuate.endpoint.HealthEndpoint.invoke(HealthEndpoint.java:85)
at org.springframework.boot.actuate.endpoint.mvc.HealthMvcEndpoint.getCurrentHealth(HealthMvcEndpoint.java:177)
at org.springframework.boot.actuate.endpoint.mvc.HealthMvcEndpoint.getHealth(HealthMvcEndpoint.java:166)
at org.springframework.boot.actuate.endpoint.mvc.HealthMvcEndpoint.invoke(HealthMvcEndpoint.java:143)
This is spring boot 1.5.9
Where should I fix this, so that the exception is catched and instead a an error status is returned?

You have to turn on your SMTP server or disable checks to it.
To disable checks to SMTP server:
management.health.mail.enabled=false
To disable checks to all server:
management.health.defaults.enabled=false
for more information, see http://www.briansjavablog.com/2017/09/health-checks-metric-s-more-with-spring.html
I believe you can handle this error with the ExceptionHandler for 1.5.9 version of Spring Boot since the newer version there is no such problem:
#ControllerAdvice
public class ExceptionController {
#ExceptionHandler(MailConnectException.class)
public ResponseEntity<?> mailExceptionHandler(MailConnectException e) {
// Do your treatment ...
} ...
}

Related

Spring Boot LDAP - Eror code 80 when trying to auth users

I am trying to auth users through secured adlds server from a spring boot application, and I am facing an issue for 2 weeks now, and no solutions found in the internet worked for me.
First I had an error that says that I need to bind the authentication before successful operation. I added the right properties to the context source but now I am getting an error code 80 which gives me no clues on the error.
Here is my code:
Application.yml
spring:
ldap:
url: ldaps://<hostname>:636
base: DC=<dc>>,DC=<dc>
username: CN=<cn>>,OU=Privileged,OU=<ou>,OU=<ou>,OU=<ou>,DC=<dc>,DC=<dc>
password: <secret>
base-environment:
com.sun.jndi.ldap.connect.timeout: 500
management:
health:
ldap:
enabled: false
Configuration.java
#Bean
#DependsOn("frameworkInstance")
public LdapContextSource contextSource() {
LdapContextSource contextSource = new LdapContextSource();
contextSource.setUrl("ldaps://<hostname>:636");
contextSource.setBase("<base>");
contextSource.setUserDn("CN=<cn>,OU=<ou>>,OU=<ou>>,OU=<ou>>,OU=<ou>,DC=<dc>,DC=<dc>>");
contextSource.setPassword("<secret>");
contextSource.afterPropertiesSet();
return contextSource;
}
#Bean
#DependsOn("frameworkInstance")
public LdapTemplate ldapTemplate() {
return new LdapTemplate(contextSource());
}
My auth process :
Filter filter = new EqualsFilter("cn", "<cn>");
ldapTemplate.authenticate(LdapUtils.emptyLdapName(), filter.encode(), "<secret>");
The error code is :
Uncategorized exception occured during LDAP processing; nested exception is javax.naming.NamingException: [LDAP: error code 80 - 80090304: LdapErr: DSID-0C090447, comment: AcceptSecurityContext error, data 20ee, v3839\u0000]
I tried everything for a couple of days but nothing ... The account used for the "bind" and for the authentication is the same, to ensure that the auth will be succesfull. Keep in mind that the words between chevrons are hidden because of production environment, I am not allowed to display credentials, etc.
Do you have please any clues to resolve that issue ? it's very critical
Best regards,
In the error message, the data 20ee indicates the Windows System Error Code. According to the Microsoft documentation, that is:
ERROR_DS_INTERNAL_FAILURE
8430 (0x20EE)
The directory service encountered an internal failure.
I don't think that indicates any problem with your code. It sounds more like a problem with your Active Directory environment.
Have you tried connecting via regular LDAP rather than LDAPS? (ldap://<hostname>). If that works, then it would indicate a problem with the LDAPS configuration.
As a side note, if you indicate ldaps:// in the path, you don't need to include :636, since that is the default LDAPS port.

Not able to resolve feign client name from application yml

I have a spring boot app and i am trying to use feign client to make a request to an endpoint but its not able to resolve feign client name from application yml.
My application yml has following code :
ribbon:
eureka:
enabled: false
beacon:
ribbon:
isSecure: true
listOfServers: https://beacon.org
My interface look like this :
#FeignClient("beacon")
public interface BeaconClient {
#GetMapping("/api/organizations")
List<Org> getOrgs();
}
I am getting an error 500 internal server error because i see that it making a request to http://beacon/api/organizations endpoint instead of https://beacon.org/api/organizations
Your code is correct. The default feign Logger is misleading. http://beacon/.. that you see in the log isn't indicative of actual url that is being called. The actual request is resolved with https://beacon.org/...

Authentication with Spring-Boot-Admin and Eureka discovery

SBA version 2.0.1
Spring-Cloud Finchley.RELEASE
I have some services registered in Eureka. The services are Spring-Boot apps, and have their actuators secured by HTTP basic auth. The service actuators are at /actuator. The services are working and I can interact with their actuators via Postman and curl. SBA connects to Eureka and discovers the services, but they are always in a down (red) state, except for the SBA application itself, which is shown just fine as green in the SBA console, and I am able to click on it and see it's properties.
When I click on one of the service instances, I am prompted for credentials. I'm not sure what credentials to use, so I use the credentials for the service actuator. I already have these credentials in the metadata-map as shown in the docs, but I am still prompted for credentials anyway. This always results in showing the Whitelabel Error Page, with an error message like this:
Mon Jun 25 12:40:57 CDT 2018 There was an unexpected error
(type=Method Not Allowed, status=405). Request method 'POST' not
supported
Though I note the url for that error is apparently on the SBA instance intself, not the remote service. The url decodes to this: http://localhost:8080/#/instances/9207aa5fc06b/
But I see this in the log for the service, so apparently an unauthenticated request is making it to the remove service:
[2018-06-25 12:16:54.242] - DEBUG - [http-nio-8380-exec-7]
[AUTHENTICATION_SERVICE_DEV,8dc8165d4f77be7c,8dc8165d4f77be7c,false]
--- [nio-8380-exec-7] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Written [{timestamp=Mon Jun 25 12:16:54 CDT 2018, status=401,
error=Unauthorized, message=Unauthorized, path=/actuator/health}] as
"application/vnd.spring-boot.actuator.v2+json" using
[org.springframework.http.converter.json.MappingJackson2HttpMessageConverter#30c8681]
And this in the SBA log:
2018-06-25 12:39:40.884 ERROR [SERVICES_ADMIN_CONSOLE_LOCAL,,,] 20728
--- [nio-8080-exec-8] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path
[] threw exception
java.io.IOException: An established connection was aborted by the
software in your host machine
This is the root of my confusion, I'm not sure what credentials I need or even what I am authenticating to. I have provided the credentials to remote service in properties as well as in the login form, and it doesn't work.
When I click on the SBA application in the SBA console, it works as expected. So this seems to be related to authenticating to a remote actuator, but I can't figure out what the problem is.
Server:
#Configuration
#EnableAutoConfiguration
#EnableEurekaClient
#EnableAdminServer
public class ServiceAdmin {
public static void main(String[] args) {
SpringApplication.run(ServiceAdmin.class, args);
}
#Configuration
public static class SecurityPermitAllConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().permitAll()
.and().csrf().disable();
}
}
}
SBA Config:
management.endpoints.web.exposure.include=*
management.endpoint.health.show-details=always
management.info.git.mode=full
management.endpoint.shutdown.enabled=true
spring.security.user.name=actuator
spring.security.user.password=password
spring.security.user.roles=ACTUATOR
eureka.instance.leaseRenewalIntervalInSeconds=10
eureka.instance.health-check-url-path=/actuator/health
eureka.instance.metadata-map.user.name=actuator
eureka.instance.metadata-map.user.password=password
eureka.client.registryFetchIntervalSeconds=5
eureka.client.serviceUrl.defaultZone=http://svcregistry1.mycompany.com/eureka/,http://svcregistry2.mycompany.com
For anyone coming to this question, being as puzzled as I, to clear up this answer.
I'm having Eureka and Springboot admin server/ui in the same application
All the services that will register into eureka AND springboot admin, will need their own /actuator credentials present as metadata :
eureka.instance.metadata-map.user.name = ${endpoints.user.name}
eureka.instance.metadata-map.user.password = ${endpoints.user.password}
This post cleared up a few things.
https://zoltanaltfatter.com/2018/05/15/spring-cloud-discovery-with-spring-boot-admin/
The problem here was I failed to understand the docs. The eureka credentials in the metadataMap have to be provided by the monitored application at registration time. Not provided in the SBA config.

java.net.UnknownHostException during Eureka service discovery

According to this blog https://spring.io/blog/2015/07/14/microservices-with-spring
Was able to run the application without any issues. In this order:
java -jar microservice-demo-0.0.1-SNAPSHOT.jar registration 1111
java -jar microservice-demo-0.0.1-SNAPSHOT.jar accounts 2222
java -jar microservice-demo-0.0.1-SNAPSHOT.jar web 3333
But when trying to hit any service through the web application (http://localhost:3333/) which uses the http://ACCOUNTS-SERVICE url to access any accounts service endpoints like http://ACCOUNTS-SERVICE/accounts/123456789 I'm getting an error response:
Response Status: 500 (Internal Server Error)
Cause: org.springframework.web.client.ResourceAccessException I/O error on GET request for "http://ACCOUNTS-SERVICE/accounts/123456789": ACCOUNTS-SERVICE; nested exception is java.net.UnknownHostException: ACCOUNTS-SERVICE
When I provide the real address (http://localhost:2223/) of the accounts service to the web server instead of the http://ACCOUNTS-SERVICE everything works properly but there is no service discovery in this case.
The source code is stored at: https://github.com/paulc4/microservices-demo
This issue was due to the RestTemplate was no longer auto-created in the Brixton release-train (Spring Cloud 1.1.0.RELEASE), so the RestTemplate could not resolve properly the http://ACCOUNTS-SERVICE url using the service discovery server.
Was able to fix this issue after declaring a RestTemplate bean with #LoadBalanced as follows:
#Bean
#LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}

Grizzly / Glassfish - Cant establish websockets handshake

I'm trying to get WebSockets working on top of Grizzly / Glassfish. I've cloned the sample WebSockets chat application, built it and deployed it to Glassfish 3.1.2. However, I cannot get WebSockets to connect. The WebSockets handshake is failing because I'm getting a 405 (Method Not Allowed) response. This makes sense because of what is in the Servlet:
public class WebSocketsServlet extends HttpServlet {
private final ChatApplication app = new ChatApplication();
#Override
public void init(ServletConfig config) throws ServletException {
WebSocketEngine.getEngine().register(app);
}
#Override
public void destroy() {
WebSocketEngine.getEngine().unregister(app);
}
}
There is no doGet method specified, so I'm wondering if there is more configuration required somewhere, or if you need to implement the handshake logic in the servlet doGet method yourself?
I was trying to use grizzly-websockets-chat-2.1.9.war on glassfish 3.1.2 and getting same error.
Followed the advice from this page http://www.java.net/forum/topic/glassfish/glassfish/websocket-connection-not-establishing-glasshfish-server-how-fix-it-0
which states to use the version found here (I would think the version would indicate it being older however the time stamps on the files are Jan 30 2012):
WAR
https://maven.java.net/service/local/artifact/maven/redirect?r=releases&g=com.sun.grizzly.samples&a=grizzly-websockets-chat&v=1.9.46&e=war
SOURCES
https://maven.java.net/service/local/artifact/maven/redirect?r=releases&g=com.sun.grizzly.samples&a=grizzly-websockets-chat&v=1.9.46&e=jar&c=sources
By using that war everything works.
For those that like using the glassfish web console. You can enable web-sockets by:
Configurations > server-config > Network Config > Protocols > http-listener-1, then HTTP tab > Scroll to bottom and check off Websockets Support.
Note Configurations > default-config > ... also has the same options
You might find this more continent that keeping a terminal around.
It appears you haven't enabled websocket support (disabled by default).
Issue the following command and then restart the server:
asadmin set configs.config.server-config.network-config.protocols.protocol.http-listener-1.http.websockets-support-enabled=true
You can replace http-listener-1 with whatever http-listener you wish to enable WS support for.

Resources