Skip to content

Commit

Permalink
Valideringsendepunkt tilpasset format (#3682)
Browse files Browse the repository at this point in the history
* Add syfosmregler consumer for sykemelding validation #deploy-test-sykemelding-api

Introduced a new consumer, `SyfosmreglerConsumer`, to enable validation of sykemeldings using the sykemelding proxy service. This addition includes necessary DTOs and configurations, allowing the system to validate submitted sykemeldings and return validation results. Additionally, the `SykemeldingService` and `SykemeldingController` have been updated to incorporate the validation functionality.

* Rename @PostMapping endpoint to /validate #deploy-test-sykemelding-api

The endpoint change in SykemeldingController aligns with its purpose of validating a sykemelding. This update enhances clarity and better represents the action being performed by this method.

* Implement Orika mapping for sykemelding validation. #deploy-test-sykemelding-api

Added Orika MapperFacade to support sykemelding validation process by mapping Sykemelding to ReceivedSykemeldingDTO. Created new mapping strategy interface and configuration class to define mapping strategy and register mappers and converters. Removed unnecessary Swagger dependency from build.gradle.

* Add Orika mapping utilities and tests.
#deploy-test-sykemelding-api

Introduced MapperTestUtils and SykemeldingValidateMappingStrategyTest to establish a testing framework for Orika-based mapping strategies in sykemelding validation. Updated SykemeldingConsumer to improve logging by utilizing Json.pretty for detailed request logging.

* Add JAVA_OPTS for module accessibility in Dockerfile #deploy-test-sykemelding-api

Include the JAVA_OPTS environment variable to grant unnamed module access to java.lang in the Dockerfile. This change ensures compatibility with reflective operations or frameworks needing internal JDK classes, enhancing runtime flexibility.

* Add sykemelding API applications to proxy config
#deploy-proxy-sykemelding

Included `testnav-sykemelding-api-dev` and `testnav-sykemelding-api` in the sykemelding-proxy configuration to ensure proper routing and access. This update supports the deployment of new sykemelding API environments.

* Enhance error handling in sykemelding validation.
#deploy-test-sykemelding-api

Added error handling in SyfosmreglerPostValidateCommand to capture and log errors, assigning relevant HTTP status and message to ValidationResultDTO. This improves reliability and debuggability by providing more information about the error state during the sykemelding validation process. Additionally, updated ValidationResultDTO and included a new import in test cases for consistency.

* Add logging to SyfosmreglerPostValidateCommand
#deploy-test-sykemelding-api

Enhanced the SyfosmreglerPostValidateCommand with logging capability using SLF4J, allowing more detailed insights into the data being sent for validation. This update includes utilizing the pretty print feature of Json to format the logged sykemelding data, ensuring clarity for debugging purposes.

* Add Sykemelding mapping and application-local.yml #deploy-test-sykemelding-api

Implemented a comprehensive mapping strategy in SykemeldingValidateMappingStrategy to transform Sykemelding to ReceivedSykemeldingDTO. Introduced application-local.yml for local development configuration with default dummy values for IBM MQ connection and sykemelding-proxy consumer. Revised associated data structures and test cases to support new mapping functionalities.

* Add UtdypendeOpplysninger feature to Sykemelding. #deploy-test-sykemelding-api

Introduce new classes and methods to handle UtdypendeOpplysninger in Sykemelding. The changes include the addition of a new domain and DTO for UtdypendeOpplysninger, updates to mapper logic, and adjustment in tests to ensure proper validation.

* Fix incorrect restriction value indexing in UtdypendeOpplysninger #deploy-test-sykemelding-api

Correct the restriction value calculation to align with the ordinal index of enum members by removing the unnecessary increment. This ensures the restriction values are accurately mapped and prevents potential data inconsistencies.

* Add support for additional measures in sykemelding DTO #deploy-test-sykemelding-api

Introduced the andreTiltak field in DetaljerDTO to capture additional work measures. Updated SykemeldingValidateMappingStrategy and accompanying tests to handle mapping of biDiagnoser and andreTiltak, ensuring complete DTO representations. Modified domain classes to align with new DTO structure.

* Refactor DTO classes to use Lombok's @DaTa annotation
#deploy-test-sykemelding-api

Replaced @value, @Getter, and @Setter with @DaTa for simplicity and consistency across all DTO classes. Removed the forced argument requirement from @NoArgsConstructor where it was previously applied. Additionally, adjusted null handling in the "Arbeidsgiver" domain class to manage DTO presence better.

* Implement arbeidsgiver mapping and update tests
#deploy-test-sykemelding-api

Introduced the method `mapHarArbeidsgiver` to handle mapping of arbeidsgiver types based on XML input, supporting cases for "EN_ARBEIDSGIVER", "FLERE_ARBEIDSGIVERE", and "INGEN_ARBEIDSGIVER". Removed the direct call to `SykemeldingRequestValidator.validate` in `SykemeldingController`, and added a test in `SykemeldingValidateMappingStrategyTest` for validation when no arbeidsgiver data is presented.

* Remove obsolete SykemeldingRequestValidator class #deploy-test-sykemelding-api

The SykemeldingRequestValidator class has been deleted to streamline validation processes. Validation logic has now been moved directly into relevant classes, such as within the Aktivitet constructor, enhancing maintainability and reducing duplication. Tests have been updated to ensure validation errors are correctly handled, confirming that a missing "perioder" now throws a proper exception.

---------

Co-authored-by: Stian Gustavsson <[email protected]>
  • Loading branch information
krharum and stigus authored Dec 10, 2024
1 parent dc688e5 commit fd3cc5b
Show file tree
Hide file tree
Showing 39 changed files with 1,420 additions and 135 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package no.nav.dolly.bestilling.sykemelding;

import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.core.util.Json;
import lombok.extern.slf4j.Slf4j;
import no.nav.dolly.bestilling.ConsumerStatus;
import no.nav.dolly.bestilling.sykemelding.command.SykemeldingPostCommand;
Expand Down Expand Up @@ -41,7 +42,7 @@ public SykemeldingConsumer(
@Timed(name = "providers", tags = { "operation", "detaljertsykemelding_opprett" })
public Mono<SykemeldingResponse> postDetaljertSykemelding(DetaljertSykemeldingRequest detaljertSykemeldingRequest) {

log.info("Detaljert Sykemelding sendt {}", detaljertSykemeldingRequest);
log.info("Detaljert Sykemelding sendt {}", Json.pretty(detaljertSykemeldingRequest));

return tokenService.exchange(serverProperties)
.flatMap(token -> new SykemeldingPostCommand(webClient, detaljertSykemeldingRequest,
Expand Down
1 change: 1 addition & 0 deletions apps/sykemelding-api/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
FROM ghcr.io/navikt/baseimages/temurin:21
LABEL maintainer="Team Dolly"

ENV JAVA_OPTS="--add-opens java.base/java.lang=ALL-UNNAMED"
ADD /build/libs/app.jar /app/app.jar

EXPOSE 8080
3 changes: 2 additions & 1 deletion apps/sykemelding-api/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,15 @@ dependencies {
implementation "org.springframework.boot:spring-boot-starter-security"

implementation "org.springdoc:springdoc-openapi-starter-webmvc-ui:$versions.springdoc"
implementation "io.swagger.core.v3:swagger-annotations-jakarta:$versions.swagger"

implementation "com.ibm.mq:mq-jms-spring-boot-starter:$versions.mq"
implementation "jakarta.xml.bind:jakarta.xml.bind-api:$versions.jakartaXmlBindApi"
implementation "jakarta.activation:jakarta.activation-api:$versions.jakartaActivation"
implementation "org.glassfish.jaxb:jaxb-runtime:$versions.jaxb"
implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-xml"

implementation "ma.glasnost.orika:orika-core:$versions.orika"

testImplementation "no.nav.testnav.libs:testing"
testImplementation "org.springframework.security:spring-security-test"
testImplementation "org.springframework.cloud:spring-cloud-contract-wiremock"
Expand Down
2 changes: 2 additions & 0 deletions apps/sykemelding-api/config.test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ spec:
- application: testnav-oversikt-frontend
- application: testnav-synt-sykemelding-api-dev
outbound:
rules:
- application: testnav-sykemelding-proxy
external:
- host: mqls04.preprod.local
ports:
Expand Down
2 changes: 2 additions & 0 deletions apps/sykemelding-api/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ spec:
- application: testnav-oversikt-frontend
- application: testnav-synt-sykemelding-api
outbound:
rules:
- application: testnav-sykemelding-proxy
external:
- host: mqls04.preprod.local
ports:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package no.nav.registre.testnorge.sykemelding.config;

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

import no.nav.testnav.libs.securitycore.domain.ServerProperties;

import static lombok.AccessLevel.PACKAGE;

@Configuration
@ConfigurationProperties(prefix = "consumers")
@NoArgsConstructor(access = PACKAGE)
@Getter
@Setter(PACKAGE)
public class Consumers {

private ServerProperties sykemeldingProxy;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package no.nav.registre.testnorge.sykemelding.config;

import lombok.RequiredArgsConstructor;
import ma.glasnost.orika.CustomConverter;
import ma.glasnost.orika.MapperFacade;
import ma.glasnost.orika.impl.DefaultMapperFactory;
import no.nav.registre.testnorge.sykemelding.mapper.MappingStrategy;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.List;

import static java.util.Objects.nonNull;

@Configuration
@RequiredArgsConstructor
public class MapperFacadeConfig {

@Bean
MapperFacade mapperFacade(List<MappingStrategy> mappingStrategies, List<CustomConverter> customConverters) {
DefaultMapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();

if (nonNull(mappingStrategies)) {
for (MappingStrategy mapper : mappingStrategies) {
mapper.register(mapperFactory);
}
}

if (nonNull(customConverters)) {
for (CustomConverter converter : customConverters) {
mapperFactory.getConverterFactory().registerConverter(converter);
}
}

return mapperFactory.getMapperFacade();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

@Slf4j
@Component
@Service
public class SyfoConsumer {

private final JmsTemplate jmsTemplate;
private final String queueName;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package no.nav.registre.testnorge.sykemelding.consumer;

import no.nav.registre.testnorge.sykemelding.config.Consumers;
import no.nav.registre.testnorge.sykemelding.consumer.command.SyfosmreglerPostValidateCommand;
import no.nav.registre.testnorge.sykemelding.dto.ReceivedSykemeldingDTO;
import no.nav.testnav.libs.dto.sykemelding.v1.ValidationResultDTO;
import no.nav.testnav.libs.securitycore.domain.ServerProperties;
import no.nav.testnav.libs.servletsecurity.exchange.TokenExchange;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

@Service
public class SyfosmreglerConsumer {

private final ServerProperties properties;
private final TokenExchange tokenExchange;
private final WebClient webClient;

public SyfosmreglerConsumer(Consumers consumers, WebClient.Builder webClientBuilder, TokenExchange tokenExchange) {

this.properties = consumers.getSykemeldingProxy();
this.tokenExchange = tokenExchange;
this.webClient = webClientBuilder
.baseUrl(properties.getUrl())
.build();
}

public Mono<ValidationResultDTO> validate(ReceivedSykemeldingDTO sykemelding) {

return tokenExchange.exchange(properties)
.flatMap(token -> new SyfosmreglerPostValidateCommand(webClient, sykemelding, token.getTokenValue()).call());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package no.nav.registre.testnorge.sykemelding.consumer.command;

import io.swagger.v3.core.util.Json;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import no.nav.registre.testnorge.sykemelding.dto.ReceivedSykemeldingDTO;
import no.nav.testnav.libs.dto.sykemelding.v1.ValidationResultDTO;
import no.nav.testnav.libs.reactivecore.utils.WebClientFilter;
import org.springframework.http.HttpHeaders;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import java.util.concurrent.Callable;

@Slf4j
@RequiredArgsConstructor
public class SyfosmreglerPostValidateCommand implements Callable<Mono<ValidationResultDTO>> {

private static final String SYFOSMREGLER_VALIDATE_URL = "/v1/rules/validate";

private final WebClient webClient;
private final ReceivedSykemeldingDTO receivedSykemelding;
private final String accessToken;

@Override
public Mono<ValidationResultDTO> call() {

log.info("Sender til syfosmregler {}", Json.pretty(receivedSykemelding));

return webClient.post()
.uri(uriBuilder -> uriBuilder.path(SYFOSMREGLER_VALIDATE_URL).build())
.header(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken)
.bodyValue(receivedSykemelding)
.retrieve()
.bodyToMono(ValidationResultDTO.class)
.doOnError(WebClientFilter::logErrorMessage)
.onErrorResume(error -> Mono.just(ValidationResultDTO.builder()
.httpStatus(WebClientFilter.getStatus(error))
.message(WebClientFilter.getMessage(error))
.build()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,26 @@

import no.nav.registre.testnorge.sykemelding.external.xmlstds.helseopplysningerarbeidsuforhet._2013_10_01.XMLHelseOpplysningerArbeidsuforhet;
import no.nav.testnav.libs.dto.sykemelding.v1.PeriodeDTO;
import org.springframework.http.HttpStatus;
import org.springframework.web.server.ResponseStatusException;

import java.time.LocalDate;
import java.util.List;
import java.util.stream.Collectors;

class Aktivitet {
private final XMLHelseOpplysningerArbeidsuforhet.Aktivitet xmlAktivitet;

Aktivitet(List<PeriodeDTO> dtos, boolean manglendeTilretteleggingPaaArbeidsplassen) {

if (dtos.isEmpty()) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Perioder må angis");
}
this.xmlAktivitet = new XMLHelseOpplysningerArbeidsuforhet.Aktivitet()
.withPeriode(
dtos.stream()
.map(value -> new Periode(value, manglendeTilretteleggingPaaArbeidsplassen))
.map(Periode::getXmlObject)
.collect(Collectors.toList())
.toList()
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
import static java.util.Objects.nonNull;

public class Arbeidsgiver {
private XMLHelseOpplysningerArbeidsuforhet.Arbeidsgiver xmlArbeidsgiver;
private final XMLHelseOpplysningerArbeidsuforhet.Arbeidsgiver xmlArbeidsgiver;

Arbeidsgiver(ArbeidsgiverDTO dto) {
xmlArbeidsgiver = new XMLHelseOpplysningerArbeidsuforhet.Arbeidsgiver()
.withHarArbeidsgiver(new XMLCS()
.withDN("En arbeidsgiver")
.withV("1"))
.withDN(nonNull(dto) ? "En arbeidsgiver" : "Ingen arbeidsgiver")
.withV(nonNull(dto) ? "1" : "3"))
.withNavnArbeidsgiver(nonNull(dto) ? dto.getNavn() : null)
.withYrkesbetegnelse(nonNull(dto) ? dto.getYrkesbetegnelse() : null)
.withStillingsprosent(nonNull(dto) ? getStillingsprosent(dto) : null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,12 @@ class Dokument {
.withMedisinskVurdering(medisinskVurdering.getXmlObject())
.withAktivitet(aktivitet.getXmlObject())
.withPrognose(prognose.getXmlObject())
.withUtdypendeOpplysninger(new UtdypendeOpplysninger(dto.getUtdypendeOpplysninger()).getXmlObject())
.withTiltak(
new XMLHelseOpplysningerArbeidsuforhet.Tiltak()
.withTiltakArbeidsplassen(dto.getDetaljer().getTiltakArbeidsplass())
.withTiltakNAV(dto.getDetaljer().getTiltakNav())
.withAndreTiltak(dto.getDetaljer().getAndreTiltak())
)
.withKontaktMedPasient(
new XMLHelseOpplysningerArbeidsuforhet.KontaktMedPasient()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,14 @@

import java.time.LocalDate;
import java.util.List;
import java.util.stream.Collectors;

class MedisinskVurdering {

private final XMLHelseOpplysningerArbeidsuforhet.MedisinskVurdering medisinskVurdering;
private final XMLHelseOpplysningerArbeidsuforhet.MedisinskVurdering xmlMedisinskVurdering;

MedisinskVurdering(LocalDate fom, DiagnoseDTO hovedDiagnose, List<DiagnoseDTO> biDiagnoser) {

medisinskVurdering = new XMLHelseOpplysningerArbeidsuforhet.MedisinskVurdering()
xmlMedisinskVurdering = new XMLHelseOpplysningerArbeidsuforhet.MedisinskVurdering()
.withHovedDiagnose(new XMLHelseOpplysningerArbeidsuforhet.MedisinskVurdering.HovedDiagnose()
.withDiagnosekode(new XMLCV()
.withDN(hovedDiagnose.getDiagnose())
Expand All @@ -29,19 +28,19 @@ class MedisinskVurdering {
.withS(value.getSystem())
.withV(value.getDiagnosekode())
)
.collect(Collectors.toList())
.toList()
)
)
.withYrkesskade(false)
.withYrkesskadeDato(fom)
.withSvangerskap(false)
.withAnnenFraversArsak(
new XMLArsakType().withBeskriv("Medising årsak i kategorien annet")
new XMLArsakType().withBeskriv("Medisinsk årsak i kategorien annet")
)
.withSkjermesForPasient(false);
}

XMLHelseOpplysningerArbeidsuforhet.MedisinskVurdering getXmlObject() {
return medisinskVurdering;
return xmlMedisinskVurdering;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,38 @@
import no.nav.testnav.libs.dto.sykemelding.v1.HelsepersonellDTO;
import no.nav.testnav.libs.dto.sykemelding.v1.PasientDTO;

import static java.util.Objects.nonNull;

public class Pasient {

private final XMLHelseOpplysningerArbeidsuforhet.Pasient xmlPasient;


Pasient(PasientDTO pasientDTO, HelsepersonellDTO helsepersonellDTO) {
var pasient = nonNull(pasientDTO) ? pasientDTO : PasientDTO.builder()
.ident("12508407724")
.fornavn("Test")
.etternavn("Testesen")
.build();
xmlPasient = new XMLHelseOpplysningerArbeidsuforhet.Pasient()
.withNavn(new XMLNavnType()
.withEtternavn(pasientDTO.getEtternavn())
.withMellomnavn(pasientDTO.getMellomnavn())
.withFornavn(pasientDTO.getFornavn())
.withEtternavn(pasient.getEtternavn())
.withMellomnavn(pasient.getMellomnavn())
.withFornavn(pasient.getFornavn())
)
.withFodselsnummer(new XMLIdent()
.withId(pasientDTO.getIdent())
.withId(pasient.getIdent())
.withTypeId(new XMLCV()
.withV("FNR")
.withDN("Fødselsnummer")
.withS("2.16.578.1.12.4.1.1.8116"))
)
.withKontaktInfo(new XMLTeleCom()
.withTypeTelecom(new XMLCS().withV("HP").withDN("Hovedtelefon"))
.withTeleAddress(new XMLURL().withV("tel:" + pasientDTO.getTelefon()))
.withTeleAddress(new XMLURL().withV("tel:" + pasient.getTelefon()))
)
.withNavnFastlege(helsepersonellDTO.getFornavn() + " " + helsepersonellDTO.getEtternavn())
.withNAVKontor(pasientDTO.getNavKontor());
.withNAVKontor(pasient.getNavKontor());
}

XMLHelseOpplysningerArbeidsuforhet.Pasient getXmlObject() {
Expand Down
Loading

0 comments on commit fd3cc5b

Please sign in to comment.