From 3570095918c28fc4cf386a8efee29efdc62c1013 Mon Sep 17 00:00:00 2001 From: Celestino Bellone <3385346+cbellone@users.noreply.github.com> Date: Thu, 25 Apr 2024 18:18:10 +0200 Subject: [PATCH] optimize dependencies + replace opencsv with jackson --- build.gradle | 12 +-- .../api/admin/EventApiController.java | 32 +++--- .../api/admin/SpecialPriceApiController.java | 22 ++--- .../api/v1/admin/EventApiV1Controller.java | 3 +- .../form/ContactAndTicketsForm.java | 2 +- .../AdminReservationRequestManager.java | 6 +- .../java/alfio/manager/CheckInManager.java | 2 +- src/main/java/alfio/manager/EventManager.java | 6 +- src/main/java/alfio/manager/GroupManager.java | 3 +- .../manager/SpecialPriceTokenGenerator.java | 2 +- .../alfio/manager/system/SendGridMailer.java | 5 +- ...FieldConfigurationDescriptionAndValue.java | 2 +- .../java/alfio/model/PromoCodeDiscount.java | 2 +- .../PurchaseContextFieldConfiguration.java | 2 +- .../api/v1/admin/EventCreationRequest.java | 2 +- src/main/java/alfio/model/result/Result.java | 2 +- src/main/java/alfio/util/ExportUtils.java | 23 +++-- src/main/java/alfio/util/Validator.java | 2 +- .../reservation/BaseReservationFlowTest.java | 97 ++++++++++++------- .../manager/EventManagerCategoriesTest.java | 2 +- .../EventManagerCheckInConfigurationTest.java | 2 +- ...ntManagerHandleTicketModificationTest.java | 2 +- ...entManagerHandleTokenModificationTest.java | 2 +- .../EventManagerUnbindTicketsTest.java | 6 +- .../alfio/util/RefreshableDataSource.java | 23 ----- 25 files changed, 133 insertions(+), 131 deletions(-) diff --git a/build.gradle b/build.gradle index 6b2aeb3fd5..57d5838e48 100644 --- a/build.gradle +++ b/build.gradle @@ -35,7 +35,7 @@ plugins { id 'com.github.ben-manes.versions' version '0.51.0' id 'com.github.hierynomus.license' version '0.16.1' id 'net.researchgate.release' version '3.0.2' - id 'org.springframework.boot' version '3.2.0' + id 'org.springframework.boot' version '3.2.5' id 'org.sonarqube' version '4.4.1.3373' // id 'net.ltgt.errorprone' version '3.1.0' id 'com.github.node-gradle.node' version '7.0.2' @@ -102,8 +102,9 @@ repositories { } dependencies { - implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" implementation 'com.auth0:java-jwt:4.4.0' + implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" + implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-csv" implementation "com.fasterxml.jackson.core:jackson-core" implementation "com.fasterxml.jackson.core:jackson-databind" implementation "org.springframework.boot:spring-boot-properties-migrator", { @@ -133,10 +134,9 @@ dependencies { exclude module: 'gson' } - implementation "org.apache.commons:commons-lang3:3.13.0" - implementation 'com.opencsv:opencsv:5.9', { - exclude module: 'commons-collections:commons-collections:3.2.2' - } + implementation 'org.apache.commons:commons-lang3:3.13.0' + implementation 'org.apache.commons:commons-text:1.12.0' + implementation 'org.apache.commons:commons-collections4:4.4' implementation 'commons-codec:commons-codec:1.15' implementation 'net.sf.biweekly:biweekly:0.6.6' implementation 'com.atlassian.commonmark:commonmark:0.17.0' diff --git a/src/main/java/alfio/controller/api/admin/EventApiController.java b/src/main/java/alfio/controller/api/admin/EventApiController.java index a1b974cc8d..99f06e698d 100644 --- a/src/main/java/alfio/controller/api/admin/EventApiController.java +++ b/src/main/java/alfio/controller/api/admin/EventApiController.java @@ -42,8 +42,9 @@ import alfio.repository.PurchaseContextFieldRepository; import alfio.repository.SponsorScanRepository; import alfio.util.*; -import com.opencsv.CSVReader; -import com.opencsv.exceptions.CsvException; +import com.fasterxml.jackson.databind.MappingIterator; +import com.fasterxml.jackson.dataformat.csv.CsvMapper; +import com.fasterxml.jackson.dataformat.csv.CsvSchema; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.AllArgsConstructor; @@ -465,7 +466,7 @@ public void downloadSponsorScanExport(@PathVariable String eventName, @RequestPa header.add("Timestamp"); header.add("Full name"); header.add("Email"); - header.addAll(fields.stream().map(PurchaseContextFieldConfiguration::getName).collect(toList())); + header.addAll(fields.stream().map(PurchaseContextFieldConfiguration::getName).toList()); header.add("Sponsor notes"); header.add("Lead Status"); header.add("Operator"); @@ -576,27 +577,28 @@ public String deletePendingPayment(@PathVariable String eventName, @PostMapping("/events/{eventName}/pending-payments/bulk-confirmation") public List> bulkConfirmation(@PathVariable String eventName, Principal principal, - @RequestBody UploadBase64FileModification file) throws IOException, CsvException { - try(InputStreamReader isr = new InputStreamReader(file.getInputStream(), UTF_8); CSVReader reader = new CSVReader(isr)) { - var all = reader.readAll(); + @RequestBody UploadBase64FileModification file) throws IOException { + record Transaction(String reservationId, BigDecimal price) {} + var csvMapper = new CsvMapper(); + try(InputStreamReader isr = new InputStreamReader(file.getInputStream(), UTF_8)) { + MappingIterator iterator = csvMapper.readerFor(Transaction.class) + .with(CsvSchema.emptySchema().withoutHeader()) + .readValues(isr); + var all = iterator.readAll(); + var reservationIds = all.stream() - .map(line -> { - Validate.isTrue(line.length >= 2); - return line[0]; - }) + .map(Transaction::reservationId) .collect(Collectors.toSet()); accessService.checkEventAndReservationOwnership(principal, eventName, reservationIds); Event event = loadEvent(eventName, principal); return all.stream() .map(line -> { - String reservationID = null; try { - reservationID = line[0]; - ticketReservationManager.validateAndConfirmOfflinePayment(reservationID, event, new BigDecimal(line[1]), principal.getName()); - return Triple.of(Boolean.TRUE, reservationID, ""); + ticketReservationManager.validateAndConfirmOfflinePayment(line.reservationId, event, line.price, principal.getName()); + return Triple.of(Boolean.TRUE, line.reservationId, ""); } catch (Exception e) { - return Triple.of(Boolean.FALSE, Optional.ofNullable(reservationID).orElse(""), e.getMessage()); + return Triple.of(Boolean.FALSE, Optional.ofNullable(line.reservationId).orElse(""), e.getMessage()); } }) .collect(toList()); diff --git a/src/main/java/alfio/controller/api/admin/SpecialPriceApiController.java b/src/main/java/alfio/controller/api/admin/SpecialPriceApiController.java index 8b8b59f433..8ce281fcab 100644 --- a/src/main/java/alfio/controller/api/admin/SpecialPriceApiController.java +++ b/src/main/java/alfio/controller/api/admin/SpecialPriceApiController.java @@ -21,8 +21,9 @@ import alfio.model.SpecialPrice; import alfio.model.modification.SendCodeModification; import alfio.model.modification.UploadBase64FileModification; -import com.opencsv.CSVReader; -import com.opencsv.exceptions.CsvException; +import com.fasterxml.jackson.databind.MappingIterator; +import com.fasterxml.jackson.dataformat.csv.CsvMapper; +import com.fasterxml.jackson.dataformat.csv.CsvSchema; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.Validate; import org.slf4j.Logger; @@ -36,10 +37,8 @@ import java.security.Principal; import java.util.List; import java.util.Objects; -import java.util.stream.Collectors; import static java.nio.charset.StandardCharsets.UTF_8; -import static org.apache.commons.lang3.StringUtils.trim; @RestController @RequestMapping("/admin/api") @@ -69,18 +68,15 @@ public ResponseEntity handleExceptions(Exception e) { public ResponseEntity> linkAssigneeToCodes(@PathVariable String eventName, @PathVariable int categoryId, @RequestBody UploadBase64FileModification file, - Principal principal) throws IOException, CsvException { + Principal principal) throws IOException { Validate.isTrue(StringUtils.isNotEmpty(eventName)); accessService.checkCategoryOwnership(principal, eventName, categoryId); - try(InputStreamReader isr = new InputStreamReader(file.getInputStream(), UTF_8); CSVReader reader = new CSVReader(isr)) { - List content = reader.readAll().stream() - .map(line -> { - Validate.isTrue(line.length >= 4); - return new SendCodeModification(StringUtils.trimToNull(line[0]), trim(line[1]), trim(line[2]), trim(line[3])); - }) - .collect(Collectors.toList()); - return ResponseEntity.ok(specialPriceManager.linkAssigneeToCode(content, eventName, categoryId, principal.getName())); + try(InputStreamReader isr = new InputStreamReader(file.getInputStream(), UTF_8)) { + MappingIterator iterator = new CsvMapper().readerFor(SendCodeModification.class) + .with(CsvSchema.emptySchema().withoutHeader()) + .readValues(isr); + return ResponseEntity.ok(specialPriceManager.linkAssigneeToCode(iterator.readAll(), eventName, categoryId, principal.getName())); } } diff --git a/src/main/java/alfio/controller/api/v1/admin/EventApiV1Controller.java b/src/main/java/alfio/controller/api/v1/admin/EventApiV1Controller.java index bef0a490b6..2fa2909523 100644 --- a/src/main/java/alfio/controller/api/v1/admin/EventApiV1Controller.java +++ b/src/main/java/alfio/controller/api/v1/admin/EventApiV1Controller.java @@ -43,8 +43,7 @@ import alfio.repository.ExtensionRepository; import alfio.util.Json; import lombok.AllArgsConstructor; -import lombok.extern.log4j.Log4j2; -import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.tuple.Pair; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/alfio/controller/form/ContactAndTicketsForm.java b/src/main/java/alfio/controller/form/ContactAndTicketsForm.java index 46f0b95bde..7b81c6184f 100644 --- a/src/main/java/alfio/controller/form/ContactAndTicketsForm.java +++ b/src/main/java/alfio/controller/form/ContactAndTicketsForm.java @@ -32,7 +32,7 @@ import alfio.util.ItalianTaxIdValidator; import alfio.util.Validator; import lombok.Data; -import org.apache.commons.collections.MapUtils; +import org.apache.commons.collections4.MapUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.validation.BindingResult; import org.springframework.validation.ValidationUtils; diff --git a/src/main/java/alfio/manager/AdminReservationRequestManager.java b/src/main/java/alfio/manager/AdminReservationRequestManager.java index ebb04d0929..9100a91369 100644 --- a/src/main/java/alfio/manager/AdminReservationRequestManager.java +++ b/src/main/java/alfio/manager/AdminReservationRequestManager.java @@ -26,10 +26,7 @@ import alfio.repository.AdminReservationRequestRepository; import alfio.repository.EventRepository; import alfio.repository.user.UserRepository; -import alfio.util.ClockProvider; import lombok.RequiredArgsConstructor; -import lombok.extern.log4j.Log4j2; -import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Triple; @@ -53,6 +50,7 @@ import static alfio.model.modification.AdminReservationModification.Notification.orEmpty; import static java.util.Collections.singletonList; import static java.util.Optional.ofNullable; +import static org.apache.commons.collections4.CollectionUtils.size; @Component @Transactional @@ -128,7 +126,7 @@ public Pair processPendingReservations() { } }); - return Pair.of(CollectionUtils.size(result.get(true)), CollectionUtils.size(result.get(false))); + return Pair.of(size(result.get(true)), size(result.get(false))); } diff --git a/src/main/java/alfio/manager/CheckInManager.java b/src/main/java/alfio/manager/CheckInManager.java index 99ded75b4e..cd64547796 100644 --- a/src/main/java/alfio/manager/CheckInManager.java +++ b/src/main/java/alfio/manager/CheckInManager.java @@ -35,7 +35,7 @@ import lombok.AllArgsConstructor; import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.digest.DigestUtils; -import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.tuple.Pair; diff --git a/src/main/java/alfio/manager/EventManager.java b/src/main/java/alfio/manager/EventManager.java index e564951acf..12c58dac7f 100644 --- a/src/main/java/alfio/manager/EventManager.java +++ b/src/main/java/alfio/manager/EventManager.java @@ -48,7 +48,6 @@ import alfio.util.RequestUtils; import ch.digitalfondue.npjt.AffectedRowCountAndKey; import lombok.AllArgsConstructor; -import lombok.extern.log4j.Log4j2; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.IterableUtils; import org.apache.commons.lang3.ObjectUtils; @@ -108,7 +107,6 @@ public class EventManager { private final SpecialPriceRepository specialPriceRepository; private final PromoCodeDiscountRepository promoCodeRepository; private final ConfigurationManager configurationManager; - private final PurchaseContextFieldRepository purchaseContextFieldRepository; private final EventDeleterRepository eventDeleterRepository; private final PurchaseContextFieldManager purchaseContextFieldManager; private final Flyway flyway; @@ -824,13 +822,13 @@ void handleTicketNumberModification(Event event, TicketCategory updated, int add } private void createAllTicketsForEvent(Event event, EventModification em) { - Validate.notNull(em.getAvailableSeats()); + Objects.requireNonNull(em.getAvailableSeats()); final MapSqlParameterSource[] params = prepareTicketsBulkInsertParameters(event.now(clockProvider), event, em.getAvailableSeats(), TicketStatus.FREE); ticketRepository.bulkTicketInitialization(params); } private int insertEvent(EventModification em) { - Validate.notNull(em.getAvailableSeats()); + Objects.requireNonNull(em.getAvailableSeats()); validatePaymentProxies(em.getAllowedPaymentProxies(), em.getOrganizationId()); String paymentProxies = collectPaymentProxies(em); BigDecimal vat = em.isFreeOfCharge() ? BigDecimal.ZERO : em.getVatPercentage(); diff --git a/src/main/java/alfio/manager/GroupManager.java b/src/main/java/alfio/manager/GroupManager.java index 79472f5b73..680a9400c1 100644 --- a/src/main/java/alfio/manager/GroupManager.java +++ b/src/main/java/alfio/manager/GroupManager.java @@ -31,8 +31,7 @@ import alfio.repository.TicketRepository; import ch.digitalfondue.npjt.AffectedRowCountAndKey; import lombok.RequiredArgsConstructor; -import lombok.extern.log4j.Log4j2; -import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.Validate; import org.slf4j.Logger; diff --git a/src/main/java/alfio/manager/SpecialPriceTokenGenerator.java b/src/main/java/alfio/manager/SpecialPriceTokenGenerator.java index 1d70ab76a7..64de993e3f 100644 --- a/src/main/java/alfio/manager/SpecialPriceTokenGenerator.java +++ b/src/main/java/alfio/manager/SpecialPriceTokenGenerator.java @@ -57,7 +57,7 @@ public class SpecialPriceTokenGenerator { private static final RandomStringGenerator RANDOM_STRING_GENERATOR = new RandomStringGenerator.Builder() .selectFrom(ADMITTED_CHARACTERS) .usingRandom(RANDOM::nextInt) - .build(); + .get(); private final SpecialPriceRepository specialPriceRepository; private final TicketCategoryRepository ticketCategoryRepository; diff --git a/src/main/java/alfio/manager/system/SendGridMailer.java b/src/main/java/alfio/manager/system/SendGridMailer.java index 75eb5bea96..189d71d8c7 100644 --- a/src/main/java/alfio/manager/system/SendGridMailer.java +++ b/src/main/java/alfio/manager/system/SendGridMailer.java @@ -21,8 +21,7 @@ import alfio.repository.user.OrganizationRepository; import alfio.util.HttpUtils; import alfio.util.Json; -import lombok.extern.log4j.Log4j2; -import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.ArrayUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -94,7 +93,7 @@ private List> createPersonalizations(final String to, final final var recipients = new ArrayList<>(); recipients.add(Map.of(EMAIL, to)); if (CollectionUtils.isNotEmpty(cc)) { - recipients.addAll(cc.stream().map(email -> Map.of(EMAIL, email)).collect(Collectors.toList())); + recipients.addAll(cc.stream().map(email -> Map.of(EMAIL, email)).toList()); } return List.of(Map.of("to", recipients, "subject", subject)); } diff --git a/src/main/java/alfio/model/FieldConfigurationDescriptionAndValue.java b/src/main/java/alfio/model/FieldConfigurationDescriptionAndValue.java index 6d418b8859..e88039308b 100644 --- a/src/main/java/alfio/model/FieldConfigurationDescriptionAndValue.java +++ b/src/main/java/alfio/model/FieldConfigurationDescriptionAndValue.java @@ -22,7 +22,7 @@ import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.experimental.Delegate; -import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Triple; diff --git a/src/main/java/alfio/model/PromoCodeDiscount.java b/src/main/java/alfio/model/PromoCodeDiscount.java index 18505bbcb1..61b35a1ec5 100644 --- a/src/main/java/alfio/model/PromoCodeDiscount.java +++ b/src/main/java/alfio/model/PromoCodeDiscount.java @@ -21,7 +21,7 @@ import ch.digitalfondue.npjt.ConstructorAnnotationRowMapper.Column; import com.google.gson.reflect.TypeToken; import lombok.Getter; -import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import java.time.ZoneId; diff --git a/src/main/java/alfio/model/PurchaseContextFieldConfiguration.java b/src/main/java/alfio/model/PurchaseContextFieldConfiguration.java index ee49981414..cc15b3130b 100644 --- a/src/main/java/alfio/model/PurchaseContextFieldConfiguration.java +++ b/src/main/java/alfio/model/PurchaseContextFieldConfiguration.java @@ -20,7 +20,7 @@ import ch.digitalfondue.npjt.ConstructorAnnotationRowMapper.Column; import com.google.gson.reflect.TypeToken; import lombok.Getter; -import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections4.CollectionUtils; import java.util.*; import java.util.regex.Pattern; diff --git a/src/main/java/alfio/model/api/v1/admin/EventCreationRequest.java b/src/main/java/alfio/model/api/v1/admin/EventCreationRequest.java index ad17f6b6e4..8936c782f8 100644 --- a/src/main/java/alfio/model/api/v1/admin/EventCreationRequest.java +++ b/src/main/java/alfio/model/api/v1/admin/EventCreationRequest.java @@ -41,7 +41,7 @@ import java.util.stream.Collectors; import static java.util.Collections.emptyList; -import static org.apache.commons.collections.CollectionUtils.isEmpty; +import static org.apache.commons.collections4.CollectionUtils.isEmpty; @Getter @AllArgsConstructor diff --git a/src/main/java/alfio/model/result/Result.java b/src/main/java/alfio/model/result/Result.java index ad6386fa61..4f748d7745 100644 --- a/src/main/java/alfio/model/result/Result.java +++ b/src/main/java/alfio/model/result/Result.java @@ -19,7 +19,7 @@ import alfio.model.result.ValidationResult.ErrorDescriptor; import lombok.AllArgsConstructor; import lombok.Getter; -import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.tuple.Pair; import org.springframework.validation.ObjectError; diff --git a/src/main/java/alfio/util/ExportUtils.java b/src/main/java/alfio/util/ExportUtils.java index 725a9c9f37..b4832f94f3 100644 --- a/src/main/java/alfio/util/ExportUtils.java +++ b/src/main/java/alfio/util/ExportUtils.java @@ -19,20 +19,18 @@ import ch.digitalfondue.basicxlsx.Cell; import ch.digitalfondue.basicxlsx.StreamingWorkbook; import ch.digitalfondue.basicxlsx.Style; -import com.opencsv.CSVWriter; -import org.apache.commons.lang3.StringUtils; - +import com.fasterxml.jackson.dataformat.csv.CsvMapper; +import com.fasterxml.jackson.dataformat.csv.CsvSchema; import jakarta.servlet.ServletOutputStream; import jakarta.servlet.http.HttpServletResponse; +import org.apache.commons.lang3.StringUtils; + import java.io.IOException; -import java.io.OutputStreamWriter; import java.util.Arrays; import java.util.function.Consumer; import java.util.stream.Collectors; import java.util.stream.Stream; -import static java.nio.charset.StandardCharsets.UTF_8; - public class ExportUtils { private static final int[] BOM_MARKERS = new int[] {0xEF, 0xBB, 0xBF}; @@ -93,18 +91,25 @@ public static void exportCsv(String fileName, String[] header, Stream response.setHeader("Content-Disposition", "attachment; filename=" + fileName); markAsNoIndex(response); - try (ServletOutputStream out = response.getOutputStream(); CSVWriter writer = new CSVWriter(new OutputStreamWriter(out, UTF_8))) { + var headerBuilder = CsvSchema.builder().setUseHeader(true).setQuoteChar('"'); + Arrays.stream(header).forEach(headerBuilder::addColumn); + + try (ServletOutputStream out = response.getOutputStream()) { for (int marker : ExportUtils.BOM_MARKERS) { out.write(marker); } - writer.writeNext(header); + var writer = new CsvMapper().writer().with(headerBuilder.build()).writeValues(out); data.forEachOrdered(d -> { var copy = Arrays.copyOf(d, d.length); for (var i = 0; i < copy.length; i++) { var res = copy[i]; copy[i] = escapeFormulaChar(res); } - writer.writeNext(copy); + try { + writer.write(copy); + } catch (IOException e) { + throw new RuntimeException(e); + } }); writer.flush(); out.flush(); diff --git a/src/main/java/alfio/util/Validator.java b/src/main/java/alfio/util/Validator.java index b13a0928d3..cae94de252 100644 --- a/src/main/java/alfio/util/Validator.java +++ b/src/main/java/alfio/util/Validator.java @@ -33,7 +33,7 @@ import alfio.model.result.Result; import alfio.model.result.ValidationResult; import lombok.RequiredArgsConstructor; -import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.Validate; import org.springframework.validation.BindingResult; diff --git a/src/test/java/alfio/controller/api/v2/user/reservation/BaseReservationFlowTest.java b/src/test/java/alfio/controller/api/v2/user/reservation/BaseReservationFlowTest.java index 605f9192f4..da734e19e8 100644 --- a/src/test/java/alfio/controller/api/v2/user/reservation/BaseReservationFlowTest.java +++ b/src/test/java/alfio/controller/api/v2/user/reservation/BaseReservationFlowTest.java @@ -58,16 +58,22 @@ import ch.digitalfondue.jfiveparse.Element; import ch.digitalfondue.jfiveparse.Parser; import ch.digitalfondue.jfiveparse.Selector; +import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.MappingIterator; +import com.fasterxml.jackson.dataformat.csv.CsvMapper; +import com.fasterxml.jackson.dataformat.csv.CsvParser; +import com.fasterxml.jackson.dataformat.csv.CsvSchema; import com.google.zxing.BinaryBitmap; import com.google.zxing.DecodeHintType; import com.google.zxing.client.j2se.BufferedImageLuminanceSource; import com.google.zxing.common.HybridBinarizer; import com.google.zxing.qrcode.QRCodeReader; -import com.opencsv.CSVReader; import lombok.RequiredArgsConstructor; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.io.IOUtils; +import org.apache.commons.io.input.BOMInputStream; +import org.apache.commons.lang3.StringUtils; import org.junit.jupiter.api.Assertions; import org.mockito.Mockito; import org.slf4j.Logger; @@ -1268,15 +1274,34 @@ protected void testBasicFlow(Supplier contextSupplier) t MockHttpServletResponse response = new MockHttpServletResponse(); eventApiController.downloadSponsorScanExport(context.event.getShortName(), "csv", response, principal); response.getContentAsString(); - CSVReader csvReader = new CSVReader(new StringReader(response.getContentAsString())); - List csvSponsorScan = csvReader.readAll(); - assertEquals(2, csvSponsorScan.size()); - assertEquals("sponsor", csvSponsorScan.get(1)[0]); - assertEquals("Test Testson", csvSponsorScan.get(1)[3]); - assertEquals("testmctest@test.com", csvSponsorScan.get(1)[4]); - assertEquals("", csvSponsorScan.get(1)[8]); - assertEquals(SponsorScan.LeadStatus.WARM.name(), csvSponsorScan.get(1)[9]); - assertEquals(AttendeeManager.DEFAULT_OPERATOR_ID, csvSponsorScan.get(1)[10]); + var schema = CsvSchema.builder().setUseHeader(true).setQuoteChar('"').build(); + var mapper = new CsvMapper(); + record SponsorScanRecord( + @JsonProperty("Username/Api Key") String username, + @JsonProperty("Description") String description, + @JsonProperty("Timestamp") String timestamp, + @JsonProperty("Full name") String fullName, + @JsonProperty("Email") String email, + @JsonProperty("field1") String field1, + @JsonProperty("field2") String field2, + @JsonProperty("field3") String field3, + @JsonProperty("Sponsor notes") String notes, + @JsonProperty("Lead Status") SponsorScan.LeadStatus leadStatus, + @JsonProperty("Operator") String operator + ) {} + + MappingIterator values = mapper.readerFor(SponsorScanRecord.class) + .with(schema) + .readValues(BOMInputStream.builder().setReader(new StringReader(response.getContentAsString())).get()); + + List csvSponsorScan = values.readAll(); + assertEquals(1, csvSponsorScan.size()); + assertEquals("sponsor", csvSponsorScan.get(0).username); + assertEquals("Test Testson", csvSponsorScan.get(0).fullName); + assertEquals("testmctest@test.com", csvSponsorScan.get(0).email); + assertEquals("", csvSponsorScan.get(0).notes); + assertEquals(SponsorScan.LeadStatus.WARM, csvSponsorScan.get(0).leadStatus); + assertEquals(AttendeeManager.DEFAULT_OPERATOR_ID, csvSponsorScan.get(0).operator); // // check update notes @@ -1288,35 +1313,39 @@ protected void testBasicFlow(Supplier contextSupplier) t assertEquals(1, requireNonNull(scannedBadges).size()); response = new MockHttpServletResponse(); eventApiController.downloadSponsorScanExport(context.event.getShortName(), "csv", response, principal); - csvReader = new CSVReader(new StringReader(response.getContentAsString())); - csvSponsorScan = csvReader.readAll(); - assertEquals(2, csvSponsorScan.size()); - assertEquals("sponsor", csvSponsorScan.get(1)[0]); - assertEquals("Test Testson", csvSponsorScan.get(1)[3]); - assertEquals("testmctest@test.com", csvSponsorScan.get(1)[4]); - assertEquals("this is a very good lead!", csvSponsorScan.get(1)[8]); - assertEquals(SponsorScan.LeadStatus.HOT.name(), csvSponsorScan.get(1)[9]); - assertEquals(AttendeeManager.DEFAULT_OPERATOR_ID, csvSponsorScan.get(1)[10]); + values = mapper.readerFor(SponsorScanRecord.class) + .with(schema) + .readValues(BOMInputStream.builder().setReader(new StringReader(response.getContentAsString())).get()); + csvSponsorScan = values.readAll(); + assertEquals(1, csvSponsorScan.size()); + assertEquals("sponsor", csvSponsorScan.get(0).username); + assertEquals("Test Testson", csvSponsorScan.get(0).fullName); + assertEquals("testmctest@test.com", csvSponsorScan.get(0).email); + assertEquals("this is a very good lead!", csvSponsorScan.get(0).notes); + assertEquals(SponsorScan.LeadStatus.HOT, csvSponsorScan.get(0).leadStatus); + assertEquals(AttendeeManager.DEFAULT_OPERATOR_ID, csvSponsorScan.get(0).operator); // scan from a different operator response = new MockHttpServletResponse(); assertEquals(CheckInStatus.SUCCESS, attendeeApiController.scanBadge(new AttendeeApiController.SponsorScanRequest(eventName, ticketwc.getUuid(), null, null, null), sponsorPrincipal, "OP2").getBody().getResult().getStatus()); eventApiController.downloadSponsorScanExport(context.event.getShortName(), "csv", response, principal); - csvReader = new CSVReader(new StringReader(response.getContentAsString())); - csvSponsorScan = csvReader.readAll(); - assertEquals(3, csvSponsorScan.size()); - assertEquals("sponsor", csvSponsorScan.get(1)[0]); - assertEquals("Test Testson", csvSponsorScan.get(1)[3]); - assertEquals("testmctest@test.com", csvSponsorScan.get(1)[4]); - assertEquals("this is a very good lead!", csvSponsorScan.get(1)[8]); - assertEquals(SponsorScan.LeadStatus.HOT.name(), csvSponsorScan.get(1)[9]); - assertEquals(AttendeeManager.DEFAULT_OPERATOR_ID, csvSponsorScan.get(1)[10]); - - assertEquals("sponsor", csvSponsorScan.get(2)[0]); - assertEquals("Test Testson", csvSponsorScan.get(2)[3]); - assertEquals("testmctest@test.com", csvSponsorScan.get(2)[4]); - assertEquals("", csvSponsorScan.get(2)[8]); - assertEquals("OP2", csvSponsorScan.get(2)[10]); + values = mapper.readerFor(SponsorScanRecord.class) + .with(schema) + .readValues(BOMInputStream.builder().setReader(new StringReader(response.getContentAsString())).get()); + csvSponsorScan = values.readAll(); + assertEquals(2, csvSponsorScan.size()); + assertEquals("sponsor", csvSponsorScan.get(0).username); + assertEquals("Test Testson", csvSponsorScan.get(0).fullName); + assertEquals("testmctest@test.com", csvSponsorScan.get(0).email); + assertEquals("this is a very good lead!", csvSponsorScan.get(0).notes); + assertEquals(SponsorScan.LeadStatus.HOT, csvSponsorScan.get(0).leadStatus); + assertEquals(AttendeeManager.DEFAULT_OPERATOR_ID, csvSponsorScan.get(0).operator); + + assertEquals("sponsor", csvSponsorScan.get(1).username); + assertEquals("Test Testson", csvSponsorScan.get(1).fullName); + assertEquals("testmctest@test.com", csvSponsorScan.get(1).email); + assertEquals("", csvSponsorScan.get(1).notes); + assertEquals("OP2", csvSponsorScan.get(1).operator); // #742 - test multiple check-ins diff --git a/src/test/java/alfio/manager/EventManagerCategoriesTest.java b/src/test/java/alfio/manager/EventManagerCategoriesTest.java index 1da4eb0ce8..a55ead4172 100644 --- a/src/test/java/alfio/manager/EventManagerCategoriesTest.java +++ b/src/test/java/alfio/manager/EventManagerCategoriesTest.java @@ -58,7 +58,7 @@ void init() { EventRepository eventRepository = mock(EventRepository.class); event = mock(Event.class); when(event.getId()).thenReturn(eventId); - eventManager = new EventManager(null, eventRepository, null, ticketCategoryRepository, ticketCategoryDescriptionRepository, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, clockProvider(), mock(SubscriptionRepository.class), null); + eventManager = new EventManager(null, eventRepository, null, ticketCategoryRepository, ticketCategoryDescriptionRepository, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, clockProvider(), mock(SubscriptionRepository.class), null); when(eventRepository.countExistingTickets(0)).thenReturn(availableSeats); when(event.getZoneId()).thenReturn(ZoneId.systemDefault()); } diff --git a/src/test/java/alfio/manager/EventManagerCheckInConfigurationTest.java b/src/test/java/alfio/manager/EventManagerCheckInConfigurationTest.java index e6331e4a00..a8ef832d43 100644 --- a/src/test/java/alfio/manager/EventManagerCheckInConfigurationTest.java +++ b/src/test/java/alfio/manager/EventManagerCheckInConfigurationTest.java @@ -50,7 +50,7 @@ void init() { when(event.getOrganizationId()).thenReturn(1); configurationManager = mock(ConfigurationManager.class); configurationRepository = mock(ConfigurationRepository.class); - eventManager = new EventManager(null, null, null, null, null, null, null, null, configurationManager, null, null, null, null, null, null, null, null, null, null, configurationRepository, null, TestUtil.clockProvider(), mock(SubscriptionRepository.class), null); + eventManager = new EventManager(null, null, null, null, null, null, null, null, configurationManager, null, null, null, null, null, null, null, null, null, configurationRepository, null, TestUtil.clockProvider(), mock(SubscriptionRepository.class), null); when(event.getZoneId()).thenReturn(ZoneId.systemDefault()); configuration = mock(ConfigurationManager.MaybeConfiguration.class); when(configurationManager.getFor(eq(CHECK_IN_COLOR_CONFIGURATION), any())).thenReturn(configuration); diff --git a/src/test/java/alfio/manager/EventManagerHandleTicketModificationTest.java b/src/test/java/alfio/manager/EventManagerHandleTicketModificationTest.java index 7384b594dd..dccec1edf4 100644 --- a/src/test/java/alfio/manager/EventManagerHandleTicketModificationTest.java +++ b/src/test/java/alfio/manager/EventManagerHandleTicketModificationTest.java @@ -58,7 +58,7 @@ void init() { when(event.getId()).thenReturn(eventId); when(event.now(any(ClockProvider.class))).thenReturn(ZonedDateTime.now(clockProvider().getClock().withZone(ZoneId.systemDefault()))); - eventManager = new EventManager(null, null, null, null, null, ticketRepository, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, clockProvider(), mock(SubscriptionRepository.class), null); + eventManager = new EventManager(null, null, null, null, null, ticketRepository, null, null, null, null, null, null, null, null, null, null, null, null, null, null, clockProvider(), mock(SubscriptionRepository.class), null); when(original.getId()).thenReturn(originalCategoryId); when(updated.getId()).thenReturn(updatedCategoryId); when(original.getSrcPriceCts()).thenReturn(1000); diff --git a/src/test/java/alfio/manager/EventManagerHandleTokenModificationTest.java b/src/test/java/alfio/manager/EventManagerHandleTokenModificationTest.java index cbf8251b2c..6c84f97910 100644 --- a/src/test/java/alfio/manager/EventManagerHandleTokenModificationTest.java +++ b/src/test/java/alfio/manager/EventManagerHandleTokenModificationTest.java @@ -53,7 +53,7 @@ void init() { TicketRepository ticketRepository = mock(TicketRepository.class); when(event.getId()).thenReturn(eventId); eventManager = new EventManager(null, null, null, null, - null, ticketRepository, specialPriceRepository, null, null, null, null, null, null, null, null, null, null, null, null, null, null, TestUtil.clockProvider(), mock(SubscriptionRepository.class), null); + null, ticketRepository, specialPriceRepository, null, null, null, null, null, null, null, null, null, null, null, null, null, TestUtil.clockProvider(), mock(SubscriptionRepository.class), null); when(original.getId()).thenReturn(20); when(updated.getId()).thenReturn(30); when(original.getSrcPriceCts()).thenReturn(1000); diff --git a/src/test/java/alfio/manager/EventManagerUnbindTicketsTest.java b/src/test/java/alfio/manager/EventManagerUnbindTicketsTest.java index 3e6793036c..7a0568e631 100644 --- a/src/test/java/alfio/manager/EventManagerUnbindTicketsTest.java +++ b/src/test/java/alfio/manager/EventManagerUnbindTicketsTest.java @@ -85,9 +85,9 @@ void setUp() { eventDescriptionRepository, ticketCategoryRepository, ticketCategoryDescriptionRepository, ticketRepository, specialPriceRepository, null, null, null, null, null, null, - null, organizationRepository, - null, null, null, null, null, - null, TestUtil.clockProvider(), mock(SubscriptionRepository.class), null); + organizationRepository, + null, null, null, null, null, null, + TestUtil.clockProvider(), mock(SubscriptionRepository.class), null); } @Test diff --git a/src/test/java/alfio/util/RefreshableDataSource.java b/src/test/java/alfio/util/RefreshableDataSource.java index b61f997a6d..4b75659b55 100644 --- a/src/test/java/alfio/util/RefreshableDataSource.java +++ b/src/test/java/alfio/util/RefreshableDataSource.java @@ -41,27 +41,4 @@ public DataSource getTargetDataSource() { public void refresh() { this.dataSource.getAndSet(new HikariDataSource(config)).close(); } - - public boolean isWrapperFor(Class iface) throws java.sql.SQLException { - // TODO Auto-generated method stub - return iface != null && iface.isAssignableFrom(this.getClass()); - } - - public T unwrap(Class iface) throws java.sql.SQLException { - // TODO Auto-generated method stub - try { - if(iface != null && iface.isAssignableFrom(this.getClass())) { - return (T) this; - } - throw new java.sql.SQLException("Auto-generated unwrap failed; Revisit implementation"); - } catch (Exception e) { - throw new java.sql.SQLException(e); - } - } - - public java.util.logging.Logger getParentLogger() { - // TODO Auto-generated method stub - return null; - } - }