
no.difi.meldingsutveksling.ks.mapping.FiksMapper Maven / Gradle / Ivy
package no.difi.meldingsutveksling.ks.mapping;
import lombok.extern.slf4j.Slf4j;
import no.arkivverket.standarder.noark5.arkivmelding.*;
import no.arkivverket.standarder.noark5.metadatakatalog.Korrespondanseparttype;
import no.arkivverket.standarder.noark5.metadatakatalog.TilknyttetRegistreringSom;
import no.difi.meldingsutveksling.DateTimeUtil;
import no.difi.meldingsutveksling.api.OptionalCryptoMessagePersister;
import no.difi.meldingsutveksling.arkivmelding.ArkivmeldingUtil;
import no.difi.meldingsutveksling.config.IntegrasjonspunktProperties;
import no.difi.meldingsutveksling.dokumentpakking.service.CreateCMSDocument;
import no.difi.meldingsutveksling.domain.arkivmelding.JournalposttypeMapper;
import no.difi.meldingsutveksling.domain.arkivmelding.JournalstatusMapper;
import no.difi.meldingsutveksling.domain.sbdh.SBDUtil;
import no.difi.meldingsutveksling.ks.svarut.*;
import no.difi.meldingsutveksling.nextmove.*;
import no.difi.meldingsutveksling.serviceregistry.ServiceRegistryLookup;
import no.difi.meldingsutveksling.serviceregistry.externalmodel.InfoRecord;
import no.difi.move.common.io.ResourceDataSource;
import no.difi.move.common.io.pipe.Reject;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import javax.activation.DataHandler;
import javax.xml.bind.JAXBException;
import java.io.IOException;
import java.math.BigInteger;
import java.security.cert.X509Certificate;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static java.lang.String.format;
import static no.difi.meldingsutveksling.NextMoveConsts.ARKIVMELDING_FILE;
@Slf4j
@Component
public class FiksMapper {
private final IntegrasjonspunktProperties properties;
private final ServiceRegistryLookup serviceRegistry;
private final OptionalCryptoMessagePersister optionalCryptoMessagePersister;
private final CreateCMSDocument createCMSDocument;
private final ArkivmeldingUtil arkivmeldingUtil;
private final Supplier algorithmIdentifierSupplier;
public FiksMapper(IntegrasjonspunktProperties properties,
ServiceRegistryLookup serviceRegistry,
OptionalCryptoMessagePersister optionalCryptoMessagePersister,
CreateCMSDocument createCMSDocument,
ArkivmeldingUtil arkivmeldingUtil,
Supplier algorithmIdentifierSupplier) {
this.properties = properties;
this.serviceRegistry = serviceRegistry;
this.optionalCryptoMessagePersister = optionalCryptoMessagePersister;
this.createCMSDocument = createCMSDocument;
this.algorithmIdentifierSupplier = algorithmIdentifierSupplier;
this.arkivmeldingUtil = arkivmeldingUtil;
}
public SendForsendelseMedId mapFrom(NextMoveOutMessage message, X509Certificate certificate, Reject reject) throws NextMoveException {
Optional senderRef = SBDUtil.getOptionalSenderRef(message.getSbd());
// Confirm that SenderRef is a valid UUID, else use messageId
if (senderRef.isPresent()) {
try {
//noinspection ResultOfMethodCallIgnored
UUID.fromString(senderRef.get());
} catch (IllegalArgumentException e) {
senderRef = Optional.empty();
}
}
String forsendelsesid = senderRef.orElse(message.getMessageId());
return SendForsendelseMedId.builder()
.withForsendelse(getForsendelse(message, certificate, reject))
.withForsendelsesid(forsendelsesid)
.build();
}
private Forsendelse getForsendelse(NextMoveOutMessage message, X509Certificate certificate, Reject reject) throws NextMoveException {
Arkivmelding am = getArkivmelding(message);
Saksmappe saksmappe = arkivmeldingUtil.getSaksmappe(am);
Journalpost journalpost = arkivmeldingUtil.getJournalpost(am);
Optional receiverRef = SBDUtil.getOptionalReceiverRef(message.getSbd());
if (receiverRef.isPresent()) {
try {
//noinspection ResultOfMethodCallIgnored
UUID.fromString(receiverRef.get());
} catch (IllegalArgumentException e) {
receiverRef = Optional.empty();
}
}
return Forsendelse.builder()
.withEksternref(message.getMessageId())
.withForsendelseType(getForsendelseType(message))
.withKunDigitalLevering(false)
.withSvarPaForsendelse(receiverRef.orElse(null))
.withTittel(journalpost.getOffentligTittel())
.withKrevNiva4Innlogging(kreverNiva4Innlogging(message))
.withKonteringskode(properties.getFiks().getUt().getKonteringsKode())
.withKryptert(properties.getFiks().isKryptert())
.withAvgivendeSystem(properties.getNoarkSystem().getType())
.withPrintkonfigurasjon(getPrintkonfigurasjon())
.withMottaker(getMottaker(message))
.withSvarSendesTil(getSvarSendesTil(message, journalpost))
.withMetadataFraAvleverendeSystem(metaDataFrom(saksmappe, journalpost))
.withDokumenter(mapArkivmeldingDokumenter(message, getDokumentbeskrivelser(journalpost), certificate, reject))
.withKunDigitalLevering(properties.getFiks().getUt().isKunDigitalLevering())
.build();
}
private String getForsendelseType(NextMoveOutMessage message) {
return getDpfSettings(message)
.map(DpfSettings::getForsendelseType)
.filter(StringUtils::hasText)
.orElse(null);
}
private Optional getDpfSettings(NextMoveOutMessage message) {
if (message.getBusinessMessage() instanceof ArkivmeldingMessage) {
ArkivmeldingMessage arkivmeldingMessage = (ArkivmeldingMessage) message.getBusinessMessage();
return Optional.ofNullable(arkivmeldingMessage.getDpf());
}
return Optional.empty();
}
private Printkonfigurasjon getPrintkonfigurasjon() {
return Printkonfigurasjon.builder()
.withTosidig(true)
.withFargePrint(false)
.withBrevtype(Brevtype.BPOST).build();
}
private Adresse getSvarSendesTil(NextMoveOutMessage message, Journalpost journalpost) {
for (Korrespondansepart part : journalpost.getKorrespondansepart()){
if (part.getKorrespondanseparttype() == null) {
log.warn("Invalid value for korrespondanseparttype element in Noark5 arkivmelding");
journalpost.getKorrespondansepart().clear();
break;
}
}
return journalpost.getKorrespondansepart().stream()
.filter(k -> k.getKorrespondanseparttype().equals(Korrespondanseparttype.AVSENDER))
.map(a -> mottakerFrom(a, message.getSenderIdentifier()))
.findFirst()
.orElseGet(() -> mottakerFrom(serviceRegistry.getInfoRecord(message.getSenderIdentifier())));
}
private boolean kreverNiva4Innlogging(NextMoveOutMessage message) {
Integer sikkerhetsnivaa = message.getBusinessMessage().getSikkerhetsnivaa();
return sikkerhetsnivaa != null && sikkerhetsnivaa == 4;
}
private List getDokumentbeskrivelser(Journalpost journalpost) {
return journalpost.getDokumentbeskrivelseAndDokumentobjekt().stream()
.filter(Dokumentbeskrivelse.class::isInstance)
.map(Dokumentbeskrivelse.class::cast)
.sorted((o1, o2) -> {
if (TilknyttetRegistreringSom.HOVEDDOKUMENT.equals(o1.getTilknyttetRegistreringSom())) {
return -1;
} else if (TilknyttetRegistreringSom.HOVEDDOKUMENT.equals(o2.getTilknyttetRegistreringSom())) {
return 1;
}
return 0;
})
.collect(Collectors.toList());
}
private Adresse getMottaker(NextMoveOutMessage message) {
final InfoRecord receiverInfo = serviceRegistry.getInfoRecord(message.getReceiverIdentifier());
return mottakerFrom(receiverInfo);
}
private Arkivmelding getArkivmelding(NextMoveOutMessage message) throws NextMoveException {
String identifier = getArkivmeldingIdentifier(message);
try {
Resource resource = optionalCryptoMessagePersister.read(message.getMessageId(), identifier);
return arkivmeldingUtil.unmarshalArkivmelding(resource);
} catch (JAXBException | IOException e) {
throw new NextMoveRuntimeException("Failed to get Arkivmelding", e);
}
}
private String getArkivmeldingIdentifier(NextMoveOutMessage message) throws NextMoveException {
return message.getFiles().stream()
.filter(f -> ARKIVMELDING_FILE.equals(f.getFilename()))
.findAny()
.map(BusinessMessageFile::getIdentifier)
.orElseThrow(() -> new NextMoveException(format("No attachement \"%s\" found", ARKIVMELDING_FILE)));
}
private List mapArkivmeldingDokumenter(NextMoveOutMessage message, List docs, X509Certificate cert, Reject reject) {
return docs.stream()
.sorted((o1, o2) -> {
if (TilknyttetRegistreringSom.HOVEDDOKUMENT.equals(o1.getTilknyttetRegistreringSom())) {
return -1;
} else if (TilknyttetRegistreringSom.HOVEDDOKUMENT.equals(o2.getTilknyttetRegistreringSom())) {
return 1;
}
return 0;
})
.flatMap(p -> p.getDokumentobjekt().stream())
.map(d -> getBusinessMessageFile(message, d.getReferanseDokumentfil()))
.map(file -> getDocument(message.getMessageId(), file, cert, reject))
.collect(Collectors.toList());
}
private BusinessMessageFile getBusinessMessageFile(NextMoveOutMessage message, String referanseDokumentfil) {
return message.getFiles().stream()
.filter(bmf -> bmf.getFilename().equals(referanseDokumentfil))
.findFirst()
.orElseThrow(() -> new NextMoveRuntimeException(
String.format("File '%s' referenced in '%s' not found", referanseDokumentfil, message.getMessageId())));
}
private Dokument getDocument(String messageId, BusinessMessageFile file, X509Certificate cert, Reject reject) {
Resource document = readDocument(messageId, file);
Resource encryptedDocument = createCMSDocument.encrypt(CreateCMSDocument.Input.builder()
.resource(document)
.certificate(cert)
.keyEncryptionScheme(algorithmIdentifierSupplier.get())
.build(), reject);
Dokument.Builder builder = Dokument.builder()
.withData(new DataHandler(new ResourceDataSource(encryptedDocument)))
.withFilnavn(file.getFilename())
.withMimetype(file.getMimetype());
String ext = Stream.of(file.getFilename().split("\\.")).reduce((a, b) -> b).orElse("pdf");
if (ext.equalsIgnoreCase("pdf")) {
builder.withEkskluderesFraPrint(false);
} else if (properties.getFiks().getUt().getEkskluderesFraPrint().contains("*")) {
builder.withEkskluderesFraPrint(true);
} else if (properties.getFiks().getUt().getEkskluderesFraPrint().contains(ext)) {
builder.withEkskluderesFraPrint(true);
}
return builder.build();
}
private Resource readDocument(String messageId, BusinessMessageFile file) {
try {
return optionalCryptoMessagePersister.read(messageId, file.getIdentifier());
} catch (IOException e) {
throw new NextMoveRuntimeException(String.format("Could not read file named '%s' for messageId='%s'", file.getIdentifier(), messageId), e);
}
}
private NoarkMetadataFraAvleverendeSakssystem metaDataFrom(Saksmappe sm, Journalpost jp) {
return NoarkMetadataFraAvleverendeSakssystem.builder()
.withSakssekvensnummer(toInt(sm.getSakssekvensnummer()))
.withSaksaar(toInt(sm.getSaksaar()))
.withJournalaar(toInt(jp.getJournalaar()))
.withJournalsekvensnummer(toInt(jp.getJournalsekvensnummer()))
.withJournalpostnummer(toInt(jp.getJournalpostnummer()))
.withJournalposttype(JournalposttypeMapper.getNoarkType(jp.getJournalposttype()))
.withJournalstatus(JournalstatusMapper.getNoarkType(jp.getJournalstatus()))
.withJournaldato(DateTimeUtil.atStartOfDay(jp.getJournaldato()))
.withDokumentetsDato(DateTimeUtil.atStartOfDay(jp.getDokumentetsDato()))
.withTittel(jp.getOffentligTittel())
.withSaksbehandler(getSaksbehandler(jp).orElse(null))
.build();
}
private Optional getSaksbehandler(Journalpost jp) {
return jp.getKorrespondansepart().stream()
.filter(k -> k.getKorrespondanseparttype().equals(Korrespondanseparttype.AVSENDER))
.findFirst()
.map(Korrespondansepart::getSaksbehandler);
}
private int toInt(BigInteger x) {
return x == null ? 0 : x.intValueExact();
}
private Adresse mottakerFrom(Korrespondansepart kp, String orgnr) {
return Adresse.builder()
.withDigitalAdresse(OrganisasjonDigitalAdresse.builder().withOrgnr(orgnr).build())
.withPostAdresse(PostAdresse.builder()
.withNavn(kp.getKorrespondansepartNavn())
.withAdresse1(String.join(" ", kp.getPostadresse()))
.withPostnr(kp.getPostnummer())
.withPoststed(kp.getPoststed())
.withLand(kp.getLand())
.build())
.build();
}
private Adresse mottakerFrom(InfoRecord infoRecord) {
return Adresse.builder()
.withDigitalAdresse(OrganisasjonDigitalAdresse.builder()
.withOrgnr(infoRecord.getIdentifier())
.build())
.withPostAdresse(getPostAdresse(infoRecord))
.build();
}
private PostAdresse getPostAdresse(InfoRecord infoRecord) {
PostAdresse.Builder builder = PostAdresse.builder()
.withNavn(infoRecord.getOrganizationName());
if (infoRecord.getPostadresse() != null) {
builder.withAdresse1(infoRecord.getPostadresse().getAdresse())
.withPostnr(infoRecord.getPostadresse().getPostnummer())
.withPoststed(infoRecord.getPostadresse().getPoststed())
.withLand(infoRecord.getPostadresse().getLand());
} else {
builder.withPostnr("0192")
.withPoststed("Oslo")
.withLand("Norge");
}
return builder.build();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy