Skip to content

Commit

Permalink
Merge pull request #407 from it-at-m/review-393-lesen-schreiben-wahlen
Browse files Browse the repository at this point in the history
Verbesserungsvorschläge zu PR 393 Lesen und Schreiben von Wahlen
  • Loading branch information
MrSebastian authored Sep 4, 2024
2 parents ffae4a0 + 4cebd1a commit 5dbe68c
Show file tree
Hide file tree
Showing 32 changed files with 420 additions and 205 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@ changes:
role: Basisdaten_BUSINESSACTION_GetWahltage
clientId: ${SSO_CLIENT_ID}

- addRole:
name: Basisdaten_BUSINESSACTION_GetWahltag
clientRole: true
clientId: ${SSO_CLIENT_ID}
- assignRoleToGroup:
group: allBasisdatenAuthorities
role: Basisdaten_BUSINESSACTION_GetWahltag
clientId: ${SSO_CLIENT_ID}

- addRole:
name: Basisdaten_READ_Wahltag
clientRole: true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.wahlbezirke.WahlbezirkeClient;
import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.wahlen.WahlModel;
import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.wahlen.WahlenClient;
import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.wahlen.WahltagWithNummer;
import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.wahltag.WahltagModel;
import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.wahltag.WahltageClient;
import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.wahlvorschlag.KandidatModel;
Expand Down Expand Up @@ -66,11 +67,11 @@ public List<WahltagModel> getWahltage(LocalDate tag) {
}

@Override
public List<WahlModel> getWahlen(LocalDate wahltag, String wahltagNummer) throws WlsException {
public List<WahlModel> getWahlen(final WahltagWithNummer wahltagWithNummer) throws WlsException {
return List.of(
new WahlModel("wahl1", "0", 1L, 1L, wahltag, BTW, new Farbe(0, 1, 2), "1"),
new WahlModel("wahl2", "1", 2L, 1L, wahltag, EUW, new Farbe(3, 4, 5), "1"),
new WahlModel("wahl3", "2", 3L, 1L, wahltag, LTW, new Farbe(6, 7, 8), "1"));
new WahlModel("wahl1", "0", 1L, 1L, wahltagWithNummer.wahltag(), BTW, new Farbe(0, 1, 2), "1"),
new WahlModel("wahl2", "1", 2L, 1L, wahltagWithNummer.wahltag(), EUW, new Farbe(3, 4, 5), "1"),
new WahlModel("wahl3", "2", 3L, 1L, wahltagWithNummer.wahltag(), LTW, new Farbe(6, 7, 8), "1"));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import de.muenchen.oss.wahllokalsystem.basisdatenservice.exception.ExceptionConstants;
import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.wahlen.WahlModel;
import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.wahlen.WahlenClient;
import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.wahlen.WahltagWithNummer;
import de.muenchen.oss.wahllokalsystem.wls.common.exception.util.ExceptionFactory;
import java.util.List;
import java.util.Set;
Expand All @@ -26,10 +27,10 @@ public class WahlenClientImpl implements WahlenClient {
private final WahlenClientMapper wahlenClientMapper;

@Override
public List<WahlModel> getWahlen(java.time.LocalDate wahltag, String wahltagNummer) {
public List<WahlModel> getWahlen(final WahltagWithNummer wahltagWithNummer) {
final Set<WahlDTO> wahlDTOs;
try {
wahlDTOs = wahldatenControllerApi.loadWahlen(wahltag, wahltagNummer);
wahlDTOs = wahldatenControllerApi.loadWahlen(wahltagWithNummer.wahltag(), wahltagWithNummer.wahltagNummer());
} catch (final Exception exception) {
log.info("exception on loadwahl from external", exception);
throw exceptionFactory.createTechnischeWlsException(ExceptionConstants.FAILED_COMMUNICATION_WITH_EAI);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,41 +1,21 @@
package de.muenchen.oss.wahllokalsystem.basisdatenservice.clients;

import de.muenchen.oss.wahllokalsystem.basisdatenservice.domain.wahl.Farbe;
import de.muenchen.oss.wahllokalsystem.basisdatenservice.eai.aou.model.WahlDTO;
import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.wahlen.WahlModel;
import de.muenchen.oss.wahllokalsystem.basisdatenservice.utils.ObjectPropertyChecker;
import java.util.List;
import java.util.Set;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Named;
import org.mapstruct.factory.Mappers;

@Mapper
@Mapper(imports = Farbe.class)
public interface WahlenClientMapper {

WahlenClientMapper INSTANCE = Mappers.getMapper(WahlenClientMapper.class);

@Mapping(target = "waehlerverzeichnisnummer", source = ".", qualifiedByName = "setWZeroIfNotExisting")
@Mapping(target = "reihenfolge", source = ".", qualifiedByName = "setRZeroIfNotExisting")
@Mapping(target = "farbe", ignore = true)
@Mapping(target = "waehlerverzeichnisnummer", constant = "1l")
@Mapping(target = "reihenfolge", constant = "1l")
@Mapping(target = "farbe", expression = "java(new Farbe(0, 0, 0))")
@Mapping(target = "wahlID", source = "identifikator")
WahlModel toModel(WahlDTO wahlDTO);

@Named("setWZeroIfNotExisting")
default Long setWZeroIfNotExisting(final WahlDTO wahlDTO) throws NoSuchFieldException, IllegalAccessException {
if (ObjectPropertyChecker.objectHasProperty(wahlDTO, "waehlerverzeichnisnummer")) {
ObjectPropertyChecker.getValueFromField(wahlDTO, "waehlerverzeichnisnummer");
}
return 0L;
}

@Named("setRZeroIfNotExisting")
default Long setRZeroIfNotExisting(final WahlDTO wahlDTO) throws NoSuchFieldException, IllegalAccessException {
if (ObjectPropertyChecker.objectHasProperty(wahlDTO, "reihenfolge")) {
ObjectPropertyChecker.getValueFromField(wahlDTO, "reihenfolge");
}
return 0L;
}

List<WahlModel> fromRemoteClientSetOfWahlDTOtoListOfWahlModel(Set<WahlDTO> wahlDTO);
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,5 @@ public interface WahlRepository extends CrudRepository<Wahl, String> {

List<Wahl> findByWahltagOrderByReihenfolge(LocalDate wahltag);

int countByWahltag(LocalDate wahltag);
boolean existsByWahltag(LocalDate wahltag);
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,19 +51,16 @@ public class ExceptionConstants {
public static ExceptionDataWrapper GETREFERENDUMVORLAGEN_PARAMETER_UNVOLLSTAENDIG = new ExceptionDataWrapper("308",
"getReferendumvorlagen: Suchkriterien unvollständig.");

public static ExceptionDataWrapper WAHL_SPEICHERN_FEHLGESCHLAGEN = new ExceptionDataWrapper("351",
"postUngueltigeWahl: Das Speichern der Wahl ist fehlgeschlagen");

public static ExceptionDataWrapper CODE_GETWAHLEN_PARAMETER_UNVOLLSTAENDIG = new ExceptionDataWrapper("314",
public static ExceptionDataWrapper GETWAHLEN_PARAMETER_UNVOLLSTAENDIG = new ExceptionDataWrapper("314",
"getWahlen: Der Wahltag zu den gesuchten Wahlen existiert nicht.");
public static ExceptionDataWrapper CODE_POSTWAHLEN_PARAMETER_UNVOLLSTAENDIG = new ExceptionDataWrapper("317",
public static ExceptionDataWrapper POSTWAHLEN_PARAMETER_UNVOLLSTAENDIG = new ExceptionDataWrapper("317",
"postWahlen: Suchkriterien unvollständig. Die wahltagID ist leer oder null.");
public static ExceptionDataWrapper CODE_POSTWAHLEN_UNSAVEABLE = new ExceptionDataWrapper("318",
public static ExceptionDataWrapper POSTWAHLEN_UNSAVEABLE = new ExceptionDataWrapper("318",
"postWahlen: Die Wahlen konnten nicht gespeichert werden.");

public static ExceptionDataWrapper CODE_GETWAHLBEZIRKE_PARAMETER_UNVOLLSTAENDIG = new ExceptionDataWrapper("312",
"getWahlbezirke: Suchkriterien unvollständig. Die wahltagID ist leer oder null.");
public static ExceptionDataWrapper CODE_GETWAHLBEZIRKE_NO_WAHLTAG = new ExceptionDataWrapper("313",
public static ExceptionDataWrapper GETWAHLBEZIRKE_NO_WAHLTAG = new ExceptionDataWrapper("313",
"Es wurde kein Wahltag zu dieser WahltagID gefunden. Bitte legen Sie die Basisdaten an.");

public static final ExceptionDataWrapper GETKOPFDATEN_PARAMETER_UNVOLLSTAENDIG = new ExceptionDataWrapper("303",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package de.muenchen.oss.wahllokalsystem.basisdatenservice.rest.wahlen;

import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.wahlen.WahlenService;
import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.wahlen.WahlenWriteModel;
import de.muenchen.oss.wahllokalsystem.wls.common.exception.rest.model.WlsExceptionDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.ArraySchema;
Expand Down Expand Up @@ -57,7 +58,7 @@ public List<WahlDTO> getWahlen(@PathVariable("wahltagID") String wahltagID) {
)
@ResponseStatus(HttpStatus.OK)
public void postWahlen(@PathVariable("wahltagID") String wahltagID, @RequestBody List<WahlDTO> wahlDTOs) {
wahlenService.postWahlen(wahltagID, wahlDTOMapper.fromListOfWahlDTOtoListOfWahlModel(wahlDTOs));
wahlenService.postWahlen(new WahlenWriteModel(wahltagID, wahlDTOMapper.fromListOfWahlDTOtoListOfWahlModel(wahlDTOs)));
}

@Operation(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public List<WahlbezirkModel> getWahlbezirke(final String wahltagID) {
}
return wahlbezirkModelMapper.fromListOfWahlbezirkEntityToListOfWahlbezirkModel(wahlbezirkRepository.findByWahltag(wahltagObjekt.getWahltag()));
} else {
throw exceptionFactory.createFachlicheWlsException(ExceptionConstants.CODE_GETWAHLBEZIRKE_NO_WAHLTAG);
throw exceptionFactory.createFachlicheWlsException(ExceptionConstants.GETWAHLBEZIRKE_NO_WAHLTAG);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public void validWahltagIDParamOrThrow(final String wahltagID) {

public void validateWahltagForSearchingWahltagID(final Optional<Wahltag> wahltag) {
if (wahltag.isEmpty() || null == wahltag.get().getWahltag()) {
throw exceptionFactory.createFachlicheWlsException(ExceptionConstants.CODE_GETWAHLBEZIRKE_NO_WAHLTAG);
throw exceptionFactory.createFachlicheWlsException(ExceptionConstants.GETWAHLBEZIRKE_NO_WAHLTAG);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
package de.muenchen.oss.wahllokalsystem.basisdatenservice.services.wahlen;

import de.muenchen.oss.wahllokalsystem.wls.common.exception.WlsException;
import java.time.LocalDate;
import java.util.List;

public interface WahlenClient {

/**
* @param wahltag The Request Wahltag - Reference for requested Wahlen
* @param wahltagNummer The Number of the Wahltag, it could exist more then one Wahltag at same day
* if more elections on the day
* @param wahltagWithNummer reference to a specific event on a date of election
* @return List<WahltagModel>
* @throws WlsException
* {@link de.muenchen.oss.wahllokalsystem.wls.common.exception.FachlicheWlsException} if
* return would be null
* {@link de.muenchen.oss.wahllokalsystem.wls.common.exception.TechnischeWlsException}
* if there were trouble during communication
*/
List<WahlModel> getWahlen(final LocalDate wahltag, final String wahltagNummer) throws WlsException;
List<WahlModel> getWahlen(final WahltagWithNummer wahltagWithNummer) throws WlsException;
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
package de.muenchen.oss.wahllokalsystem.basisdatenservice.services.wahlen;

import de.muenchen.oss.wahllokalsystem.basisdatenservice.domain.WahltagRepository;
import de.muenchen.oss.wahllokalsystem.basisdatenservice.domain.wahl.Farbe;
import de.muenchen.oss.wahllokalsystem.basisdatenservice.domain.wahl.Wahl;
import de.muenchen.oss.wahllokalsystem.basisdatenservice.domain.wahl.WahlRepository;
import de.muenchen.oss.wahllokalsystem.basisdatenservice.exception.ExceptionConstants;
import de.muenchen.oss.wahllokalsystem.basisdatenservice.services.wahltag.WahltageService;
import de.muenchen.oss.wahllokalsystem.wls.common.exception.util.ExceptionFactory;
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.springframework.http.HttpMethod;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
Expand All @@ -22,7 +21,7 @@ public class WahlenService {

private final WahlRepository wahlRepository;

private final WahltagRepository wahltagRepository;
private final WahltageService wahltageService;

private final ExceptionFactory exceptionFactory;

Expand All @@ -35,29 +34,30 @@ public class WahlenService {
@PreAuthorize("hasAuthority('Basisdaten_BUSINESSACTION_GetWahlen')")
@Transactional
public List<WahlModel> getWahlen(String wahltagID) {
wahlenValidator.validWahltagIDParamOrThrow(wahltagID, HttpMethod.GET);
val wahltag = wahltagRepository.findById(wahltagID);
wahlenValidator.validateWahltagForSearchingWahltagID(wahltag);
wahlenValidator.validWahlenCriteriaOrThrow(wahltagID);

if (wahlRepository.countByWahltag(wahltag.get().getWahltag()) == 0) {
val wahltagValue = wahltageService.getWahltagByID(wahltagID);

if (!wahlRepository.existsByWahltag(wahltagValue.wahltag())) {
log.info("#getWahlen: Für wahltagID {} waren keine Wahlen in der Datenbank", wahltagID);
List<Wahl> wahlEntities = wahlModelMapper
.fromListOfWahlModeltoListOfWahlEntities(wahlenClient.getWahlen(wahltag.get().getWahltag(), wahltag.get().getNummer()));
.fromListOfWahlModeltoListOfWahlEntities(
wahlenClient.getWahlen(new WahltagWithNummer(wahltagValue.wahltag(), wahltagValue.nummer())));
wahlRepository.saveAll(wahlEntities);
}
return wahlModelMapper.fromListOfWahlEntityToListOfWahlModel(wahlRepository.findByWahltagOrderByReihenfolge(wahltag.get().getWahltag()));
return wahlModelMapper.fromListOfWahlEntityToListOfWahlModel(wahlRepository.findByWahltagOrderByReihenfolge(wahltagValue.wahltag()));
}

@PreAuthorize("hasAuthority('Basisdaten_BUSINESSACTION_PostWahlen')")
@Transactional
public void postWahlen(String wahltagID, List<WahlModel> wahlen) {
public void postWahlen(final WahlenWriteModel wahlenWriteModel) {
log.info("#postWahlen");
wahlenValidator.validWahltagIDParamOrThrow(wahltagID, HttpMethod.POST);
wahlenValidator.validWahlenWriteModelOrThrow(wahlenWriteModel);
try {
wahlRepository.saveAll(wahlModelMapper.fromListOfWahlModeltoListOfWahlEntities(wahlen));
wahlRepository.saveAll(wahlModelMapper.fromListOfWahlModeltoListOfWahlEntities(wahlenWriteModel.wahlen()));
} catch (Exception e) {
log.error("#postWahlen: Die Wahlen konnten aufgrund eines Fehlers nicht gespeichert werden {}:", e);
throw exceptionFactory.createFachlicheWlsException(ExceptionConstants.CODE_POSTWAHLEN_UNSAVEABLE);
log.error("#postWahlen: Die Wahlen konnten aufgrund eines Fehlers nicht gespeichert werden:", e);
throw exceptionFactory.createFachlicheWlsException(ExceptionConstants.POSTWAHLEN_UNSAVEABLE);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,27 @@
package de.muenchen.oss.wahllokalsystem.basisdatenservice.services.wahlen;

import de.muenchen.oss.wahllokalsystem.basisdatenservice.domain.Wahltag;
import de.muenchen.oss.wahllokalsystem.basisdatenservice.exception.ExceptionConstants;
import de.muenchen.oss.wahllokalsystem.wls.common.exception.util.ExceptionFactory;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

@Component
@RequiredArgsConstructor
public class WahlenValidator {

private final ExceptionFactory exceptionFactory;

public void validWahltagIDParamOrThrow(final String wahltagID, HttpMethod httpMethod) {
if (wahltagID == null || StringUtils.isBlank(wahltagID) || StringUtils.isEmpty(wahltagID)) {
switch (httpMethod.toString()) {
case "GET" -> throw exceptionFactory.createFachlicheWlsException(ExceptionConstants.CODE_GETWAHLEN_PARAMETER_UNVOLLSTAENDIG);
case "POST" -> throw exceptionFactory.createFachlicheWlsException(ExceptionConstants.CODE_POSTWAHLEN_PARAMETER_UNVOLLSTAENDIG);
}
public void validWahlenCriteriaOrThrow(final String wahltagID) {
if (StringUtils.isBlank(wahltagID)) {
throw exceptionFactory.createFachlicheWlsException(ExceptionConstants.GETWAHLEN_PARAMETER_UNVOLLSTAENDIG);
}
}

public void validateWahltagForSearchingWahltagID(final Optional<Wahltag> wahltag) {
if (wahltag.isEmpty() || null == wahltag.get().getWahltag()) {
throw exceptionFactory.createFachlicheWlsException(ExceptionConstants.CODE_GETWAHLBEZIRKE_NO_WAHLTAG);
public void validWahlenWriteModelOrThrow(final WahlenWriteModel wahlenWriteModel) {
if (wahlenWriteModel == null || StringUtils.isBlank(wahlenWriteModel.wahltagID()) || CollectionUtils.isEmpty(wahlenWriteModel.wahlen())) {
throw exceptionFactory.createFachlicheWlsException(ExceptionConstants.POSTWAHLEN_PARAMETER_UNVOLLSTAENDIG);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package de.muenchen.oss.wahllokalsystem.basisdatenservice.services.wahlen;

import java.util.List;

public record WahlenWriteModel(
String wahltagID,
List<WahlModel> wahlen
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package de.muenchen.oss.wahllokalsystem.basisdatenservice.services.wahlen;

import jakarta.validation.constraints.NotNull;
import java.time.LocalDate;

public record WahltagWithNummer(
@NotNull LocalDate wahltag,
@NotNull String wahltagNummer) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
@Mapper
public interface WahltagModelMapper {

WahltagModel toModel(Wahltag wahltag);

List<WahltagModel> fromWahltagEntityToWahltagModelList(List<Wahltag> entities);

List<Wahltag> fromWahltagModelToWahltagEntityList(List<WahltagModel> entities);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package de.muenchen.oss.wahllokalsystem.basisdatenservice.services.wahltag;

import de.muenchen.oss.wahllokalsystem.basisdatenservice.domain.Wahltag;
import de.muenchen.oss.wahllokalsystem.basisdatenservice.domain.WahltagRepository;
import de.muenchen.oss.wahllokalsystem.basisdatenservice.exception.ExceptionConstants;
import de.muenchen.oss.wahllokalsystem.wls.common.exception.util.ExceptionFactory;
import java.time.LocalDate;
import java.util.List;
import lombok.RequiredArgsConstructor;
Expand All @@ -14,6 +17,8 @@
@Slf4j
public class WahltageService {

private final ExceptionFactory exceptionFactory;

private final WahltagRepository wahltagRepository;

private final WahltagModelMapper wahltagModelMapper;
Expand All @@ -29,4 +34,16 @@ public List<WahltagModel> getWahltage() {
wahltagRepository.saveAll(wahltagModelMapper.fromWahltagModelToWahltagEntityList(wahltage));
return wahltagModelMapper.fromWahltagEntityToWahltagModelList(wahltagRepository.findAllByOrderByWahltagAsc());
}

@PreAuthorize(
"hasAuthority('Basisdaten_BUSINESSACTION_GetWahltag')"
)
public WahltagModel getWahltagByID(final String wahltagID) {
return wahltagModelMapper.toModel(getWahltagByIDOrThrow(wahltagID));
}

private Wahltag getWahltagByIDOrThrow(final String wahltagID) {
return wahltagRepository.findById(wahltagID)
.orElseThrow(() -> exceptionFactory.createFachlicheWlsException(ExceptionConstants.GETWAHLBEZIRKE_NO_WAHLTAG));
}
}
Loading

0 comments on commit 5dbe68c

Please sign in to comment.