Два использования Mono.fromCallable (), но только один, кажется, «работает» - PullRequest
0 голосов
/ 09 июля 2019

В приведенном ниже коде оба варианта использования Mono.fromCallable () in DemoPOJORepo.getById (int) возвращают запрошенный объект (используя значение 2). Комментируемая строка - мое предпочтительное использование, некомментированная строка была добавлена ​​для имитации использования в DemoPOJORepo.add (DemoPOJO) .

При выполнении кода оператор Mono.fromCallable () в DemoPOJORepo.add (DemoPOJO) не вызывает addPOJO (DemoPOJO) . Кажется «очевидным», что есть что-то другое, и я «делаю что-то не так», но я этого не вижу.

@Component
public class DemoPOJORepo {

    private static DemoPOJORepo demoPOJORepo = null;

    private Map<Integer, DemoPOJO> demoPOJOMap;

    private DemoPOJORepo() {
        initMap();
    }

    public static DemoPOJORepo getInstance() {
        if (demoPOJORepo == null) {
            demoPOJORepo = new DemoPOJORepo();
        }
        return demoPOJORepo;
    }

    public Flux<DemoPOJO> getAll() {
        return Flux.fromIterable(demoPOJOMap.values());
    }

    public Mono<DemoPOJO> getById(int id) {
        return Mono.fromCallable( () -> getPOJOById(id) );
//        return Mono.fromCallable( () -> demoPOJOMap.get(id) );
    }

    private DemoPOJO getPOJOById(int id) {
        return demoPOJOMap.get(id);
    }

    public Mono<Boolean> add(DemoPOJO fooPOJO) {
        System.out.println("DEMO >> DemoPOJORepo.add(DemoPOJO)");
        return Mono.fromCallable( () -> addPOJO(fooPOJO) );
    }

    private Boolean addPOJO(DemoPOJO fooPOJO) {
        Boolean pojoAdded = false;

        System.out.println("DEMO >> DemoPOJORepo.addPOJO(DemoPOJO)");
        if (!demoPOJOMap.containsKey(fooPOJO.getId())) {
            demoPOJOMap.put(fooPOJO.getId(), fooPOJO);
            pojoAdded = true;
        }
        return pojoAdded;
    }
}

Вот остальная часть кода, необходимого для запуска примера ...

Реализация DemoPOJO ...

public class DemoPOJO {

    public static final String DEF_NAME  = "DEFAULT NAME";
    public static final int    DEF_VALUE = 99;

    private int    id;
    private String name;
    private int    value;

    public DemoPOJO(int id) {
        this(id, DEF_NAME, DEF_VALUE);
    }

    public DemoPOJO(@JsonProperty("id") int id, @JsonProperty("name") String name, @JsonProperty("value") int value) {
        this.id    = id;
        this.name  = name;
        this.value = value;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public int getValue() {
        return value;
    }
}

Реализация роутера ...

@Configuration
public class DemoPOJORouter {

    @Bean
    public RouterFunction<ServerResponse> route(DemoPOJOHandler requestHandler) {
        return nest(path("/v2"),
               nest(accept(APPLICATION_JSON),
                   RouterFunctions.route(RequestPredicates.GET("/DemoPOJO/{id}"), requestHandler::getById)
                               .andRoute(RequestPredicates.POST("/DemoPOJO"), requestHandler::add)));
    }
}

И, реализация обработчика ...

@Component
public class DemoPOJOHandler {

    public static final String PATH_VAR_ID = "id";

    private DemoPOJORepo repo = null;

    public Mono<ServerResponse> getById(ServerRequest request) {
        Mono<DemoPOJO>      monoDemoPOJO  = null;
        Map<String, String> pathVariables = request.pathVariables();
        int                 id            = -1;

        checkRepoRef();  // just makes sure that "repo" is populated

        // short-circuit if bad request
        if ((pathVariables == null)
         || (!pathVariables.containsKey(PATH_VAR_ID))) {
            return ServerResponse.badRequest().build();
        }

        // short-circuit if bad id value
        try {
            id = Integer.parseInt(pathVariables.get(PATH_VAR_ID));
        } catch(NumberFormatException e) {
            return ServerResponse.badRequest().build();
        }

        // call to get entity by keyValue
        monoDemoPOJO = repo.getById(id);

        /* non-blocking mechanism for either returning the Mono<DemoPOJO>
         *   or an empty response if Mono<Void> was returned by repo.getById()
         */
        return monoDemoPOJO
                   .flatMap(demoPOJO -> ServerResponse.ok()
                                                      .contentType(MediaType.APPLICATION_JSON)
                                                      .syncBody(demoPOJO))
                   .switchIfEmpty(ServerResponse.notFound().build());
    }

    public Mono<ServerResponse> add(ServerRequest request) {

        checkRepoRef();

        return request.bodyToMono(DemoPOJO.class).doOnSuccess( demoPOJO -> repo.add(demoPOJO))
                                                 .then(ServerResponse.ok().build());
    }

    private void checkRepoRef() {
        if (repo == null) {
            repo = DemoPOJORepo.getInstance();
        }
    }
}
...