0

Trying to rewrite a working reactive function by including a small validation in between. Unfortunately, the program is not able to complete the request even though the computation is completed in the backend. Also, It will be great if someone can tell me if there is any unnecessary coding practice related to reactive.

  1. Handler function, from where we invoke the reactive service

        public Mono<ServerResponse> performValidation(ServerRequest serverRequest) {
        Mono<Request> request = serverRequest.bodyToMono(Request.class);
        return ServerResponse.ok()
                .body(service1.performValidation(boundaryCheckRequest, ""), ServiceResponse.class)
                //.body(service1.performValidation_Working(boundaryCheckRequest, ""), ServiceResponse.class)
                .onErrorResume(Exception.class,
                        e -> ServerResponse.status(HttpStatus.INTERNAL_SERVER_ERROR)
                                .body(Mono.just(e.getMessage()), String.class));}
    
  2. Handler invokes the below service, the below code snippet is having issue

    public Mono<ServiceResponse> performValidation(Mono<ServiceRequest> requestMono,String token) {
        return Mono.create(monoSink -> {
            requestMono.map(triggerRequest -> {
                return checkValidOrders(triggerRequest)?doValidations(requestMono,token).subscribe():Mono.just(new ServiceResponse()).subscribe();
            }).subscribe();
        });
    }
    
    private Mono<ServiceResponse> doValidations(ServiceRequest request,String token){
        RequestHolder requestHolder= new RequestHolder(request,token);
        ServiceResponseObject serviceBus=new ServiceResponseObject();
        return Mono.create(monoSink -> {
            Flux.merge(
                    getServiceOne(requestHolder, serviceBus),
                    getServiceTwo(requestHolder, serviceBus)
                  )
                    .doOnNext(completedFlag -> {
                    })
                    .doOnComplete(() -> {
                        ServiceResponse ServiceResponse = validationService.validate(serviceBus, requestHolder.getRequest());
                        monoSink.success(ServiceResponse);
                    })
                    .doOnError(throwable -> {
                        monoSink.success(handleError(throwable, requestHolder));
                    })
                    .subscribe();
        });
    }
      private Boolean checkValidOrders(ServiceRequest tr){
        return tr.getLines().stream().anyMatch(line-> !line.getStatus().equals("ACIVE"));
    }   
    
  3. working version of the service code.
    public Mono<ServiceResponse> performValidation_Working(Mono<ServiceRequest> requestMono,String token) {
        return Mono.create(monoSink -> {
            requestMono.map((triggerReq)->
            {
                return new RequestHolder(request,token);
            })
            .subscribe(servicesRequestHolder -> {
                ServiceResponseObject serviceBus=new ServiceResponseObject();
                Flux.merge(
                        getServiceOne(requestHolder, serviceBus),
                        getServiceTwo(requestHolder, serviceBus)
                )
                    .doOnNext(completedFlag -> { })
                    .doOnComplete(()->{
                        ServiceResponse ServiceResponse = validationService.validate(serviceBus, requestHolder.getRequest());
                        monoSink.success(ServiceResponse);
                    })
                    .doOnError(throwable -> {
                        monoSink.success(handleError(throwable,servicesRequestHolder));
                    })
                    .subscribe();
            });
        });
    } 

Not able to figure out why the request processing is not ending, kindly advise.

busywithJava
  • 41
  • 1
  • 4
  • I can see you call subscribe, you should not do that. Let spring subscribe to the top Mono/Flux and chain - read flat map following steps. `request.flatMap(request -> service1.performValidation(request, "")).flatMap(validatedRequest-> ...` – Palcente Feb 12 '20 at 15:53
  • okey, this is one of the messiest, reactive code examples i have ever seen. I have so many questions. What is `getServiceOne` and what is `getServiceTwo` can you please explain on a high level, you get a request, you want to validate that the request has some lines that say active, and then? – Toerktumlare Feb 12 '20 at 17:33
  • what is `validationService.validate` and why all the subscribing? – Toerktumlare Feb 12 '20 at 17:34
  • @Thomas Andolf, Thanks a lot for your kind response. I have just started with reactive and so kindly excuse :) . getServiceOne and two is invoked to get data from two external services(Flux.merge is used to gather all the required data before proceeding to validation service) which is required by the validationService to complete the validations. Thanks. – busywithJava Feb 13 '20 at 01:01

0 Answers0