格式修改
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
package com.baiyue.print.config;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import java.io.InputStream;
|
||||
import org.apache.fontbox.ttf.TTFParser;
|
||||
import org.apache.fontbox.ttf.TrueTypeFont;
|
||||
@@ -11,11 +14,11 @@ import org.springframework.stereotype.Component;
|
||||
/** Exposes font packaging/parsing failures through readiness health. */
|
||||
@Component("printFont")
|
||||
public class PrintFontHealthIndicator implements HealthIndicator {
|
||||
private final Health validationResult;
|
||||
@Resource private PrintPdfProperties properties;
|
||||
private Health validationResult;
|
||||
|
||||
public PrintFontHealthIndicator(PrintPdfProperties properties) {
|
||||
this.validationResult = validate(properties.getFontResource());
|
||||
}
|
||||
@PostConstruct
|
||||
void initializeHealth() { validationResult = validate(properties.getFontResource()); }
|
||||
|
||||
@Override
|
||||
public Health health() {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.baiyue.print.controller;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import com.baiyue.common.web.CorrelationContext;
|
||||
import com.baiyue.print.dto.InboundMarkPdfDtos;
|
||||
import com.baiyue.print.service.InboundMarkPdfService;
|
||||
@@ -24,13 +26,8 @@ public class InternalPdfController {
|
||||
static final String INTERNAL_TOKEN_HEADER = "X-Internal-Service-Token";
|
||||
static final String PAGE_COUNT_HEADER = "X-Print-Page-Count";
|
||||
|
||||
private final InboundMarkPdfService pdfService;
|
||||
private final InternalServiceTokenGuard tokenGuard;
|
||||
|
||||
public InternalPdfController(InboundMarkPdfService pdfService, InternalServiceTokenGuard tokenGuard) {
|
||||
this.pdfService = pdfService;
|
||||
this.tokenGuard = tokenGuard;
|
||||
}
|
||||
@Resource private InboundMarkPdfService pdfService;
|
||||
@Resource private InternalServiceTokenGuard tokenGuard;
|
||||
|
||||
@PostMapping(value = "/inbound-marks", consumes = MediaType.APPLICATION_JSON_VALUE)
|
||||
public ResponseEntity<byte[]> generateInboundMarks(
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.baiyue.print.controller;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
|
||||
import com.baiyue.common.core.api.ResultCode;
|
||||
import com.baiyue.common.core.exception.BizException;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
@@ -11,9 +13,11 @@ import java.security.MessageDigest;
|
||||
/** Verifies the shared credential used by internal service callers. */
|
||||
@Component
|
||||
public class InternalServiceTokenGuard {
|
||||
private final byte[] expectedToken;
|
||||
@Value("${baiyue.security.internal-service-token}") private String token;
|
||||
private byte[] expectedToken;
|
||||
|
||||
public InternalServiceTokenGuard(@Value("${baiyue.security.internal-service-token}") String token) {
|
||||
@PostConstruct
|
||||
void initializeToken() {
|
||||
if (token == null || token.getBytes(StandardCharsets.UTF_8).length < 32) {
|
||||
throw new IllegalStateException("INTERNAL_SERVICE_TOKEN must contain at least 32 bytes");
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.baiyue.print.controller;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import com.baiyue.common.core.api.ApiResponse;
|
||||
import com.baiyue.common.core.api.ResultCode;
|
||||
import com.baiyue.common.web.CorrelationContext;
|
||||
@@ -28,13 +30,8 @@ import org.springframework.web.filter.OncePerRequestFilter;
|
||||
public class PrintRequestSizeFilter extends OncePerRequestFilter {
|
||||
private static final String PATH = "/internal/print/v1/pdfs/inbound-marks";
|
||||
|
||||
private final PrintPdfProperties properties;
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
public PrintRequestSizeFilter(PrintPdfProperties properties, ObjectMapper objectMapper) {
|
||||
this.properties = properties;
|
||||
this.objectMapper = objectMapper;
|
||||
}
|
||||
@Resource private PrintPdfProperties properties;
|
||||
@Resource private ObjectMapper objectMapper;
|
||||
|
||||
@Override
|
||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.baiyue.print.renderer;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import com.baiyue.print.dto.InboundMarkPdfDtos;
|
||||
import com.google.zxing.common.BitMatrix;
|
||||
import java.io.IOException;
|
||||
@@ -24,11 +26,7 @@ public class InboundMarkV1Renderer {
|
||||
private static final float QR_LEFT_PT = (PAGE_WIDTH_PT - QR_SIZE_PT) / 2f;
|
||||
private static final float QR_BOTTOM_PT = PAGE_HEIGHT_PT - PdfUnits.mmToPt(84);
|
||||
|
||||
private final PdfQrRenderer qrRenderer;
|
||||
|
||||
public InboundMarkV1Renderer(PdfQrRenderer qrRenderer) {
|
||||
this.qrRenderer = qrRenderer;
|
||||
}
|
||||
@Resource private PdfQrRenderer qrRenderer;
|
||||
|
||||
public void renderPage(PDDocument document, PDFont font, InboundMarkPdfDtos.Label label,
|
||||
BitMatrix qrMatrix) throws IOException {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.baiyue.print.service;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import com.baiyue.common.core.api.ResultCode;
|
||||
import com.baiyue.common.core.exception.BizException;
|
||||
import com.baiyue.print.config.PrintPdfProperties;
|
||||
@@ -30,18 +32,10 @@ public class InboundMarkPdfService {
|
||||
private static final Set<Character> FORBIDDEN_FILE_NAME_CHARACTERS =
|
||||
Set.of('/', '\\', ':', '*', '?', '"', '<', '>', '|');
|
||||
|
||||
private final PrintPdfProperties properties;
|
||||
private final PdfGenerationLimiter limiter;
|
||||
private final InboundMarkV1Renderer renderer;
|
||||
private final PdfQrRenderer qrRenderer;
|
||||
|
||||
public InboundMarkPdfService(PrintPdfProperties properties, PdfGenerationLimiter limiter,
|
||||
InboundMarkV1Renderer renderer, PdfQrRenderer qrRenderer) {
|
||||
this.properties = properties;
|
||||
this.limiter = limiter;
|
||||
this.renderer = renderer;
|
||||
this.qrRenderer = qrRenderer;
|
||||
}
|
||||
@Resource private PrintPdfProperties properties;
|
||||
@Resource private PdfGenerationLimiter limiter;
|
||||
@Resource private InboundMarkV1Renderer renderer;
|
||||
@Resource private PdfQrRenderer qrRenderer;
|
||||
|
||||
public GeneratedPdf generate(InboundMarkPdfDtos.Request request) {
|
||||
NormalizedRequest normalized = validateAndNormalize(request);
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package com.baiyue.print.service;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import com.baiyue.common.core.api.ResultCode;
|
||||
import com.baiyue.common.core.exception.BizException;
|
||||
import com.baiyue.print.config.PrintPdfProperties;
|
||||
@@ -13,10 +16,12 @@ import org.springframework.stereotype.Component;
|
||||
*/
|
||||
@Component
|
||||
public class PdfGenerationLimiter {
|
||||
private final Semaphore semaphore;
|
||||
private final Duration acquireTimeout;
|
||||
@Resource private PrintPdfProperties properties;
|
||||
private Semaphore semaphore;
|
||||
private Duration acquireTimeout;
|
||||
|
||||
public PdfGenerationLimiter(PrintPdfProperties properties) {
|
||||
@PostConstruct
|
||||
void initializeLimiter() {
|
||||
if (properties.getMaxConcurrentGenerations() < 1) {
|
||||
throw new IllegalArgumentException("print.pdf.max-concurrent-generations must be positive");
|
||||
}
|
||||
|
||||
@@ -44,6 +44,6 @@ logging:
|
||||
rollingpolicy:
|
||||
file-name-pattern: "${LOGGING_ROLLING_FILE_NAME_PATTERN:${LOG_PATH:./logs}/${spring.application.name}.%d{yyyy-MM-dd}.%i.log.gz}"
|
||||
max-file-size: "${LOGGING_ROLLING_MAX_FILE_SIZE:100MB}"
|
||||
max-history: "${LOGGING_ROLLING_MAX_HISTORY:30}"
|
||||
max-history: "${LOGGING_ROLLING_MAX_HISTORY:7}"
|
||||
total-size-cap: "${LOGGING_ROLLING_TOTAL_SIZE_CAP:5GB}"
|
||||
clean-history-on-start: "${LOGGING_ROLLING_CLEAN_HISTORY_ON_START:false}"
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.baiyue.print.renderer.InboundMarkV1Renderer;
|
||||
import com.baiyue.print.renderer.PdfQrRenderer;
|
||||
import com.baiyue.print.service.InboundMarkPdfService;
|
||||
import com.baiyue.print.service.PdfGenerationLimiter;
|
||||
import jakarta.annotation.Resource;
|
||||
import com.google.zxing.BinaryBitmap;
|
||||
import com.google.zxing.MultiFormatReader;
|
||||
import com.google.zxing.RGBLuminanceSource;
|
||||
@@ -29,16 +30,20 @@ import org.apache.pdfbox.rendering.PDFRenderer;
|
||||
import org.apache.pdfbox.text.PDFTextStripper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
/** End-to-end renderer acceptance checks. These intentionally exercise the real service, not mocks. */
|
||||
@SpringJUnitConfig(classes = {InboundMarkPdfService.class, PrintPdfProperties.class,
|
||||
PdfGenerationLimiter.class, InboundMarkV1Renderer.class, PdfQrRenderer.class})
|
||||
class InboundMarkPdfAcceptanceTest {
|
||||
private static final String TEMPLATE = "INBOUND_MARK_V1";
|
||||
private static final BigDecimal MM_100 = new BigDecimal("100");
|
||||
@Resource
|
||||
private InboundMarkPdfService service;
|
||||
|
||||
@Test
|
||||
void generatesOnePageWithExactSizeTextOrderEmbeddedChineseFontAndNoDiskArtifact(@TempDir Path tempDir)
|
||||
throws Exception {
|
||||
InboundMarkPdfService service = service();
|
||||
InboundMarkPdfDtos.Label label = label(1);
|
||||
String originalTmp = System.getProperty("java.io.tmpdir");
|
||||
System.setProperty("java.io.tmpdir", tempDir.toString());
|
||||
@@ -62,13 +67,13 @@ class InboundMarkPdfAcceptanceTest {
|
||||
@Test
|
||||
void preservesPageOrderAndDecodableQrOnFirstMiddleAndLastPages() throws Exception {
|
||||
List<InboundMarkPdfDtos.Label> labels = labels(19);
|
||||
assertPdf(service().generate(request(labels)).content(), labels);
|
||||
assertPdf(service.generate(request(labels)).content(), labels);
|
||||
}
|
||||
|
||||
@Test
|
||||
void generatesTwoHundredEighteenPagesWithExactDimensions() throws Exception {
|
||||
List<InboundMarkPdfDtos.Label> labels = labels(218);
|
||||
byte[] pdf = service().generate(request(labels)).content();
|
||||
byte[] pdf = service.generate(request(labels)).content();
|
||||
try (PDDocument document = Loader.loadPDF(pdf)) {
|
||||
assertThat(document.getNumberOfPages()).isEqualTo(218);
|
||||
for (int i : List.of(0, 108, 217)) {
|
||||
@@ -82,7 +87,7 @@ class InboundMarkPdfAcceptanceTest {
|
||||
assumeTrue(Boolean.getBoolean("print.capacity.tests"),
|
||||
"Enable with -Dprint.capacity.tests=true for the 2000-page capacity acceptance test");
|
||||
List<InboundMarkPdfDtos.Label> labels = labels(2000);
|
||||
byte[] pdf = service().generate(request(labels)).content();
|
||||
byte[] pdf = service.generate(request(labels)).content();
|
||||
assertThat(pdf).startsWith("%PDF".getBytes(StandardCharsets.US_ASCII));
|
||||
assertThat(pdf.length).isLessThan(32 * 1024 * 1024);
|
||||
try (PDDocument document = Loader.loadPDF(pdf)) {
|
||||
@@ -152,12 +157,6 @@ class InboundMarkPdfAcceptanceTest {
|
||||
return List.of(0, size / 2, size - 1);
|
||||
}
|
||||
|
||||
private InboundMarkPdfService service() {
|
||||
PrintPdfProperties properties = new PrintPdfProperties();
|
||||
return new InboundMarkPdfService(properties, new PdfGenerationLimiter(properties),
|
||||
new InboundMarkV1Renderer(new PdfQrRenderer()), new PdfQrRenderer());
|
||||
}
|
||||
|
||||
private InboundMarkPdfDtos.Request request(List<InboundMarkPdfDtos.Label> labels) {
|
||||
return new InboundMarkPdfDtos.Request(TEMPLATE,
|
||||
new InboundMarkPdfDtos.PageSpec(MM_100, MM_100), "acceptance.pdf", labels);
|
||||
|
||||
@@ -4,20 +4,28 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.actuate.health.Status;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
|
||||
class PrintFontHealthIndicatorTest {
|
||||
@Test
|
||||
void reportsUpForPackagedParseableFont() {
|
||||
PrintPdfProperties properties = new PrintPdfProperties();
|
||||
|
||||
assertThat(new PrintFontHealthIndicator(properties).health().getStatus()).isEqualTo(Status.UP);
|
||||
context("fonts/NotoSansSC-Bold.ttf").run(context -> assertThat(
|
||||
context.getBean(PrintFontHealthIndicator.class).health().getStatus()).isEqualTo(Status.UP));
|
||||
}
|
||||
|
||||
@Test
|
||||
void reportsDownForMissingFont() {
|
||||
PrintPdfProperties properties = new PrintPdfProperties();
|
||||
properties.setFontResource("fonts/missing.ttf");
|
||||
context("fonts/missing.ttf").run(context -> assertThat(
|
||||
context.getBean(PrintFontHealthIndicator.class).health().getStatus()).isEqualTo(Status.DOWN));
|
||||
}
|
||||
|
||||
assertThat(new PrintFontHealthIndicator(properties).health().getStatus()).isEqualTo(Status.DOWN);
|
||||
private ApplicationContextRunner context(String font) {
|
||||
return new ApplicationContextRunner()
|
||||
.withBean(PrintPdfProperties.class, () -> {
|
||||
PrintPdfProperties properties = new PrintPdfProperties();
|
||||
properties.setFontResource(font);
|
||||
return properties;
|
||||
})
|
||||
.withBean(PrintFontHealthIndicator.class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.baiyue.common.core.exception.BizException;
|
||||
import com.baiyue.common.web.GlobalExceptionHandler;
|
||||
import com.baiyue.print.dto.InboundMarkPdfDtos;
|
||||
import com.baiyue.print.service.InboundMarkPdfService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
@@ -12,6 +13,9 @@ import org.springframework.http.MediaType;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
@@ -28,16 +32,18 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
@SpringJUnitConfig(classes = {InternalPdfController.class, InternalServiceTokenGuard.class})
|
||||
@TestPropertySource(properties = "baiyue.security.internal-service-token=0123456789abcdef0123456789abcdef")
|
||||
class InternalPdfControllerTest {
|
||||
private static final String TOKEN = "0123456789abcdef0123456789abcdef";
|
||||
@MockBean
|
||||
private InboundMarkPdfService service;
|
||||
@Resource
|
||||
private InternalPdfController controller;
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
service = mock(InboundMarkPdfService.class);
|
||||
InternalPdfController controller = new InternalPdfController(
|
||||
service, new InternalServiceTokenGuard(TOKEN));
|
||||
mockMvc = MockMvcBuilders.standaloneSetup(controller)
|
||||
.setControllerAdvice(new GlobalExceptionHandler())
|
||||
.build();
|
||||
|
||||
@@ -3,17 +3,23 @@ package com.baiyue.print.controller;
|
||||
import com.baiyue.common.core.api.ResultCode;
|
||||
import com.baiyue.common.core.exception.BizException;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
@SpringJUnitConfig(InternalServiceTokenGuard.class)
|
||||
@TestPropertySource(properties = "baiyue.security.internal-service-token=0123456789abcdef0123456789abcdef")
|
||||
class InternalServiceTokenGuardTest {
|
||||
private static final String TOKEN = "0123456789abcdef0123456789abcdef";
|
||||
@Resource private InternalServiceTokenGuard guard;
|
||||
|
||||
@Test
|
||||
void acceptsOnlyConfiguredToken() {
|
||||
InternalServiceTokenGuard guard = new InternalServiceTokenGuard(TOKEN);
|
||||
|
||||
guard.verify(TOKEN);
|
||||
assertThatThrownBy(() -> guard.verify(null))
|
||||
.isInstanceOf(BizException.class)
|
||||
@@ -27,10 +33,14 @@ class InternalServiceTokenGuardTest {
|
||||
|
||||
@Test
|
||||
void refusesUnsafeConfiguration() {
|
||||
assertThatThrownBy(() -> new InternalServiceTokenGuard("too-short"))
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.hasMessageContaining("at least 32 bytes");
|
||||
assertThatThrownBy(() -> new InternalServiceTokenGuard(null))
|
||||
.isInstanceOf(IllegalStateException.class);
|
||||
new ApplicationContextRunner()
|
||||
.withBean(PropertySourcesPlaceholderConfigurer.class)
|
||||
.withBean(InternalServiceTokenGuard.class)
|
||||
.withPropertyValues("baiyue.security.internal-service-token=too-short")
|
||||
.run(context -> assertThat(context).hasFailed());
|
||||
new ApplicationContextRunner()
|
||||
.withBean(PropertySourcesPlaceholderConfigurer.class)
|
||||
.withBean(InternalServiceTokenGuard.class)
|
||||
.run(context -> assertThat(context).hasFailed());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,15 +10,20 @@ import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
@SpringJUnitConfig(classes = {PrintRequestSizeFilter.class, PrintPdfProperties.class,
|
||||
PrintRequestSizeFilterTest.TestConfig.class})
|
||||
class PrintRequestSizeFilterTest {
|
||||
private PrintRequestSizeFilter filter;
|
||||
@Resource private PrintRequestSizeFilter filter;
|
||||
@Resource private PrintPdfProperties properties;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
PrintPdfProperties properties = new PrintPdfProperties();
|
||||
properties.setMaxRequestBytes(10);
|
||||
filter = new PrintRequestSizeFilter(properties, new ObjectMapper().findAndRegisterModules());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -86,4 +91,12 @@ class PrintRequestSizeFilterTest {
|
||||
.contains("Request body exceeds 10 bytes")
|
||||
.contains("\"requestId\":\"request-123\"");
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class TestConfig {
|
||||
@Bean
|
||||
ObjectMapper objectMapper() {
|
||||
return new ObjectMapper().findAndRegisterModules();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
-7
@@ -7,6 +7,7 @@ import com.baiyue.print.dto.InboundMarkPdfDtos;
|
||||
import com.baiyue.print.renderer.InboundMarkV1Renderer;
|
||||
import com.baiyue.print.renderer.PdfQrRenderer;
|
||||
import com.baiyue.print.renderer.PdfUnits;
|
||||
import jakarta.annotation.Resource;
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
@@ -14,17 +15,15 @@ import org.apache.pdfbox.Loader;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.text.PDFTextStripper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
@SpringJUnitConfig(classes = {InboundMarkPdfService.class, PrintPdfProperties.class,
|
||||
PdfGenerationLimiter.class, InboundMarkV1Renderer.class, PdfQrRenderer.class})
|
||||
class InboundMarkPdfServiceGenerationTest {
|
||||
@Resource
|
||||
private InboundMarkPdfService service;
|
||||
@Test
|
||||
void generatesOneStrictHundredMillimeterPagePerLabelInRequestOrder() throws IOException {
|
||||
PrintPdfProperties properties = new PrintPdfProperties();
|
||||
PdfQrRenderer qrRenderer = new PdfQrRenderer();
|
||||
InboundMarkPdfService service = new InboundMarkPdfService(
|
||||
properties,
|
||||
new PdfGenerationLimiter(properties),
|
||||
new InboundMarkV1Renderer(qrRenderer),
|
||||
qrRenderer);
|
||||
InboundMarkPdfDtos.Request request = new InboundMarkPdfDtos.Request(
|
||||
"INBOUND_MARK_V1",
|
||||
new InboundMarkPdfDtos.PageSpec(new BigDecimal("100"), new BigDecimal("100.0")),
|
||||
|
||||
+8
-11
@@ -10,23 +10,20 @@ import com.baiyue.print.config.PrintPdfProperties;
|
||||
import com.baiyue.print.dto.InboundMarkPdfDtos;
|
||||
import com.baiyue.print.renderer.InboundMarkV1Renderer;
|
||||
import com.baiyue.print.renderer.PdfQrRenderer;
|
||||
import jakarta.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
@SpringJUnitConfig(classes = {InboundMarkPdfService.class, PrintPdfProperties.class})
|
||||
class InboundMarkPdfServiceValidationTest {
|
||||
private InboundMarkPdfService service;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
PrintPdfProperties properties = new PrintPdfProperties();
|
||||
service = new InboundMarkPdfService(
|
||||
properties,
|
||||
mock(PdfGenerationLimiter.class),
|
||||
mock(InboundMarkV1Renderer.class),
|
||||
mock(PdfQrRenderer.class));
|
||||
}
|
||||
@MockBean private PdfGenerationLimiter limiter;
|
||||
@MockBean private InboundMarkV1Renderer renderer;
|
||||
@MockBean private PdfQrRenderer qrRenderer;
|
||||
@Resource private InboundMarkPdfService service;
|
||||
|
||||
@Test
|
||||
void rejectsUnsupportedPageSizeBeforeRendering() {
|
||||
|
||||
@@ -7,15 +7,16 @@ import com.baiyue.common.core.exception.BizException;
|
||||
import com.baiyue.print.config.PrintPdfProperties;
|
||||
import java.time.Duration;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
@SpringJUnitConfig(classes = {PdfGenerationLimiter.class, PdfGenerationLimiterTest.TestConfig.class})
|
||||
class PdfGenerationLimiterTest {
|
||||
@Resource private PdfGenerationLimiter limiter;
|
||||
@Test
|
||||
void rejectsWhenAllPermitsAreInUseAndReleasesPermitOnClose() {
|
||||
PrintPdfProperties properties = new PrintPdfProperties();
|
||||
properties.setMaxConcurrentGenerations(1);
|
||||
properties.setAcquireTimeout(Duration.ZERO);
|
||||
PdfGenerationLimiter limiter = new PdfGenerationLimiter(properties);
|
||||
|
||||
PdfGenerationLimiter.Permit permit = limiter.acquire();
|
||||
assertThatThrownBy(limiter::acquire)
|
||||
.isInstanceOfSatisfying(BizException.class,
|
||||
@@ -27,4 +28,15 @@ class PdfGenerationLimiterTest {
|
||||
// A second acquisition proves that close returned the only permit.
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class TestConfig {
|
||||
@Bean
|
||||
PrintPdfProperties properties() {
|
||||
PrintPdfProperties properties = new PrintPdfProperties();
|
||||
properties.setMaxConcurrentGenerations(1);
|
||||
properties.setAcquireTimeout(Duration.ZERO);
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user