spring-framework icon indicating copy to clipboard operation
spring-framework copied to clipboard

DataBufferUtils.write(Publisher, Path) loses context

Open kzander91 opened this issue 3 years ago • 1 comments

Very similar to #27517, but it looks like this issue has not been fixed for the Path variant of DataBufferUtils.write, the following code (similar to the example snippet from #27517 but writing to a Path instead of an OutputStream):

DataBufferUtils.read(new ByteArrayResource("test".getBytes()), new NettyDataBufferFactory(new PooledByteBufAllocator()), 1024)
        .transformDeferredContextual((f, ctx) -> {
            System.out.println("1: " + ctx.getOrDefault("key", "EMPTY"));
            return f;
        })
        .transform(f -> DataBufferUtils.write(f, Path.of("test")))
        .transformDeferredContextual((f, ctx) -> {
            System.out.println("2: " + ctx.getOrDefault("key", "EMPTY"));
            return f;
        })
        .contextWrite(Context.of("key", "TEST"))
        .subscribe();

Expected result:

2: TEST
1: TEST

Actual result:

2: TEST
1: EMPTY

The context is lost here: https://github.com/spring-projects/spring-framework/blob/508cc346e098266a84d64281635344f8c6231281/spring-core/src/main/java/org/springframework/core/io/buffer/DataBufferUtils.java#L367-L369

Passing sink's context into the subscribe() call would fix this isssue:

write(source, channel).subscribe(DataBufferUtils::release,
		sink::error,
		sink::success,
		Context.of(sink.contextView()));

Environment:

  • Spring Boot 2.7.2
  • Spring Framework 5.3.22
  • Project Reactor 3.4.21

kzander91 avatar Aug 05 '22 17:08 kzander91

Our workaround until this is fixed is to manually propagate the context:

Flux<DataBuffer> bufs = ...;
Path path = ...;
Mono<Void> write = Mono.deferContextual(ctx -> DataBufferUtils.write(bufs.contextWrite(ctx), path));

kzander91 avatar Aug 10 '22 09:08 kzander91

Fixed! Thanks for spotting this, @kzander91

poutsma avatar Aug 16 '22 09:08 poutsma