Skip to content

Commit

Permalink
Synchronoss should create temp directory lazily
Browse files Browse the repository at this point in the history
The SynchronossPartHttpMessageReader should only create temp directory
when needed, not at startup.

Closes gh-27092
  • Loading branch information
poutsma committed Jun 23, 2021
1 parent c5a138a commit 7b34bf2
Showing 1 changed file with 36 additions and 18 deletions.
Expand Up @@ -17,7 +17,6 @@
package org.springframework.http.codec.multipart;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
Expand All @@ -31,6 +30,7 @@
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;

import org.synchronoss.cloud.nio.multipart.DefaultPartBodyStreamStorageFactory;
Expand All @@ -46,6 +46,7 @@
import reactor.core.publisher.FluxSink;
import reactor.core.publisher.Mono;
import reactor.core.publisher.SignalType;
import reactor.core.scheduler.Schedulers;

import org.springframework.core.ResolvableType;
import org.springframework.core.codec.DecodingException;
Expand Down Expand Up @@ -93,7 +94,7 @@ public class SynchronossPartHttpMessageReader extends LoggingCodecSupport implem

private int maxParts = -1;

private Path fileStorageDirectory = createTempDirectory();
private final AtomicReference<Path> fileStorageDirectory = new AtomicReference<>();


/**
Expand Down Expand Up @@ -178,29 +179,46 @@ public boolean canRead(ResolvableType elementType, @Nullable MediaType mediaType

@Override
public Flux<Part> read(ResolvableType elementType, ReactiveHttpInputMessage message, Map<String, Object> hints) {
return Flux.create(new SynchronossPartGenerator(message, this.fileStorageDirectory))
.doOnNext(part -> {
if (!Hints.isLoggingSuppressed(hints)) {
LogFormatUtils.traceDebug(logger, traceOn -> Hints.getLogPrefix(hints) + "Parsed " +
(isEnableLoggingRequestDetails() ?
LogFormatUtils.formatValue(part, !traceOn) :
"parts '" + part.name() + "' (content masked)"));
}
});
return getFileStorageDirectory().flatMapMany(directory ->
Flux.create(new SynchronossPartGenerator(message, directory))
.doOnNext(part -> {
if (!Hints.isLoggingSuppressed(hints)) {
LogFormatUtils.traceDebug(logger, traceOn -> Hints.getLogPrefix(hints) + "Parsed " +
(isEnableLoggingRequestDetails() ?
LogFormatUtils.formatValue(part, !traceOn) :
"parts '" + part.name() + "' (content masked)"));
}
}));
}

@Override
public Mono<Part> readMono(ResolvableType elementType, ReactiveHttpInputMessage message, Map<String, Object> hints) {
return Mono.error(new UnsupportedOperationException("Cannot read multipart request body into single Part"));
}

private static Path createTempDirectory() {
try {
return Files.createTempDirectory(FILE_STORAGE_DIRECTORY_PREFIX);
}
catch (IOException ex) {
throw new UncheckedIOException(ex);
}
private Mono<Path> getFileStorageDirectory() {
return Mono.defer(() -> {
Path directory = this.fileStorageDirectory.get();
if (directory != null) {
return Mono.just(directory);
}
else {
return Mono.fromCallable(() -> {
Path tempDirectory = Files.createTempDirectory(FILE_STORAGE_DIRECTORY_PREFIX);
if (this.fileStorageDirectory.compareAndSet(null, tempDirectory)) {
return tempDirectory;
}
else {
try {
Files.delete(tempDirectory);
}
catch (IOException ignored) {
}
return this.fileStorageDirectory.get();
}
}).subscribeOn(Schedulers.boundedElastic());
}
});
}


Expand Down

0 comments on commit 7b34bf2

Please sign in to comment.