Exemplo de aplicação reativa por mola (liberação de 14/01/2020)

Feliz Ano Novo atrasado, Comunidade Primavera!

Quando o próximo ano incrível de desenvolvimento e aprimoramento no ecossistema do Spring começar, quero compartilhar com você um exemplo atualizado de um aplicativo que demonstra parte do progresso feito no portfólio de projetos do Spring em relação ao suporte ao modelo de programação Reativa.

O aplicativo BookStore Service Broker de amostra foi atualizado para demonstrar a integração de vários projetos diferentes do Spring, incluindo o Spring Cloud Open Service Broker, o Spring Data, o Spring Security, o Spring HATEOAS e, é claro, o Spring WebFlux e o Spring Boot. Todos esses projetos têm versões do GA, incluindo suporte reativo e pronto para produção em seus próprios aplicativos e serviços.

Traduzido por @middle_java

Para simplificar, o próprio aplicativo funciona como um intermediário e como uma instância de serviço. Embora os próprios corretores sigam a API do Open Service Broker, os serviços que eles fornecem são definidos de maneira mais abstrata. Os serviços podem fazer ou ser quase tudo. No caso do nosso aplicativo, um novo conjunto de credenciais é criado para cada instância do serviço. Essas credenciais são usadas em solicitações para a instância de serviço. A URL da nova instância de serviço é configurada para a mesma rota para o broker. Portanto, credenciais são usadas para separar solicitações para diferentes instâncias de serviço. O objetivo era desenvolver um exemplo totalmente equipado que demonstre muitas partes do portfólio de projetos da Spring.

Spring Cloud Open Service Broker 3.1


O Spring Cloud Open Service Broker é uma plataforma para a criação de aplicativos Spring Boot que implementam a API do Open Service Broker e permite que os desenvolvedores forneçam serviços para aplicativos em execução em plataformas na nuvem, como Cloud Foundry, Kubernetes e OpenShift. A partir da versão 3.0, o Spring Cloud Open Service Broker suporta as estruturas da Web Spring WebFlux e Spring MVC usando tipos Reativos nas interfaces de controlador e serviço.

Para começar com o Spring Cloud Open Service Broker, inclua o iniciador do Spring Boot no seu aplicativo:

implementation('org.springframework.cloud:spring-cloud-starter-open-service-broker:3.1.0.RELEASE') 

Em seguida, implementamos ServiceInstateService e ServiceInstateBindingService . O código a seguir ilustra a API necessária. Consulte o aplicativo de amostra para obter detalhes completos.

 @Service public class BookStoreServiceInstanceService implements ServiceInstanceService { @Override public Mono < CreateServiceInstanceResponse > createServiceInstance( CreateServiceInstanceRequest request) { ... } @Override public Mono < GetServiceInstanceResponse > getServiceInstance( GetServiceInstanceRequest request) { ... } @Override public Mono < DeleteServiceInstanceResponse > deleteServiceInstance( DeleteServiceInstanceRequest request) { ... } } 

Spring data moore


Na família de projeto Spring Data , o suporte reativo foi originalmente introduzido no Spring Data Kay . O Spring Data R2DBC anunciou recentemente um lançamento do GA, mas o Spring Boot ainda não possui um lançamento do GA integrado ao Spring Data R2DBC. Este exemplo usa o MongoDB como o armazenamento de dados de backup.

Para iniciar o Reactive MongoDB, inclua o iniciador do Spring Boot no seu aplicativo:

 implementation('org.springframework.boot:spring-boot-starter-data-mongodb-reactive') 

Para demonstrar, adicione o servidor MongoDB interno:

 implementation('de.flapdoodle.embed:de.flapdoodle.embed.mongo') 

Em seguida, configure o repositório Jet:

 @Configuration @EnableReactiveMongoRepositories(basePackageClasses = { ServiceBrokerRepositoryPackageMarker.class, WebRepositoryPackageMarker.class }) public class ApplicationRepositoryConfiguration { } 

Por fim, defina ReactiveCrudRepository . A interface a seguir é um exemplo de um aplicativo de amostra:

 public interface ServiceInstanceRepository extends ReactiveCrudRepository < ServiceInstance, String > { } 

Spring security 5.2


O suporte reativo foi originalmente incluído no Spring Security 5, e a integração com o Spring Boot e o Spring Framework continua a evoluir.

Para usar o Spring Security, adicione o iniciador do Spring Boot:

 implementation('org.springframework.boot:spring-boot-starter-security') 

Em seguida, defina a configuração de segurança usando @EnableWebCardingSecurity . Este código ilustra como um aplicativo protege os pontos de extremidade do broker /v2 e /bookstars , que respondem a solicitações de instâncias de serviço:

 @Configuration @EnableWebFluxSecurity public class SecurityConfiguration { @Bean public SecurityWebFilterChain securityWebFilterChain( ServerHttpSecurity http) { return http .csrf().disable() .httpBasic() .and().authorizeExchange() .pathMatchers("/bookstores/**").authenticated() .pathMatchers("/v2/**").hasAuthority( SecurityAuthorities.ADMIN) .matchers(EndpointRequest.to("info", "health")).permitAll() .matchers(EndpointRequest.toAnyEndpoint()).hasAuthority( SecurityAuthorities.ADMIN) .and().build(); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } } 

Em seguida, implementamos ReactiveUserDetailsService :

 @Service public class RepositoryUserDetailsService implements ReactiveUserDetailsService { private final UserRepository userRepository; public RepositoryUserDetailsService(UserRepository userRepository) { this.userRepository = userRepository; } } 

Finalmente, os avaliadores de permissão não são suportados nos controladores WebFlux, mas podemos obter funcionalidades semelhantes chamando o bean na expressão SpEL e passando o objeto Authentication:

 @GetMapping("/{bookStoreId}") @PreAuthorize("hasAnyRole('ROLE_FULL_ACCESS','ROLE_READ_ONLY') and @bookStoreIdEvaluator.canAccessBookstore(authentication, #bookStoreId)") public Mono<ResponseEntity<BookStoreResource>> getBooks( @PathVariable String bookStoreId) { return bookStoreService.getBookStore(bookStoreId) .flatMap(this::createResponse); } 

Este exemplo analisa permissões para determinar se existe um identificador de livraria:

 public boolean canAccessBookstore(Authentication authentication, String bookStoreId) { return authentication.getAuthorities().stream() .filter(authority - > authority.getAuthority() .startsWith(BOOK_STORE_ID_PREFIX)) .map(authority - > { String serviceInstanceId = authority.getAuthority() .substring(BOOK_STORE_ID_PREFIX.length()); return serviceInstanceId.equals(bookStoreId); }) .findFirst() .orElse(true); } 

Spring HATEOAS 1.0


O Spring HATEOAS 1.0 GA foi lançado recentemente e inclui suporte reativo para visualizações de link e modelagem.

Adicione um HATEOAS Starter do Spring para ativar a configuração automática do Spring Boot. Como estamos criando o aplicativo reativo do Spring WebFlux, precisamos excluir o iniciador do Spring Web:

 implementation('org.springframework.boot:spring-boot-starter-hateoas') { exclude group: 'org.springframework.boot', module: 'spring-boot-starter-web' } 

Em seguida, você pode usar o WebFluxLinkBuilder para criar recursos da Hipermídia:

 public Mono < BookResource > toModel(Book book, String bookStoreId) { return Mono.just(new BookResource(book)) .flatMap(bookResource - > linkTo(methodOn( BookController.class).getBook(bookStoreId, book.getId())) .withSelfRel() .toMono() .flatMap(link - > Mono.just(bookResource.add(link))) .thenReturn(bookResource)); } 

Em seguida, você pode usar este recurso no corpo da resposta do controlador:

 return new BookStoreResourceAssembler().toModel(bookStore) .flatMap(bookStoreResource - > Mono.just(new ResponseEntity < > (bookStoreResource, HttpStatus.OK))); 

Framework 5.2


O Spring Framework 5 originalmente ofereceu Suporte Reativo no novo Spring WebFlux Web Framework. Além disso, o novo WebClient e WebTestClient incluem suporte para o uso e teste de aplicativos Spring WebFlux.

Para usá-los, basta adicionar os iniciantes do Spring Boot:

 implementation('org.springframework.boot:spring-boot-starter-webflux') testImplementation('org.springframework.boot:spring-boot-starter-test') { exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' } 

Por exemplo, use WebTestClient para testar a funcionalidade do controlador:

 this.client.get().uri("/bookstores/{bookStoreId}", bookStoreId) .accept(MediaType.APPLICATION_JSON) .exchange() .expectStatus().isEqualTo(HttpStatus.OK); 

Bota de mola 2.2


O Spring Boot integra todos esses projetos, oferecendo a configuração automática de suporte reativo no Spring WebFlux, Spring Data, Spring Security, Spring HATEOAS, bem como em ferramentas de teste. Em muitos casos, a implementação requer apenas a adição de iniciantes específicos do Spring Boot ou dependências relacionadas para ativar a funcionalidade.

Conclusão


Este post inclui uma breve introdução ao Suporte Reativo em alguns projetos da Primavera. À medida que mais e mais projetos Spring se adaptam e suportam as APIs reativas, os desenvolvedores terão mais opções para usar a programação imperativa ou reativa em seus aplicativos. Além disso, este aplicativo de amostra demonstra apenas alguns dos projetos do Spring que atualmente oferecem Suporte Reativo. Procure mais no futuro! Se você tiver dúvidas ou preocupações sobre um projeto específico do Spring, entre em contato com os mantenedores do projeto na página correspondente do GitHub.

Traduzido por @middle_java

Source: https://habr.com/ru/post/pt485498/


All Articles