|
17 | 17 | package org.springframework.http.codec.multipart;
|
18 | 18 |
|
19 | 19 | import java.io.IOException;
|
20 |
| -import java.io.UncheckedIOException; |
21 | 20 | import java.nio.channels.Channels;
|
22 | 21 | import java.nio.channels.FileChannel;
|
23 | 22 | import java.nio.channels.ReadableByteChannel;
|
|
31 | 30 | import java.util.Map;
|
32 | 31 | import java.util.Optional;
|
33 | 32 | import java.util.concurrent.atomic.AtomicInteger;
|
| 33 | +import java.util.concurrent.atomic.AtomicReference; |
34 | 34 | import java.util.function.Consumer;
|
35 | 35 |
|
36 | 36 | import org.synchronoss.cloud.nio.multipart.DefaultPartBodyStreamStorageFactory;
|
|
46 | 46 | import reactor.core.publisher.FluxSink;
|
47 | 47 | import reactor.core.publisher.Mono;
|
48 | 48 | import reactor.core.publisher.SignalType;
|
| 49 | +import reactor.core.scheduler.Schedulers; |
49 | 50 |
|
50 | 51 | import org.springframework.core.ResolvableType;
|
51 | 52 | import org.springframework.core.codec.DecodingException;
|
@@ -93,7 +94,7 @@ public class SynchronossPartHttpMessageReader extends LoggingCodecSupport implem
|
93 | 94 |
|
94 | 95 | private int maxParts = -1;
|
95 | 96 |
|
96 |
| - private Path fileStorageDirectory = createTempDirectory(); |
| 97 | + private final AtomicReference<Path> fileStorageDirectory = new AtomicReference<>(); |
97 | 98 |
|
98 | 99 |
|
99 | 100 | /**
|
@@ -178,29 +179,46 @@ public boolean canRead(ResolvableType elementType, @Nullable MediaType mediaType
|
178 | 179 |
|
179 | 180 | @Override
|
180 | 181 | public Flux<Part> read(ResolvableType elementType, ReactiveHttpInputMessage message, Map<String, Object> hints) {
|
181 |
| - return Flux.create(new SynchronossPartGenerator(message, this.fileStorageDirectory)) |
182 |
| - .doOnNext(part -> { |
183 |
| - if (!Hints.isLoggingSuppressed(hints)) { |
184 |
| - LogFormatUtils.traceDebug(logger, traceOn -> Hints.getLogPrefix(hints) + "Parsed " + |
185 |
| - (isEnableLoggingRequestDetails() ? |
186 |
| - LogFormatUtils.formatValue(part, !traceOn) : |
187 |
| - "parts '" + part.name() + "' (content masked)")); |
188 |
| - } |
189 |
| - }); |
| 182 | + return getFileStorageDirectory().flatMapMany(directory -> |
| 183 | + Flux.create(new SynchronossPartGenerator(message, directory)) |
| 184 | + .doOnNext(part -> { |
| 185 | + if (!Hints.isLoggingSuppressed(hints)) { |
| 186 | + LogFormatUtils.traceDebug(logger, traceOn -> Hints.getLogPrefix(hints) + "Parsed " + |
| 187 | + (isEnableLoggingRequestDetails() ? |
| 188 | + LogFormatUtils.formatValue(part, !traceOn) : |
| 189 | + "parts '" + part.name() + "' (content masked)")); |
| 190 | + } |
| 191 | + })); |
190 | 192 | }
|
191 | 193 |
|
192 | 194 | @Override
|
193 | 195 | public Mono<Part> readMono(ResolvableType elementType, ReactiveHttpInputMessage message, Map<String, Object> hints) {
|
194 | 196 | return Mono.error(new UnsupportedOperationException("Cannot read multipart request body into single Part"));
|
195 | 197 | }
|
196 | 198 |
|
197 |
| - private static Path createTempDirectory() { |
198 |
| - try { |
199 |
| - return Files.createTempDirectory(FILE_STORAGE_DIRECTORY_PREFIX); |
200 |
| - } |
201 |
| - catch (IOException ex) { |
202 |
| - throw new UncheckedIOException(ex); |
203 |
| - } |
| 199 | + private Mono<Path> getFileStorageDirectory() { |
| 200 | + return Mono.defer(() -> { |
| 201 | + Path directory = this.fileStorageDirectory.get(); |
| 202 | + if (directory != null) { |
| 203 | + return Mono.just(directory); |
| 204 | + } |
| 205 | + else { |
| 206 | + return Mono.fromCallable(() -> { |
| 207 | + Path tempDirectory = Files.createTempDirectory(FILE_STORAGE_DIRECTORY_PREFIX); |
| 208 | + if (this.fileStorageDirectory.compareAndSet(null, tempDirectory)) { |
| 209 | + return tempDirectory; |
| 210 | + } |
| 211 | + else { |
| 212 | + try { |
| 213 | + Files.delete(tempDirectory); |
| 214 | + } |
| 215 | + catch (IOException ignored) { |
| 216 | + } |
| 217 | + return this.fileStorageDirectory.get(); |
| 218 | + } |
| 219 | + }).subscribeOn(Schedulers.boundedElastic()); |
| 220 | + } |
| 221 | + }); |
204 | 222 | }
|
205 | 223 |
|
206 | 224 |
|
|
0 commit comments