Skip to content

Commit

Permalink
Merge pull request #621 from it-at-m/189-lesen-und-schreiben-des-stat…
Browse files Browse the repository at this point in the history
…us-inklusive-update-an-monitoring-service

189 lesen und schreiben des status inklusive update an monitoring service
  • Loading branch information
MrSebastian authored Dec 10, 2024
2 parents 4883749 + e4e4c2e commit dded6a4
Show file tree
Hide file tree
Showing 53 changed files with 2,710 additions and 26 deletions.
11 changes: 10 additions & 1 deletion docs/src/services/ergebnismeldung-service/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,13 @@ Die Methode initialisiereAWerte() initialisiert die Wahlberechtigten (A-Werte) f
diese im lokalen Repository gespeichert.
- Bei Nichterfolg, wird geprüft ob im lokalen Repository wenigstens 'alte' A-Werte existieren.
- Falls weder im externen Wahlsystem noch im lokalen Repository A-Werte gefunden werden
liefert der Service einen Fehler.
liefert der Service einen Fehler.

### Update des Status der Ergebnisermittlung

Bei der Auszählung (Ergebnisermittlung) wird zuerst eine Schnellmeldung vorbereitet. Den Abschluss der Auszählung
bildet die Niederschrift. Die Schnellmeldung und die Niederschrift können gedruckt und übermittelt werden.

Welche Aktionen für die jeweiligen Dokumente bereits in einem Wahllokal vollzogen wurden, wird über den Status gepflegt.

Über Änderungen an dem Status wird auch der [Monitoring-Service](/services/monitoring-service/) informiert.
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
id: add authorities ergebnismeldung status
author: MrSebastian
realm: ${SSO_REALM}
changes:
- addRole:
name: Ergebnismeldung_BUSINESSACTION_GetStatus
clientRole: true
clientId: ${SSO_CLIENT_ID}
- assignRoleToGroup:
group: allErgebnismeldungAuthorities
role: Ergebnismeldung_BUSINESSACTION_GetStatus
clientId: ${SSO_CLIENT_ID}

- addRole:
name: Ergebnismeldung_BUSINESSACTION_PostStatus
clientRole: true
clientId: ${SSO_CLIENT_ID}
- assignRoleToGroup:
group: allErgebnismeldungAuthorities
role: Ergebnismeldung_BUSINESSACTION_PostStatus
clientId: ${SSO_CLIENT_ID}

- addRole:
name: Ergebnismeldung_READ_Status
clientRole: true
clientId: ${SSO_CLIENT_ID}
- assignRoleToGroup:
group: allErgebnismeldungAuthorities
role: Ergebnismeldung_READ_Status
clientId: ${SSO_CLIENT_ID}
- addRole:
name: Ergebnismeldung_WRITE_Status
clientRole: true
clientId: ${SSO_CLIENT_ID}
- assignRoleToGroup:
group: allErgebnismeldungAuthorities
role: Ergebnismeldung_WRITE_Status
clientId: ${SSO_CLIENT_ID}
- addRole:
name: Ergebnismeldung_DELETE_Status
clientRole: true
clientId: ${SSO_CLIENT_ID}
- assignRoleToGroup:
group: allErgebnismeldungAuthorities
role: Ergebnismeldung_DELETE_Status
clientId: ${SSO_CLIENT_ID}
1 change: 1 addition & 0 deletions stack/keycloak/migration/keycloak-changelog.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,4 @@ includes:
- path: add-authorities-wahlvorstand.yml
- path: create-group-all-ergebnismeldung-authorities.yml
- path: add-authorities-ergebnismeldung-awerte.yml
- path: add-authorities-ergebnismeldung-status.yml
68 changes: 48 additions & 20 deletions wls-ergebnismeldung-service/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,13 @@
<artifactId>spring-security-oauth2-jose</artifactId>
</dependency>

<!-- Mapping -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>

<!-- json etc. -->
<dependency>
<groupId>org.springframework.hateoas</groupId>
Expand Down Expand Up @@ -386,6 +393,36 @@
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>7.9.0</version>
<configuration>
<generatorName>java</generatorName>
<library>resttemplate</library>

<generateApiTests>false</generateApiTests>
<generateModelTests>false</generateModelTests>
<generateApiDocumentation>false</generateApiDocumentation>
<generateModelDocumentation>false</generateModelDocumentation>

<configOptions>
<hideGenerationTimestamp>false</hideGenerationTimestamp>
<legacyDiscriminatorBehavior>false</legacyDiscriminatorBehavior>
<generateClientAsBean>true</generateClientAsBean>
<useJakartaEe>true</useJakartaEe>
</configOptions>

<!-- #611 -->
<typeMappings>
<typeMapping>OffsetDateTime=java.time.LocalDateTime</typeMapping>
</typeMappings>
<importMappings>
<importMapping>java.time.OffsetDateTime=java.time.LocalDateTime</importMapping>
</importMappings>

<globalProperties>
<supportingFiles>
BaseApi.java,ApiClient.java,JavaTimeFormatter.java,Authentication.java,OAuth.java,ApiKeyAuth.java,HttpBasicAuth.java,HttpBearerAuth.java,RFC3339DateFormat.java
</supportingFiles>
</globalProperties>
</configuration>
<executions>
<execution>
<id>generateEAI</id>
Expand All @@ -395,29 +432,20 @@
<configuration>
<inputSpec>${project.basedir}/src/main/resources/openapis/openapi.eai.0.3.0.json</inputSpec>

<generatorName>java</generatorName>
<library>resttemplate</library>

<apiPackage>${project.groupId}.ergebnismeldungservice.eai.aou.client</apiPackage>
<modelPackage>${project.groupId}.ergebnismeldungservice.eai.aou.model</modelPackage>
</configuration>
</execution>
<execution>
<id>generateMonitoring</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>${project.basedir}/src/main/resources/openapis/openapi.monitoring.0.1.0.json</inputSpec>

<generateApiTests>false</generateApiTests>
<generateModelTests>false</generateModelTests>
<generateApiDocumentation>false</generateApiDocumentation>
<generateModelDocumentation>false</generateModelDocumentation>

<configOptions>
<hideGenerationTimestamp>false</hideGenerationTimestamp>
<legacyDiscriminatorBehavior>false</legacyDiscriminatorBehavior>
<generateClientAsBean>true</generateClientAsBean>
<useJakartaEe>true</useJakartaEe>
</configOptions>

<globalProperties>
<supportingFiles>
BaseApi.java,ApiClient.java,JavaTimeFormatter.java,Authentication.java,OAuth.java,ApiKeyAuth.java,HttpBasicAuth.java,HttpBearerAuth.java,RFC3339DateFormat.java
</supportingFiles>
</globalProperties>
<apiPackage>${groupId}.ergebnismeldungservice.eai.monitoring.client</apiPackage>
<modelPackage>${groupId}.ergebnismeldungservice.eai.monitoring.model</modelPackage>
</configuration>
</execution>
</executions>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
scanBasePackages = {
"org.springframework.data.jpa.convert.threeten",
"de.muenchen.oss.wahllokalsystem.ergebnismeldungservice",
"de.muenchen.oss.wahllokalsystem.wls.common.exception"
"de.muenchen.oss.wahllokalsystem.wls.common.exception",
"de.muenchen.oss.wahllokalsystem.wls.common.security"
}
)
public class MicroServiceApplication {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,45 @@
import de.muenchen.oss.wahllokalsystem.ergebnismeldungservice.configuration.Profiles;
import de.muenchen.oss.wahllokalsystem.ergebnismeldungservice.service.awerte.AWerteClient;
import de.muenchen.oss.wahllokalsystem.ergebnismeldungservice.service.awerte.AWerteModel;
import de.muenchen.oss.wahllokalsystem.ergebnismeldungservice.service.status.sender.StatusClient;
import de.muenchen.oss.wahllokalsystem.wls.common.exception.WlsException;
import de.muenchen.oss.wahllokalsystem.wls.common.security.domain.BezirkUndWahlID;
import java.time.LocalDateTime;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;

@Component
@Profile(Profiles.DUMMY_CLIENTS)
@Slf4j
public class DummyClientImpl
implements AWerteClient {
implements AWerteClient, StatusClient {

@Override
public List<AWerteModel> getAWerte(final String wahlbezirkID) throws WlsException {
return List.of(
new AWerteModel(new BezirkUndWahlID("wahlID01", wahlbezirkID), 25L, 26L));
}

@Override
public void postSchnellmeldungSendungsuhrzeit(BezirkUndWahlID bezirkUndWahlID, LocalDateTime schnellmeldungSendungsuhrzeit)
throws WlsException {
log.info("dummy client postSchnellmeldungSendungsuhrzeit of {} on {} called instead of monitoring", bezirkUndWahlID, schnellmeldungSendungsuhrzeit);
}

@Override
public void postSchnellmeldungDruckuhrzeit(BezirkUndWahlID bezirkUndWahlID, LocalDateTime schnellmeldungDruckuhrzeit) throws WlsException {
log.info("dummy client postSchnellmeldungDruckuhrzeit of {} on {} called instead of monitoring", bezirkUndWahlID, schnellmeldungDruckuhrzeit);
}

@Override
public void postNiederschriftSendungsuhrzeit(BezirkUndWahlID bezirkUndWahlID, LocalDateTime niederschriftSendungsuhrzeit) throws WlsException {
log.info("dummy client postNiederschriftSendungsuhrzeit of {} on {} called instead of monitoring", bezirkUndWahlID, niederschriftSendungsuhrzeit);
}

@Override
public void postNiederschriftDruckuhrzeit(BezirkUndWahlID bezirkUndWahlID, LocalDateTime niederschriftDruckuhrzeit) throws WlsException {
log.info("dummy client postNiederschriftDruckuhrzeit of {} on {} called instead of monitoring", bezirkUndWahlID, niederschriftDruckuhrzeit);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package de.muenchen.oss.wahllokalsystem.ergebnismeldungservice.client;

import de.muenchen.oss.wahllokalsystem.ergebnismeldungservice.configuration.Profiles;
import de.muenchen.oss.wahllokalsystem.ergebnismeldungservice.eai.monitoring.client.WahllokalZustandControllerApi;
import de.muenchen.oss.wahllokalsystem.ergebnismeldungservice.exception.ExceptionConstants;
import de.muenchen.oss.wahllokalsystem.ergebnismeldungservice.service.status.sender.StatusClient;
import de.muenchen.oss.wahllokalsystem.wls.common.exception.WlsException;
import de.muenchen.oss.wahllokalsystem.wls.common.exception.util.ExceptionFactory;
import de.muenchen.oss.wahllokalsystem.wls.common.security.domain.BezirkUndWahlID;
import java.time.LocalDateTime;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;

@Component
@Profile(Profiles.NOT + Profiles.DUMMY_CLIENTS)
@RequiredArgsConstructor
@Slf4j
public class MonitoringClient implements StatusClient {

private final WahllokalZustandControllerApi wahllokalZustandControllerApi;
private final StatusClientMapper statusClientMapper;
private final ExceptionFactory exceptionFactory;

@Override
public void postSchnellmeldungSendungsuhrzeit(BezirkUndWahlID bezirkUndWahlID, LocalDateTime schnellmeldungSendungsuhrzeit)
throws WlsException {
val schnellmeldungGesendet = statusClientMapper.toSendungsdatenDTO(bezirkUndWahlID, schnellmeldungSendungsuhrzeit);
callApiWithExceptionMapping(() -> wahllokalZustandControllerApi.postSchnellmeldungSendungsuhrzeit(schnellmeldungGesendet));
}

@Override
public void postSchnellmeldungDruckuhrzeit(BezirkUndWahlID bezirkUndWahlID, LocalDateTime schnellmeldungDruckuhrzeit) throws WlsException {
val schellmeldungGedruckt = statusClientMapper.toDruckdatenDTO(bezirkUndWahlID, schnellmeldungDruckuhrzeit);
callApiWithExceptionMapping(() -> wahllokalZustandControllerApi.postSchnellmeldungDruckuhrzeit(schellmeldungGedruckt));
}

@Override
public void postNiederschriftSendungsuhrzeit(BezirkUndWahlID bezirkUndWahlID, LocalDateTime niederschriftSendungsuhrzeit) throws WlsException {
val niederschriftGesendet = statusClientMapper.toSendungsdatenDTO(bezirkUndWahlID, niederschriftSendungsuhrzeit);
callApiWithExceptionMapping(() -> wahllokalZustandControllerApi.postNiederschriftSendungsuhrzeit(niederschriftGesendet));
}

@Override
public void postNiederschriftDruckuhrzeit(BezirkUndWahlID bezirkUndWahlID, LocalDateTime niederschriftDruckuhrzeit) throws WlsException {
val niederschriftGedruckt = statusClientMapper.toDruckdatenDTO(bezirkUndWahlID, niederschriftDruckuhrzeit);
callApiWithExceptionMapping(() -> wahllokalZustandControllerApi.postNiederschriftDruckuhrzeit(niederschriftGedruckt));
}

private void callApiWithExceptionMapping(final Runnable apiCall) {
try {
apiCall.run();
} catch (final WlsException wlsException) {
log.debug("found WlsException: {}", wlsException.getMessage());
throw wlsException;
} catch (final Exception exception) {
throw exceptionFactory.createTechnischeWlsException(ExceptionConstants.KOMMUNIKATIONSFEHLER_MIT_MONITORING);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package de.muenchen.oss.wahllokalsystem.ergebnismeldungservice.client;

import de.muenchen.oss.wahllokalsystem.ergebnismeldungservice.eai.monitoring.model.DruckdatenDTO;
import de.muenchen.oss.wahllokalsystem.ergebnismeldungservice.eai.monitoring.model.SendungsdatenDTO;
import de.muenchen.oss.wahllokalsystem.wls.common.security.domain.BezirkUndWahlID;
import java.time.LocalDateTime;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;

@Mapper
public interface StatusClientMapper {

@Mapping(target = "druckuhrzeit", source = "dateTimeOfEvent")
DruckdatenDTO toDruckdatenDTO(BezirkUndWahlID bezirkUndWahlID, LocalDateTime dateTimeOfEvent);

@Mapping(target = "sendungsuhrzeit", source = "dateTimeOfEvent")
SendungsdatenDTO toSendungsdatenDTO(BezirkUndWahlID bezirkUndWahlID, LocalDateTime dateTimeOfEvent);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package de.muenchen.oss.wahllokalsystem.ergebnismeldungservice.configuration;

import de.muenchen.oss.wahllokalsystem.ergebnismeldungservice.eai.aou.ApiClient;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
Expand All @@ -13,10 +12,15 @@ public class BasePathConfiguration {
@Value("${service.config.clients.eai.basePath}")
String eaiBasePath;

private final ApiClient eaiApiClient;
@Value("${service.config.clients.monitoring.basePath}")
String monitoringBasePath;

private final de.muenchen.oss.wahllokalsystem.ergebnismeldungservice.eai.aou.ApiClient eaiApiClient;
private final de.muenchen.oss.wahllokalsystem.ergebnismeldungservice.eai.monitoring.ApiClient monitoringApiClient;

@PostConstruct
public void updateBasePaths() {
eaiApiClient.setBasePath(eaiBasePath);
monitoringApiClient.setBasePath(monitoringBasePath);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package de.muenchen.oss.wahllokalsystem.ergebnismeldungservice.domain.status;

import jakarta.persistence.Embeddable;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.validation.constraints.NotNull;
import java.time.LocalDateTime;
import lombok.Data;

@Embeddable
@Data
public class Meldung {

@Enumerated(EnumType.STRING)
@NotNull
private Validierungsstatus validierungsstatus;

@NotNull
private boolean gedruckt;

private Boolean uebermittelt;

private LocalDateTime sendeuhrzeit;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package de.muenchen.oss.wahllokalsystem.ergebnismeldungservice.domain.status;

import de.muenchen.oss.wahllokalsystem.wls.common.security.domain.BezirkUndWahlID;
import jakarta.persistence.AttributeOverride;
import jakarta.persistence.AttributeOverrides;
import jakarta.persistence.Column;
import jakarta.persistence.Embedded;
import jakarta.persistence.EmbeddedId;
import jakarta.persistence.Entity;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Status {

@EmbeddedId
private BezirkUndWahlID bezirkUndWahlID;

@Embedded
@NotNull
@AttributeOverrides(
{
@AttributeOverride(name = "validierungsstatus", column = @Column(name = "schnellmeldungValidierungsstatus")),
@AttributeOverride(name = "gedruckt", column = @Column(name = "schnellmeldungGedruckt")),
@AttributeOverride(name = "uebermittelt", column = @Column(name = "schnellmeldungUebermittelt")),
@AttributeOverride(name = "sendeuhrzeit", column = @Column(name = "schnellmeldungSendeuhrzeit")),
}
)
private Meldung schnellmeldung;

@Embedded
@NotNull
@AttributeOverrides(
{
@AttributeOverride(name = "validierungsstatus", column = @Column(name = "niederschriftValidierungsstatus")),
@AttributeOverride(name = "gedruckt", column = @Column(name = "niederschriftGedruckt")),
@AttributeOverride(name = "uebermittelt", column = @Column(name = "niederschriftUebermittelt")),
@AttributeOverride(name = "sendeuhrzeit", column = @Column(name = "niederschriftSendeuhrzeit")),
}
)
private Meldung niederschrift;
}
Loading

0 comments on commit dded6a4

Please sign in to comment.