Skip to content
Snippets Groups Projects
Commit a6968745 authored by Felix Reichenbach's avatar Felix Reichenbach
Browse files

Merge branch 'OZG-7573-forwarding-interface' into 'main'

Ozg 7573 forwarding interface

See merge request !23
parents b6d8660e 493b2692
No related branches found
No related tags found
1 merge request!23Ozg 7573 forwarding interface
Showing
with 1628 additions and 303 deletions
......@@ -29,3 +29,4 @@ lombok.data.flagUsage = ERROR
lombok.nonNull.exceptionType = IllegalArgumentException
lombok.addLombokGeneratedAnnotation = true
lombok.copyableAnnotations += org.springframework.beans.factory.annotation.Qualifier
lombok.copyableAnnotations += net.devh.boot.grpc.client.inject.GrpcClient
\ No newline at end of file
......@@ -163,6 +163,12 @@ spec:
- name: grpc_client_zufi-manager_negotiationType
value: {{ (.Values.zufiManager).grpcClientNegotiationType | default "PLAINTEXT" }}
{{- end}}
{{- if (.Values.forwarding).enabled }}
- name: grpc_client_forwarder_address
value: {{ (.Values.forwarding).address }}
- name: grpc_client_forwarder_negotiationType
value: {{ (.Values.forwarding).grpcClientNegotiationType | default "TLS" }}
{{- end }}
{{- if not (.Values.database).useExternal }}
- name: spring_data_mongodb_uri
valueFrom:
......
......@@ -153,6 +153,18 @@ spec:
- port: 9090
protocol: TCP
{{- end }}
{{- if (.Values.forwarding).enabled }}
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: {{ required "forwarding.namespace must be set if forwarding is enabled" (.Values.forwarding).namespace }}
podSelector:
matchLabels:
component: {{ required "forwarding.serviceName must be set if forwarding is enabled" (.Values.forwarding).serviceName }}
ports:
- port: 9090
protocol: TCP
{{- end }}
{{- if ((.Values.ozgcloud).muk).enabled }}
- to:
- podSelector:
......
#
# Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den
# Ministerpräsidenten des Landes Schleswig-Holstein
# Staatskanzlei
# Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
#
# Lizenziert unter der EUPL, Version 1.2 oder - sobald
# diese von der Europäischen Kommission genehmigt wurden -
# Folgeversionen der EUPL ("Lizenz");
# Sie dürfen dieses Werk ausschließlich gemäß
# dieser Lizenz nutzen.
# Eine Kopie der Lizenz finden Sie hier:
#
# https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
#
# Sofern nicht durch anwendbare Rechtsvorschriften
# gefordert oder in schriftlicher Form vereinbart, wird
# die unter der Lizenz verbreitete Software "so wie sie
# ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
# ausdrücklich oder stillschweigend - verbreitet.
# Die sprachspezifischen Genehmigungen und Beschränkungen
# unter der Lizenz sind dem Lizenztext zu entnehmen.
#
suite: test forwarder environment
release:
name: vorgang-manager
namespace: by-helm-test
templates:
- templates/deployment.yaml
set:
baseUrl: test.sh.ozg-cloud.de
ozgcloud:
environment: dev
bezeichner: helm
imagePullSecret: test-image-pull-secret
tests:
- it: should be disabled by default
asserts:
- notContains:
path: spec.template.spec.containers[0].env
content:
name: ozgcloud_forwarder_address
any: true
- notContains:
path: spec.template.spec.containers[0].env
content:
name: grpc_client_forwarder_negotiationType
any: true
- it: should set the grpc forwarder client address
set:
forwarding:
enabled: true
address: https://forwarder.my-wonderful-domain.local:9000
asserts:
- contains:
path: spec.template.spec.containers[0].env
content:
name: grpc_client_forwarder_address
value: https://forwarder.my-wonderful-domain.local:9000
- it: should set the default negotiation type
set:
forwarding:
enabled: true
asserts:
- contains:
path: spec.template.spec.containers[0].env
content:
name: grpc_client_forwarder_negotiationType
value: TLS
- it: should set the negotiation type
set:
forwarding:
enabled: true
grpcClientNegotiationType: PLAINTEXT
asserts:
- contains:
path: spec.template.spec.containers[0].env
content:
name: grpc_client_forwarder_negotiationType
value: PLAINTEXT
\ No newline at end of file
......@@ -67,7 +67,6 @@ tests:
matchLabels:
component: vorgang-manager
- it: should add policyType Egress
set:
networkPolicy:
......@@ -179,7 +178,6 @@ tests:
matchLabels:
component: antragraum-proxy
- it: should not add ingress rule for antragraum if antragraum is disabled
set:
networkPolicy:
......@@ -266,7 +264,6 @@ tests:
- protocol: TCP
port: 9090
- it: should add egress rule to elasticsearch
set:
networkPolicy:
......@@ -456,7 +453,6 @@ tests:
- port: 9090
protocol: TCP
- it: should not add egress rule to zufi server if zufi is disabled
set:
networkPolicy:
......@@ -477,6 +473,50 @@ tests:
component: zufi-server
any: true
- it: should add egress rule to forwarding service if forwarding is enabled
set:
networkPolicy:
dnsServerNamespace: test-dns-namespace
forwarding:
enabled: true
namespace: zentraler-eingang
serviceName: fs-adapter
asserts:
- contains:
path: spec.egress
content:
to:
- podSelector:
matchLabels:
component: fs-adapter
namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: zentraler-eingang
ports:
- port: 9090
protocol: TCP
- it: should not add egress rule to forwarding service if forwarding is disabled
set:
networkPolicy:
dnsServerNamespace: test-dns-namespace
forwarding:
enabled: false
namespace: zentraler-eingang
serviceName: fs-adapter
asserts:
- notContains:
path: spec.egress
content:
to:
- podSelector:
matchLabels:
component: fs-adapter
namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: zentraler-eingang
any: true
- it: should throw error if zufi is enabled but zufi namespace is not set
set:
networkPolicy:
......@@ -506,7 +546,6 @@ tests:
component: zufi-server
any: true
- it: should add egress rule to dns service
set:
networkPolicy:
......
......@@ -32,7 +32,7 @@
<parent>
<groupId>de.ozgcloud.common</groupId>
<artifactId>ozgcloud-common-parent</artifactId>
<version>4.11.0</version>
<version>4.12.0-OZG-7573-GrpcUpload-utils-SNAPSHOT</version>
<relativePath />
</parent>
......@@ -51,7 +51,7 @@
<spring-boot.build-image.imageName>docker.ozg-sh.de/vorgang-manager:build-latest</spring-boot.build-image.imageName>
<zufi-manager-interface.version>1.6.0</zufi-manager-interface.version>
<common-lib.version>4.12.0-SNAPSHOT</common-lib.version>
<user-manager-interface.version>2.12.0</user-manager-interface.version>
<processor-manager.version>0.5.0</processor-manager.version>
<nachrichten-manager.version>2.19.0-SNAPSHOT</nachrichten-manager.version>
......@@ -60,6 +60,7 @@
<collaboration-manager.version>0.7.0</collaboration-manager.version>
<archive-manager.version>0.3.0</archive-manager.version>
<document-manager.version>1.2.0</document-manager.version>
<eingang-manager-interface.version>2.19.0-SNAPSHOT</eingang-manager-interface.version>
<zip.version>2.11.5</zip.version>
<jsoup.version>1.15.3</jsoup.version>
......@@ -81,6 +82,11 @@
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>de.ozgcloud.common</groupId>
<artifactId>ozgcloud-common-lib</artifactId>
<version>${common-lib.version}</version>
</dependency>
<dependency>
<groupId>de.ozgcloud.nachrichten</groupId>
<artifactId>nachrichten-manager-server</artifactId>
......@@ -171,6 +177,11 @@
<artifactId>api-lib-core</artifactId>
<version>${api-lib.version}</version>
</dependency>
<dependency>
<groupId>de.ozgcloud.eingang</groupId>
<artifactId>eingang-manager-interface</artifactId>
<version>${eingang-manager-interface.version}</version>
</dependency>
<!-- Spring -->
<dependency>
......@@ -396,7 +407,8 @@
<env>
<BPE_DELIM_JAVA_TOOL_OPTIONS xml:space="preserve"> </BPE_DELIM_JAVA_TOOL_OPTIONS>
<BPE_APPEND_JAVA_TOOL_OPTIONS>-Dfile.encoding=UTF-8</BPE_APPEND_JAVA_TOOL_OPTIONS>
<BPE_APPEND_JAVA_TOOL_OPTIONS>-Dio.grpc.netty.shaded.io.netty.maxDirectMemory=0</BPE_APPEND_JAVA_TOOL_OPTIONS>
<BPE_APPEND_JAVA_TOOL_OPTIONS>
-Dio.grpc.netty.shaded.io.netty.maxDirectMemory=0</BPE_APPEND_JAVA_TOOL_OPTIONS>
<BPE_APPEND_JAVA_TOOL_OPTIONS>-XX:MaxDirectMemorySize=512m</BPE_APPEND_JAVA_TOOL_OPTIONS>
<BPE_APPEND_LC_ALL>en_US.UTF-8</BPE_APPEND_LC_ALL>
</env>
......
......@@ -36,7 +36,7 @@ import de.ozgcloud.vorgang.common.grpc.GrpcFormDataMapper;
nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE, //
nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, //
collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED)
interface EingangMapper {
public interface EingangMapper {
@Mapping(source = "attachmentsList", target = "attachments")
@Mapping(source = "representationsList", target = "representations")
......
......@@ -24,9 +24,12 @@
package de.ozgcloud.vorgang.vorgang;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import com.google.protobuf.ByteString;
import de.ozgcloud.eingang.forwarding.GrpcAttachmentFile;
import de.ozgcloud.eingang.forwarding.GrpcRepresentationFile;
import de.ozgcloud.vorgang.files.FileIdMapper;
@Mapper(uses = FileIdMapper.class)
......@@ -37,4 +40,29 @@ public interface IncomingFileMapper {
default byte[] map(ByteString value) {
return value.toByteArray();
}
@Mapping(target = "mergeFrom", ignore = true)
@Mapping(target = "clearField", ignore = true)
@Mapping(target = "clearOneof", ignore = true)
@Mapping(target = "mergeUnknownFields", ignore = true)
@Mapping(target = "contentTypeBytes", ignore = true)
@Mapping(target = "fileNameBytes", ignore = true)
@Mapping(target = "groupNameBytes", ignore = true)
@Mapping(target = "unknownFields", ignore = true)
@Mapping(target = "vendorIdBytes", ignore = true)
@Mapping(target = "allFields", ignore = true)
@Mapping(target = "fileName", source = "file.name")
GrpcAttachmentFile toAttachmentFile(String groupName, IncomingFile file);
@Mapping(target = "mergeFrom", ignore = true)
@Mapping(target = "clearField", ignore = true)
@Mapping(target = "clearOneof", ignore = true)
@Mapping(target = "mergeUnknownFields", ignore = true)
@Mapping(target = "contentTypeBytes", ignore = true)
@Mapping(target = "fileNameBytes", ignore = true)
@Mapping(target = "unknownFields", ignore = true)
@Mapping(target = "vendorIdBytes", ignore = true)
@Mapping(target = "allFields", ignore = true)
@Mapping(target = "fileName", source = "name")
GrpcRepresentationFile toRepresentationFile(IncomingFile file);
}
\ No newline at end of file
/*
* Copyright (C) 2025 Das Land Schleswig-Holstein vertreten durch den
* Ministerpräsidenten des Landes Schleswig-Holstein
* Staatskanzlei
* Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
*
* Lizenziert unter der EUPL, Version 1.2 oder - sobald
* diese von der Europäischen Kommission genehmigt wurden -
* Folgeversionen der EUPL ("Lizenz");
* Sie dürfen dieses Werk ausschließlich gemäß
* dieser Lizenz nutzen.
* Eine Kopie der Lizenz finden Sie hier:
*
* https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
*
* Sofern nicht durch anwendbare Rechtsvorschriften
* gefordert oder in schriftlicher Form vereinbart, wird
* die unter der Lizenz verbreitete Software "so wie sie
* ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
* ausdrücklich oder stillschweigend - verbreitet.
* Die sprachspezifischen Genehmigungen und Beschränkungen
* unter der Lizenz sind dem Lizenztext zu entnehmen.
*/
package de.ozgcloud.vorgang.vorgang.redirect;
import java.io.InputStream;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.BiFunction;
import java.util.function.Function;
import org.springframework.stereotype.Service;
import com.google.protobuf.ByteString;
import de.ozgcloud.common.binaryfile.GrpcFileUploadUtils;
import de.ozgcloud.common.binaryfile.GrpcFileUploadUtils.FileSender;
import de.ozgcloud.common.errorhandling.TechnicalException;
import de.ozgcloud.eingang.forwarder.RouteForwardingServiceGrpc;
import de.ozgcloud.eingang.forwarding.GrpcAttachment;
import de.ozgcloud.eingang.forwarding.GrpcFileContent;
import de.ozgcloud.eingang.forwarding.GrpcRepresentation;
import de.ozgcloud.eingang.forwarding.GrpcRouteForwardingRequest;
import de.ozgcloud.eingang.forwarding.GrpcRouteForwardingResponse;
import de.ozgcloud.vorgang.callcontext.VorgangManagerClientCallContextAttachingInterceptor;
import de.ozgcloud.vorgang.files.FileService;
import de.ozgcloud.vorgang.vorgang.Eingang;
import de.ozgcloud.vorgang.vorgang.IncomingFile;
import de.ozgcloud.vorgang.vorgang.IncomingFileGroup;
import de.ozgcloud.vorgang.vorgang.IncomingFileMapper;
import de.ozgcloud.vorgang.vorgang.VorgangService;
import io.grpc.stub.CallStreamObserver;
import io.grpc.stub.StreamObserver;
import lombok.RequiredArgsConstructor;
import net.devh.boot.grpc.client.inject.GrpcClient;
@Service
@RequiredArgsConstructor
class ForwardingRemoteService {
private static final int TIMEOUT_MINUTES = 2;
private final VorgangService vorgangService;
private final ForwardingRequestMapper forwardingRequestMapper;
@GrpcClient("forwarder")
private final RouteForwardingServiceGrpc.RouteForwardingServiceStub serviceStub;
private final FileService fileService;
private final IncomingFileMapper incomingFileMapper;
public void forward(ForwardingRequest request) {
CompletableFuture<Void> responseFuture = new CompletableFuture<>();
routeForwarding(request, new ForwardingResponseObserver(responseFuture));
waitForCompletion(responseFuture);
}
void routeForwarding(ForwardingRequest request, ForwardingResponseObserver responseObserver) {
var requestStreamObserver = serviceStub.withInterceptors(new VorgangManagerClientCallContextAttachingInterceptor())
.routeForwarding(responseObserver);
try {
sendEingang(request, requestStreamObserver);
requestStreamObserver.onCompleted();
} catch (Exception e) {
requestStreamObserver.onError(e);
throw e;
}
}
void sendEingang(ForwardingRequest request, StreamObserver<GrpcRouteForwardingRequest> requestStreamObserver) {
var eingang = vorgangService.getById(request.getVorgangId()).getEingangs().getFirst();
requestStreamObserver.onNext(buildRouteForwardingRequest(request, eingang));
sendAttachments(eingang.getAttachments(), requestStreamObserver);
sendRepresentations(eingang.getRepresentations(), requestStreamObserver);
}
GrpcRouteForwardingRequest buildRouteForwardingRequest(ForwardingRequest request, Eingang eingang) {
var routeForwarding = forwardingRequestMapper.toGrpcRouteForwarding(request, eingang);
return GrpcRouteForwardingRequest.newBuilder().setRouteForwarding(routeForwarding).build();
}
void sendAttachments(List<IncomingFileGroup> attachments, StreamObserver<GrpcRouteForwardingRequest> requestStreamObserver) {
for (var attachment : attachments) {
var groupName = attachment.getName();
attachment.getFiles().forEach(file -> sendAttachmentFile(requestStreamObserver, groupName, file));
}
}
private void sendAttachmentFile(StreamObserver<GrpcRouteForwardingRequest> requestStreamObserver, String groupName, IncomingFile file) {
var fileContentStream = fileService.getUploadedFileStream(file.getId());
createAttachmentFileSender(requestStreamObserver, groupName, file, fileContentStream).send();
}
FileSender<GrpcRouteForwardingRequest, GrpcRouteForwardingResponse> createAttachmentFileSender(
StreamObserver<GrpcRouteForwardingRequest> requestStreamObserver, String groupName, IncomingFile file, InputStream fileContentStream) {
return createSenderWithoutMetadata(this::buildAttachmentChunk, requestStreamObserver, fileContentStream)
.withMetaData(buildGrpcAttachmentFile(groupName, file));
}
GrpcRouteForwardingRequest buildAttachmentChunk(byte[] chunk, int length) {
return GrpcRouteForwardingRequest.newBuilder()
.setAttachment(GrpcAttachment.newBuilder()
.setContent(buildGrpcFileContent(chunk, length))
.build())
.build();
}
GrpcRouteForwardingRequest buildGrpcAttachmentFile(String name, IncomingFile file) {
return GrpcRouteForwardingRequest.newBuilder()
.setAttachment(GrpcAttachment.newBuilder()
.setFile(incomingFileMapper.toAttachmentFile(name, file))
.build())
.build();
}
void sendRepresentations(List<IncomingFile> representations, StreamObserver<GrpcRouteForwardingRequest> requestObserver) {
representations.forEach(representation -> {
var fileContentStream = fileService.getUploadedFileStream(representation.getId());
createRepresentationFileSender(requestObserver, representation, fileContentStream).send();
});
}
FileSender<GrpcRouteForwardingRequest, GrpcRouteForwardingResponse> createRepresentationFileSender(
StreamObserver<GrpcRouteForwardingRequest> requestStreamObserver, IncomingFile file, InputStream fileContentStream) {
return createSenderWithoutMetadata(this::buildRepresentationChunk, requestStreamObserver, fileContentStream)
.withMetaData(buildGrpcRepresentationFile(file));
}
FileSender<GrpcRouteForwardingRequest, GrpcRouteForwardingResponse> createSenderWithoutMetadata(
BiFunction<byte[], Integer, GrpcRouteForwardingRequest> chunkBuilder,
StreamObserver<GrpcRouteForwardingRequest> requestStreamObserver, InputStream fileContentStream) {
return GrpcFileUploadUtils
.createSender(chunkBuilder, fileContentStream, requestCallStreamObserverProvider(requestStreamObserver), false);
}
private Function<StreamObserver<GrpcRouteForwardingResponse>, CallStreamObserver<GrpcRouteForwardingRequest>> requestCallStreamObserverProvider(
StreamObserver<GrpcRouteForwardingRequest> requestStreamObserver) {
return response -> (CallStreamObserver<GrpcRouteForwardingRequest>) requestStreamObserver;
}
GrpcRouteForwardingRequest buildRepresentationChunk(byte[] chunk, int length) {
return GrpcRouteForwardingRequest.newBuilder()
.setRepresentation(GrpcRepresentation.newBuilder()
.setContent(buildGrpcFileContent(chunk, length))
.build())
.build();
}
GrpcFileContent buildGrpcFileContent(byte[] chunk, int length) {
var fileContentBuilder = GrpcFileContent.newBuilder();
if (length <= 0) {
fileContentBuilder.setIsEndOfFile(true);
} else {
fileContentBuilder.setContent(ByteString.copyFrom(chunk));
}
return fileContentBuilder.build();
}
GrpcRouteForwardingRequest buildGrpcRepresentationFile(IncomingFile file) {
return GrpcRouteForwardingRequest.newBuilder()
.setRepresentation(GrpcRepresentation.newBuilder()
.setFile(incomingFileMapper.toRepresentationFile(file))
.build())
.build();
}
void waitForCompletion(CompletableFuture<Void> responseFuture) {
try {
responseFuture.get(TIMEOUT_MINUTES, TimeUnit.MINUTES);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new TechnicalException("Waiting for finishing file upload was interrupted.", e);
} catch (ExecutionException e) {
throw new TechnicalException("Error on uploading file content.", e);
} catch (TimeoutException e) {
throw new TechnicalException("Timeout on uploading file content.", e);
}
}
@RequiredArgsConstructor
static class ForwardingResponseObserver implements StreamObserver<GrpcRouteForwardingResponse> {
private final CompletableFuture<Void> future;
@Override
public void onNext(GrpcRouteForwardingResponse value) {
// noop
}
@Override
public void onError(Throwable t) {
future.completeExceptionally(t);
}
@Override
public void onCompleted() {
future.complete(null);
}
}
}
......@@ -26,12 +26,24 @@ package de.ozgcloud.vorgang.vorgang.redirect;
import java.util.Map;
import org.apache.commons.collections4.MapUtils;
import org.mapstruct.CollectionMappingStrategy;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.NullValueCheckStrategy;
import org.mapstruct.NullValuePropertyMappingStrategy;
import de.ozgcloud.command.Command;
import de.ozgcloud.eingang.forwarding.GrpcEingangStub;
import de.ozgcloud.eingang.forwarding.GrpcRouteCriteria;
import de.ozgcloud.eingang.forwarding.GrpcRouteForwarding;
import de.ozgcloud.vorgang.vorgang.Eingang;
import de.ozgcloud.vorgang.vorgang.EingangMapper;
import de.ozgcloud.vorgang.vorgang.GrpcEingang;
@Mapper(imports = MapUtils.class)
@Mapper(imports = MapUtils.class, uses = EingangMapper.class, //
nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE, //
nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, //
collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED)
interface ForwardingRequestMapper {
interface CommandBodyFields {
......@@ -57,4 +69,17 @@ interface ForwardingRequestMapper {
@Mapping(target = "zipCode", expression = "java(MapUtils.getString(body, CommandBodyFields.PLZ))")
@Mapping(target = "city", expression = "java(MapUtils.getString(body, CommandBodyFields.ORT))")
Address toAddress(Map<String, Object> body);
@Mapping(target = "routeCriteria", source = "request")
@Mapping(target = "eingangStub", source = "eingang")
@Mapping(target = "unknownFields", ignore = true)
@Mapping(target = "allFields", ignore = true)
GrpcRouteForwarding toGrpcRouteForwarding(ForwardingRequest request, Eingang eingang);
@Mapping(target = "organisationEinheitId", source = "organisationEinheit.id")
GrpcRouteCriteria toGrpcRouteCriteria(ForwardingRequest request);
@Mapping(target = "unknownFields", ignore = true)
@Mapping(target = "allFields", ignore = true)
GrpcEingangStub toGrpcEingangStub(GrpcEingang eingang);
}
......@@ -35,7 +35,6 @@ import java.util.stream.Stream;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
......@@ -56,10 +55,12 @@ import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import jakarta.mail.util.ByteArrayDataSource;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
@Service
@Log4j2
@RequiredArgsConstructor
public class ForwardingService {
static final String MAIL_TEMPLATE = "/mail/redirect.txt.ftlh";
......@@ -87,26 +88,15 @@ public class ForwardingService {
static final String SUBJECT_BESTAETIGUNG_TEMPL = "Ihr Antrag auf %s - Az: %s";
static final String ZIP_FILENAME_TMPL = "%s.zip";
@Autowired
private ForwardingRepository repository;
@Autowired
private Configuration freemarkerCfg;
@Autowired
private ZipBuilderService zipService;
@Autowired
private MailService emailService;
@Autowired
private VorgangService vorgangService;
private final ForwardingRepository repository;
private final Configuration freemarkerCfg;
private final ZipBuilderService zipService;
private final MailService emailService;
private final VorgangService vorgangService;
// TODO abhängigkeit entfernen
@Autowired
private StatusService statusService;
@Autowired
private ApplicationEventPublisher publisher;
private final StatusService statusService;
private final ForwardingRemoteService forwardingRemoteService;
private final ApplicationEventPublisher publisher;
@Value("${ozgcloud.redirect.mail-from}")
private String mailFrom;
......@@ -332,5 +322,6 @@ public class ForwardingService {
public void forward(ForwardingRequest request) {
statusService.setStatusToWeitergeleitet(request.getVorgangId(), request.getVersion());
forwardingRemoteService.forward(request);
}
}
\ No newline at end of file
......@@ -38,6 +38,10 @@ grpc:
negotiationType: PLAINTEXT
vorgang-manager:
negotiationType: PLAINTEXT
forwarder:
address: static://127.0.0.1:9292
negotiationType: PLAINTEXT
server:
security:
enabled: false
......
......@@ -44,6 +44,8 @@ grpc:
negotiationType: PLAINTEXT
zufi-manager:
negotiationType: TLS
forwarder:
negotiationType: TLS
server:
security:
......
......@@ -49,6 +49,9 @@ public class EingangTestFactory {
public static final Map<String, Object> SUBFORM_FLAT = Map.of(SUBFORM_FIELD_NAME, SUBFORM_FIELD);
public static final Map<String, Object> FORM_DATA = Map.of(SINGLE_FIELD_NAME, SINGLE_FIELD, SUBFORM_NAME, SUBFORM);
public static final IncomingFileGroup ATTACHMENT = IncomingFileGroupTestFactory.create();
public static final IncomingFile REPRESENTATION = IncomingFileTestFactory.create();
public static Eingang create() {
return createBuilder().build();
}
......@@ -59,8 +62,8 @@ public class EingangTestFactory {
.header(EingangHeaderTestFactory.create())
.antragsteller(AntragstellerTestFactory.create())
.formData(FORM_DATA)
.attachment(IncomingFileGroupTestFactory.create())
.representation(IncomingFileTestFactory.create())
.attachment(ATTACHMENT)
.representation(REPRESENTATION)
.zustaendigeStelle(ZustaendigeStelleTestFactory.create());
}
}
\ No newline at end of file
......@@ -25,12 +25,11 @@ package de.ozgcloud.vorgang.vorgang;
import java.util.UUID;
import de.ozgcloud.vorgang.common.grpc.GrpcSubFormTestFactory;
import de.ozgcloud.vorgang.common.grpc.GrpcFormDataTestFactory;
public class GrpcEingangTestFactory {
public static final String ID = UUID.randomUUID().toString();
public static final GrpcSubForm SUB_FORM = GrpcSubFormTestFactory.create();
public static GrpcEingang create() {
return createBuilder().build();
......@@ -42,7 +41,7 @@ public class GrpcEingangTestFactory {
.setHeader(GrpcEingangHeaderTestFactory.create())
.setAntragsteller(GrpcAntragstellerTestFactory.create())
.setZustaendigeStelle(GrpcZustaendigeStelleTestFactory.create())
.setFormData(GrpcFormData.newBuilder().addForm(GrpcSubFormTestFactory.create()).build())
.setFormData(GrpcFormDataTestFactory.create())
.addAttachments(GrpcIncomingFileGroupTestFactory.create())
.setNumberOfAttachments(4)
.addRepresentations(GrpcIncomingFileTestFactory.create())
......
......@@ -32,6 +32,8 @@ import org.mockito.InjectMocks;
import org.mockito.Spy;
import de.ozgcloud.vorgang.files.FileIdMapper;
import de.ozgcloud.vorgang.vorgang.redirect.GrpcAttachmentFileTestFactory;
import de.ozgcloud.vorgang.vorgang.redirect.GrpcRepresentationFileTestFactory;
class IncomingFileMapperTest {
......@@ -50,4 +52,26 @@ class IncomingFileMapperTest {
assertThat(result).isNotNull().usingRecursiveComparison().isEqualTo(IncomingFileTestFactory.create());
}
}
@Nested
class TestToAttachmentFile {
@Test
void shouldMapToGrpcAttachmentFile() {
var result = mapper.toAttachmentFile(GrpcAttachmentFileTestFactory.GROUP_NAME, IncomingFileTestFactory.create());
assertThat(result).isEqualTo(GrpcAttachmentFileTestFactory.create());
}
}
@Nested
class TestToRepresentationFile {
@Test
void shouldMapToGrpcRepresentationFile() {
var result = mapper.toRepresentationFile(IncomingFileTestFactory.create());
assertThat(result).isEqualTo(GrpcRepresentationFileTestFactory.create());
}
}
}
\ No newline at end of file
......@@ -223,7 +223,7 @@ class VorgangGrpcServiceITCase {
}
private static GrpcFormData expectedFormData() {
var grpcFormData = GrpcFormDataTestFactory.createBuilder().clearField().addAllField(formFields);
var grpcFormData = GrpcFormDataTestFactory.createBuilder().clearField().addAllField(formFields).clearForm();
for (String subFormName : List.of(TITLE_SUBFORM_1, TITLE_SUBFORM_2, TITLE_SUBFORM_3)) {
grpcFormData.addForm(GrpcSubForm.newBuilder()
.setTitle(subFormName)
......
......@@ -32,14 +32,26 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.mapstruct.factory.Mappers;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Spy;
import de.ozgcloud.eingang.forwarding.GrpcRouteCriteria;
import de.ozgcloud.eingang.forwarding.GrpcRouteForwarding;
import de.ozgcloud.vorgang.command.CommandTestFactory;
import de.ozgcloud.vorgang.vorgang.Eingang;
import de.ozgcloud.vorgang.vorgang.EingangMapper;
import de.ozgcloud.vorgang.vorgang.EingangTestFactory;
import de.ozgcloud.vorgang.vorgang.GrpcEingang;
import de.ozgcloud.vorgang.vorgang.GrpcEingangTestFactory;
import de.ozgcloud.vorgang.vorgang.redirect.ForwardingRequestMapper.CommandBodyFields;
class ForwardingRequestMapperTest {
@Mock
private EingangMapper eingangMapper;
@Spy
@InjectMocks
private ForwardingRequestMapper mapper = Mappers.getMapper(ForwardingRequestMapper.class);
private final Map<String, Object> bodyObject = Map.of(
CommandBodyFields.ORGANISATION_EINHEIT_ID, OrganisationEinheitTestFactory.ID,
......@@ -118,4 +130,65 @@ class ForwardingRequestMapperTest {
return mapper.toAddress(bodyObject);
}
}
@Nested
class TestToGrpcRouteForwarding {
private final ForwardingRequest request = ForwardingRequestTestFactory.create();
private final Eingang eingang = EingangTestFactory.create();
private final GrpcEingang grpcEingang = GrpcEingangTestFactory.create();
@BeforeEach
void init() {
doReturn(GrpcRouteCriteriaTestFactory.create()).when(mapper).toGrpcRouteCriteria(any());
when(eingangMapper.toGrpc(any())).thenReturn(grpcEingang);
}
@Test
void shouldCallEingangMapper() {
map();
verify(eingangMapper).toGrpc(eingang);
}
@Test
void shouldMapToGrpcRouteCriteria() {
map();
verify(mapper).toGrpcRouteCriteria(request);
}
@Test
void shouldMapToGrpcEingangStub() {
map();
verify(mapper).toGrpcEingangStub(grpcEingang);
}
@Test
void shouldMapToGrpcRouteForwarding() {
var mapped = map();
assertThat(mapped).isEqualTo(GrpcRouteForwardingTestFactory.create());
}
private GrpcRouteForwarding map() {
return mapper.toGrpcRouteForwarding(request, eingang);
}
}
@Nested
class TestToGrpcRouteCriteria {
@Test
void shouldMap() {
var mapped = map();
assertThat(mapped).isEqualTo(GrpcRouteCriteriaTestFactory.create());
}
private GrpcRouteCriteria map() {
return mapper.toGrpcRouteCriteria(ForwardingRequestTestFactory.create());
}
}
}
......@@ -64,19 +64,16 @@ class ForwardingServiceTest {
private ForwardingService service;
@Mock
private ForwardingRepository repository;
@Mock
private ZipBuilderService zipService;
@Mock
private MailService mailService;
@Mock
private VorgangService vorgangService;
@Mock
private StatusService statusService;
@Mock
private ForwardingRemoteService remoteService;
@Mock
private ApplicationEventPublisher publisher;
......@@ -626,11 +623,24 @@ class ForwardingServiceTest {
@Nested
class TestForward {
private final ForwardingRequest request = ForwardingRequestTestFactory.create();
@Test
void shouldSetStatusToWeitergeleitet() {
service.forward(ForwardingRequestTestFactory.create());
forward();
verify(statusService).setStatusToWeitergeleitet(VorgangTestFactory.ID, VorgangTestFactory.VERSION);
}
@Test
void shouldCallRemoteService() {
forward();
verify(remoteService).forward(request);
}
private void forward() {
service.forward(request);
}
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment