Skip to content

Commit

Permalink
spring boot upkeep
Browse files Browse the repository at this point in the history
  • Loading branch information
querwurzel committed Nov 24, 2023
1 parent ecebd3e commit 06a8c46
Show file tree
Hide file tree
Showing 6 changed files with 24 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
import com.github.binpastes.paste.api.model.SearchView;
import com.github.binpastes.paste.api.model.SearchView.SearchItemView;
import com.github.binpastes.paste.api.model.SingleView;
import com.github.binpastes.paste.domain.Paste;
import com.github.binpastes.paste.application.PasteService;
import com.github.binpastes.paste.domain.Paste;
import jakarta.validation.ConstraintViolationException;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
Expand All @@ -19,23 +19,13 @@
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.support.WebExchangeBindException;
import org.springframework.web.server.ResponseStatusException;
import reactor.core.publisher.Mono;

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.concurrent.TimeUnit;

import static com.github.binpastes.paste.api.model.ListView.ListItemView;
Expand Down Expand Up @@ -64,22 +54,19 @@ public Mono<SingleView> findPaste(@PathVariable("pasteId") String pasteId, Serve
return;
}

if (paste.isPermanent() || isAfter(paste.getDateOfExpiry(), 5, ChronoUnit.MINUTES)) {
response.getHeaders().setCacheControl(CacheControl.maxAge(5, TimeUnit.MINUTES));
return;
var now = LocalDateTime.now();
if (paste.isPermanent() || paste.getDateOfExpiry().plusMinutes(5).isAfter(now)) {
response.getHeaders().setCacheControl(
CacheControl.maxAge(5, TimeUnit.MINUTES));
} else {
response.getHeaders().setCacheControl(
CacheControl.maxAge(Duration.between(now, paste.getDateOfExpiry())));
}

response.getHeaders().setCacheControl(
CacheControl.maxAge(Duration.between(LocalDateTime.now(), paste.getDateOfExpiry())));
})
.map(reference -> SingleView.of(reference, remoteAddress(request)))
.switchIfEmpty(Mono.error(new ResponseStatusException(HttpStatus.NOT_FOUND)));
}

private static boolean isAfter(LocalDateTime dateTime, long amount, ChronoUnit unit) {
return LocalDateTime.now().plus(amount, unit).isBefore(dateTime);
}

@GetMapping
public Mono<ListView> findPastes() {
return pasteService
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,7 @@ public String title() {
}

public String content() {
return StringUtils.hasText(content)
? content
: null;
return content;
}

public boolean isEncrypted() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,15 @@ public Mono<Paste> find(String id) {
}

private Mono<Paste> trackAccess(Paste paste) {
trackingService.trackView(paste.getId());

if (paste.isOneTime()) {
return pasteRepository
.save(paste.markAsExpired())
.doOnSuccess(deletedPaste -> log.info("OneTime paste {} viewed and burnt", deletedPaste.getId()))
.onErrorComplete();
.retry()
.doOnSuccess(deletedPaste -> log.info("OneTime paste {} viewed and burnt", deletedPaste.getId()));
}

trackingService.trackView(paste.getId());
return Mono.just(paste);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.OptimisticLockingFailureException;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;

import java.time.Instant;
import java.time.LocalDateTime;
Expand Down Expand Up @@ -49,9 +47,8 @@ public void receiveView(String pasteId, Instant timeViewed) {
pasteRepository
.findById(pasteId)
.flatMap(paste -> pasteRepository.save(paste.trackView(timestamp)))
.retry()
.doOnNext(paste -> log.debug("Tracked view on paste {}", paste.getId()))
.doOnError(OptimisticLockingFailureException.class, e -> messagingClient.sendMessage(pasteId, timeViewed))
.onErrorResume(OptimisticLockingFailureException.class, e -> Mono.empty())
.subscribe();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class TrackingIT {
@Autowired
private WebTestClient webClient;

@Autowired
@SpyBean
private PasteRepository pasteRepository;

@Autowired
Expand Down Expand Up @@ -78,23 +78,23 @@ void trackConcurrentPasteViews() {
var intialPaste = givenPublicPaste();

Flux.fromStream(Stream.generate(intialPaste::getId))
.take(1000)
.take(500)
.doOnNext(trackingService::trackView)
// enforce a concurrent update
// simulate a concurrent update
.doOnNext(id -> pasteRepository.findById(id)
.doOnNext(paste -> setField(paste, "remoteAddress", "concurrentUpdate"))
.flatMap(paste -> pasteRepository.save(paste))
.onErrorComplete() // ignore errors in test
.onErrorComplete()
.subscribe())
.subscribeOn(Schedulers.parallel())
.subscribe();

await().atMost(Duration.ofMinutes(1)).pollInterval(Duration.ofMillis(500)).until(
await().atMost(Duration.ofMinutes(1)).pollInterval(Duration.ofSeconds(1)).until(
() -> pasteRepository.findById(intialPaste.getId()).block().getViews(),
equalTo(1000L)
equalTo(500L)
);

Mockito.verify(messagingClient, atLeast(1001)).sendMessage(any(), any());
Mockito.verify(pasteRepository, atLeast(501)).save(eq(intialPaste));
}

@Test
Expand Down
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.5</version>
<version>3.1.6</version>
<relativePath/><!-- lookup parent from repository -->
</parent>

Expand Down Expand Up @@ -43,7 +43,7 @@
<jacoco-maven-plugin.version>0.8.11</jacoco-maven-plugin.version>

<!-- 3rd-party library versions -->
<spring-boot-bom.version>3.1.5</spring-boot-bom.version>
<spring-boot-bom.version>3.1.6</spring-boot-bom.version>
<junixsocket.version>2.8.3</junixsocket.version>
<flyway.version>9.22.3</flyway.version>
<artemis.version>2.31.2</artemis.version>
Expand Down

0 comments on commit 06a8c46

Please sign in to comment.