Как я могу сделать код более реактивным; Удалите if's, проверьте на пустое и сделайте промежуточную регистрацию - PullRequest
1 голос
/ 27 февраля 2020

Я подумываю, как мне переписать этот код более реактивным способом (без if, выбросить исключения на промежуточных шагах и т. Д. c. И лучшие практики для регистрации промежуточных результатов)

        return identityRepository.findByDeviceIdAndToken(
                deviceId,
                authToken
        ).doOnSuccess(identity -> {
            if (identity == null) {
                log.info(
                        "Pair Auth-Token: {} and Device-ID: {} not found",
                        authToken,
                        deviceId
                );
            }
        })
                .map(MyPrincipal::new)
                .map(
                        principal -> {
                            if (!principal.isCredentialsNonExpired()) {
                                throw new CredentialsExpiredException();
                            }
                            return 
                                    new UsernamePasswordAuthenticationToken(
                                            principal,
                                            null,
                                            Collections.emptyList()
                                    )
                            ;
                        }
                )
                .flatMap(this.authenticationManager::authenticate)
                .map(SecurityContextImpl::new);

Ответы [ 2 ]

1 голос
/ 28 февраля 2020

Вы можете использовать Необязательно , чтобы исключить условие if из вашего кода. Всего в вашем коде 2 условия. Давайте сначала удалим if из doOnSuccess метода

.doOnSuccess(identity -> {
 if (identity == null) {
  log.info(
   "Pair Auth-Token: {} and Device-ID: {} not found",
   authToken,
   deviceId
  );
 }
})

Вы можете использовать ifPresentOrElse , чтобы удалить условие if. Это было введено в java 9:

.doOnSuccess(identity -> Optional.ofNullable(identity)
 .ifPresentOrElse(
  val -> {},
  () -> log.info(
   "Pair Auth-Token: {} and Device-ID: {} not found",
   authToken,
   deviceId)
 )
)

Второе условие if находится в map методе

.map(principal -> {
    if (!principal.isCredentialsNonExpired()) {
        throw new CredentialsExpiredException();
    }
    return new UsernamePasswordAuthenticationToken(principal, null, Collections.emptyList());
})

В приведенном выше коде вы вызываете какое-то исключение на основе условие. Вы можете использовать filter вместе с orElseThrow , чтобы выдать исключение, если Optional стал пустым из-за фильтра:

.map(principal -> Optional.of(new UsernamePasswordAuthenticationToken(principal, null, Collections.emptyList()))
        .filter(token -> token.getPrincipal().isCredentialsNonExpired())
        .orElseThrow(CredentialsExpiredException::new))
0 голосов
/ 27 февраля 2020

Вы можете изменить логи карты c следующим образом:

return identityRepository.findByDeviceIdAndToken(
                deviceId,
                authToken
        ).doOnSuccess(identity -> {
            if (identity == null) {
                log.info(
                        "Pair Auth-Token: {} and Device-ID: {} not found",
                        authToken,
                        deviceId
                );
            }
        })
                .map(MyPrincipal::new)
                .filter(principal -> principal.isCredentialsNonExpired())
                .switchIfEmpty(Mono.error(new CredentialsExpiredException()))
                .map(x -> new UsernamePasswordAuthenticationToken(
                                principal,
                                null,
                                Collections.emptyList()
                        )
                )
                .flatMap(this.authenticationManager::authenticate)
                .map(SecurityContextImpl::new);
...