An Interest In:
Web News this Week
- April 15, 2024
- April 14, 2024
- April 13, 2024
- April 12, 2024
- April 11, 2024
- April 10, 2024
- April 9, 2024
Configurando o Spring Boot Admin: Server e Client
Existem vrias formas de se monitorar sistemas distribudos e uma que me agrada bastante pela simplicidade de configurao e confiabilidade o Spring Boot Admin.
Nesse tutorial criaremos duas aplicaes utilizando o Spring Boot, uma que ser o servidor de monitoramento e a outra, o cliente que dever se registrar para ser monitorado.
Tambm vamos aproveitar para implementar uma camada de segurana utilizando o Spring Security e com o #Maven, poderemos fazer o build das aplicaes para serem executadas individualmente.
Verses utilizadas
- Spring Boot: 2.7.10
- Spring Boot Admin Server: 2.7.10
- Spring Boot Admin Client: 2.7.10
Configurando o Servidor
Crie um projeto utilizando o Spring Initilizr com as seguintes dependncias:
- Starter Web
- Starter Security
- Admin Starter Server
Confira se as dependncias relacionadas ao Spring Boot Admin foram adicionadas:
...<dependency> <groupId>de.codecentric</groupId> <artifactId>spring-boot-admin-starter-server</artifactId></dependency><dependency> <groupId>de.codecentric</groupId> <artifactId>spring-boot-admin-server-ui</artifactId></dependency>...
Adicione a anotao @EnableAdminServer em alguma classe de configurao:
...@EnableAdminServer@SpringBootApplicationpublic class SpringBootAdminServerApplication { public static void main(String[] args) { SpringApplication.run(SpringBootAdminServerApplication.class, args); }}
Configure o comportamento da aplicao utilizando o arquivo application.yaml. Como adicionamos uma camada de segurana, devemos criar um nome de usurio e senha para logarmos no servidor e tambm ser necessrio configurar o login para comunicao entre servidor e cliente.
server: port: 8081 servlet: context-path: /admin-consolespring: security: user: # Configura o login do servidor. name: ${SBA_SERVER_USERNAME} password: ${SBA_SERVER_PASSWORD} boot: admin: client: # Necessrios para que o cliente possa se registrar na api do servidor protegido. username: ${SBA_SERVER_USERNAME} password: ${SBA_SERVER_PASSWORD} instance: metadata: user: # Necessrios para que o servidor possa acessar os endpoints protegidos do cliente. name: ${SBA_CLIENT_USERNAME} password: ${SBA_CLIENT_PASSWORD}# LOGlogging: file: name: ${user.home}/logs/admin/sba-server.log level: root: info web: info dev.marksduarte: info org.springframework: info charset: file: utf-8
Agora vamos configurar o Spring Security criando uma classe e desabilitando o proxy dos beans na anotao @Configuration(proxyBeanMethods = false), pois como vamos trabalhar com @Bean autocontido, podemos evitar o processamento da subclasse CGLIB.
Tambm vamos permitir os acessos s rotas de login e assets e desabilitar a proteo CSRF paras o mtodos HTTP POST e HTTP DELETE nas instncias dos clientes.
package dev.marksduarte.springbootadminserver;import de.codecentric.boot.admin.server.config.AdminServerProperties;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.http.HttpMethod;import org.springframework.security.config.Customizer;import org.springframework.security.config.annotation.web.builders.HttpSecurity;import org.springframework.security.web.SecurityFilterChain;import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;import org.springframework.security.web.csrf.CookieCsrfTokenRepository;import org.springframework.security.web.util.matcher.AntPathRequestMatcher;@Configuration(proxyBeanMethods = false)public class SecurityConfig { private final AdminServerProperties adminServer; public SecurityConfig(AdminServerProperties adminServer) { this.adminServer = adminServer; } @Bean protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception { SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler(); successHandler.setTargetUrlParameter("redirectTo"); successHandler.setDefaultTargetUrl(this.adminServer.path("/")); http.authorizeHttpRequests(authorizeRequests -> authorizeRequests .requestMatchers(new AntPathRequestMatcher(this.adminServer.path("/assets/**"))) .permitAll() .requestMatchers(new AntPathRequestMatcher(this.adminServer.path("/login"))) .permitAll() .anyRequest() .authenticated()) .formLogin(formLogin -> formLogin.loginPage(this.adminServer.path("/login")) .successHandler(successHandler)) .logout(logout -> logout.logoutUrl(this.adminServer.path("/logout"))) .httpBasic(Customizer.withDefaults()) .csrf(csrf -> csrf.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) .ignoringRequestMatchers( new AntPathRequestMatcher(this.adminServer.path("/instances"), HttpMethod.POST.toString()), new AntPathRequestMatcher(this.adminServer.path("/instances/*"), HttpMethod.DELETE.toString()), new AntPathRequestMatcher(this.adminServer.path("/actuator/**")))); return http.build(); }}
Pronto, agora s rodar a aplicao e conferir se o Admin Server est acessvel atravs do endereo http://localhost:8081/admin-console e logar com o usurio e senha informados na configurao.
Configurando o Cliente
Crie um projeto utilizando o Spring Initilizr com as seguintes dependncias:
- Starter Web
- Starter Actuator
- Starter Security
- Admin Starter Client
Confira no seu arquivo pom.xml, se a dependncia do Spring Boot Admin Client e Spring Actuator foram adicionadas:
...<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency> <groupId>de.codecentric</groupId> <artifactId>spring-boot-admin-starter-client</artifactId> <version>2.7.10</version></dependency>...
Agora vamos configurar o sistema comeando pelo arquivo application.yaml:
## INFO ENDPOINT## Aqui configuramos as informaes sobre o sistema, como nome, descrio, verso e etc.info: name: Spring Boot Admin Client description: Sistema Cliente version: @project.version@server: port: 8080 servlet: context-path: /admin-clientspring: # Configurao bsica do Spring Security. security: user: name: ${SBA_CLIENT_USERNAME} password: ${SBA_CLIENT_PASSWORD} boot: admin: client: enabled: true # URL do servidor que o cliente deve se registrar. url: http://localhost:8081/admin-console username: ${SBA_SERVER_USERNAME} password: ${SBA_SERVER_PASSWORD} instance: # URL base para calcular o service-url com o qual se registrar. O caminho inferido em tempo de execuo e anexado url base. service-base-url: http://localhost:8080 # Essas informaes so passadas ao servidor para que ele possa fazer o acesso aos endpoints do sistema cliente. metadata: user: name: ${SBA_SERVER_USERNAME} password: ${SBA_SERVER_PASSWORD} auto-deregistration: true## APPapp: cors-origins: - http://localhost cors-methods: - GET - POST - PUT - DELETE - OPTIONS cors-headers: - Authorization - Content-Type - Content-Length - X-Requested-With## ACTUATORmanagement: info: env: # Desde o Spring Boot 2.6, o env info desabilitado por padro. enabled: true endpoint: health: show-details: ALWAYS enabled: true shutdown: enabled: true logfile: enabled: true external-file: logs/sba-client.log endpoints: web: exposure: # Liberamos todos os endpoints, mas lembre-se, em produo no se deve fazer isso. include: "*" cors: allowed-headers: ${app.cors-headers} allowed-methods: ${app.cors-methods} allowed-origins: ${app.cors-origins}## LOGlogging: file: name: logs/sba-client.log path: logs level: root: info web: info dev.marksduarte: info charset: file: utf-8 logback: rollingpolicy: clean-history-on-start: true max-file-size: 10MB
Para simplificar, vamos habilitar todas as requisies para os endpoints do "/actuator/**":
...@EnableWebSecurity@Configurationpublic class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.csrf() .disable() .authorizeHttpRequests() .antMatchers("/actuator/**") .permitAll(); return http.build(); }}
Bom, isso j suficiente para registar nossa aplicao cliente no servidor.
Mas caso acontea alguma exceo do tipo: HttpMessageNotWritableException ou um response error HTTP 416 ao tentar acessar o arquivo de log, no se assuste, isso pode acontecer caso seu sistema tenha alguma classe de configurao do Jackson que estenda WebMvcConfigurationSupport.
Nesse caso, essa classe pode estar desativando a instanciao dos Beans com as configuraes padres do Spring Boot.
Para corrigir esse tipo de problema, podemos criar um Bean customizado e substituir a configurao padro criada na inicializao do sistema.
@Configurationpublic class JacksonConfig extends WebMvcConfigurationSupport { private final Jackson2ObjectMapperBuilder builder = Jackson2ObjectMapperBuilder.json(); private static final List<MediaType> MEDIA_TYPE_LIST = List.of( MediaType.ALL, MediaType.parseMediaType("application/vnd.spring-boot.actuator.v2+json") ); @Bean public MappingJackson2HttpMessageConverter customMappingJackson2HttpMessageConverter() { MappingJackson2HttpMessageConverter converter = actuatorConverter(); converter.setSupportedMediaTypes(MEDIA_TYPE_LIST); return converter; } private MappingJackson2HttpMessageConverter actuatorConverter() { return new MappingJackson2HttpMessageConverter(builder.build()) { @Override protected boolean canWrite(MediaType mediaType) { // O mtodo super, retorna true se for null. // Assim evitamos a exceo _HttpMessageNotWritableException_ caso o Content-Type 'null' seja enviado. return mediaType != null && super.canWrite(mediaType); } }; } @Override protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) { /* Remove somente o MappingJackson2HttpMessageConverterpadro e substitui pelo customMappingJackson2HttpMessageConverter. */ var defaultHttpConverterOpt = converters.stream() .filter(MappingJackson2HttpMessageConverter.class::isInstance) .findFirst(); defaultHttpConverterOpt.ifPresent(converters::remove); converters.add(customMappingJackson2HttpMessageConverter()); }}
Por enquanto s. At mais! ;)
Original Link: https://dev.to/marksduarte/configurando-o-spring-boot-admin-server-e-client-hld
Dev To
An online community for sharing and discovering great ideas, having debates, and making friendsMore About this Source Visit Dev To