2017-12-27 42 views
0

스프링 부트 2.0.0.M7 및 프로젝트 리액터를 사용하고 있습니다. 내 문제는 단위 테스트를 작성하는 동안 발생한 이상한 동작과 관련이 있습니다. 또한 flatMap의 출력을 저장소에 공급하면서이 문제에 봉착했습니다.Reactor - flatMap의 출력에서 ​​블록을 호출하면 ClassCastException이 발생합니다.

Mono<Foo> create(Mono<FooResource> resourceMono) { 
    resourceMono.flatMap({ 
     // convert resource into Foo domain Entity 
     return new Foo() 
    }) 
} 

이 폐쇄 인해 flatMap의 리턴 값에 Mono<Foo>을 방출한다.

def createdFoo = Foo.create(Mono.just(fooResource)).block() 

스택 추적 :

java.lang.ClassCastException: com.example.Foo cannot be cast to org.reactivestreams.Publisher 

at reactor.core.publisher.FluxFlatMap.trySubscribeScalarMap(FluxFlatMap.java:141) 
at reactor.core.publisher.MonoFlatMap.subscribe(MonoFlatMap.java:53) 
at reactor.core.publisher.Mono.block(Mono.java:1161) 

MonoJust를 구현하기 때문에 발생하는 것으로 나타납니다 구독하고 결과 Foo를 얻을 수 block()를 호출 할 때,하는 ClassCastException

FluxFlatMap.trySubscribeScalarMap에서 테스트 코드가있다 Callable이므로 trySubscribeScalarMap은 성공적으로 처리를 시도하지 않습니다.

테스트 시나리오가 아닌 경우에도 유사한 오류가 발생합니다.

Mono<ServerResponse> createFoo(ServerRequest request) { 
    def body = request.body(BodyExtractors.toMono(FooResource)) 
    ok().body(fromPublisher(Foo.create(body) 
     .flatMap({fooRepository.save(it)}), Foo)) 
} 

스택 추적 :

java.lang.ClassCastException: com.example.Foo cannot be cast to reactor.core.publisher.Mono 
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:118) [reactor-core-3.1.2.RELEASE.jar:3.1.2.RELEASE] 
at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onNext(FluxOnAssembly.java:450) ~[reactor-core-3.1.2.RELEASE.jar:3.1.2.RELEASE] 
at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1092) ~[reactor-core-3.1.2.RELEASE.jar:3.1.2.RELEASE] 
at reactor.core.publisher.MonoSingle$SingleSubscriber.onComplete(MonoSingle.java:171) ~[reactor-core-3.1.2.RELEASE.jar:3.1.2.RELEASE] 
<...> 
Assembly trace from producer [reactor.core.publisher.MonoFlatMap] : 
reactor.core.publisher.Mono.flatMap(Mono.java:2059) 
org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoCachedMethodSiteNoUnwrap.invoke(PojoMetaMethodSite.java:213) 
org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:56) 
org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) 
org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113) 
org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125) 
com.example.Foo.create(Foo.groovy:28) 
org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) 
org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113) 
org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125) 
com.example.FooHandlerFunctions.createFoo(FooHandlerFunctions.groovy:48) 

다른 Mono.just(foo)flatMap 폐쇄의 출력을 포장은 모두 문제를 해결합니다. 그러나 그것이 필요하지 않아야하는 것처럼 보입니다. 내가 잘못된 것을하고 있거나 그냥 오해하고있는 것입니까? flatMap은 어떻게 작동합니까?

답변

1

flatmap은 반환해야하는 Function 소요 Mono (I 추측 끝내 FooPublisher을 구현하지 않는 것대로, 잘못된 유형으로 다시?)