From e2c4990a2bea42cbabf8311eee17ffb3f0229c17 Mon Sep 17 00:00:00 2001 From: Johanne Tronstad <43403066+johatr@users.noreply.github.com> Date: Thu, 31 Oct 2024 14:54:23 +0100 Subject: [PATCH] Bigquery (#317) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Bigquery events for forhåndsvarsler --------- Co-authored-by: sigurdgroneng --- nais/nais-dev-gcp.yaml | 4 + nais/nais-prod-gcp.yaml | 4 + pom.xml | 39 +++++ .../EskaleringsvarselController.java | 4 +- .../EskaleringsvarselService.java | 146 ----------------- .../dto/StartEskaleringDto.java | 3 +- .../veilarbdialog/service/ServiceConfig.java | 11 -- .../eskaleringsvarsel/BegrunnelseTypeEnum.kt | 18 +++ .../EskaleringsvarselService.kt | 149 ++++++++++++++++++ .../eventsLogger/BigQueryClient.kt | 63 ++++++++ .../eventsLogger/BigQueryConfig.kt | 15 ++ src/main/resources/application.yaml | 2 + .../EksternVarslingKvitteringTest.java | 2 +- .../config/ApplicationTestConfig.java | 9 +- .../EskaleringsvarselControllerTest.java | 40 ++--- .../graphql/DialogGraphqlControllerTest.java | 3 +- .../OppfolgingsperiodeConsumerTest.java | 2 +- src/test/resources/application.yaml | 2 + 18 files changed, 326 insertions(+), 190 deletions(-) delete mode 100644 src/main/java/no/nav/fo/veilarbdialog/eskaleringsvarsel/EskaleringsvarselService.java create mode 100644 src/main/kotlin/no/nav/fo/veilarbdialog/eskaleringsvarsel/BegrunnelseTypeEnum.kt create mode 100644 src/main/kotlin/no/nav/fo/veilarbdialog/eskaleringsvarsel/EskaleringsvarselService.kt create mode 100644 src/main/kotlin/no/nav/fo/veilarbdialog/eventsLogger/BigQueryClient.kt create mode 100644 src/main/kotlin/no/nav/fo/veilarbdialog/eventsLogger/BigQueryConfig.kt diff --git a/nais/nais-dev-gcp.yaml b/nais/nais-dev-gcp.yaml index 8b2e95cad..99a8e1a98 100644 --- a/nais/nais-dev-gcp.yaml +++ b/nais/nais-dev-gcp.yaml @@ -115,6 +115,10 @@ spec: envVarPrefix: DB users: - name: datastream + bigQueryDatasets: + - description: Funksjonelle metrikker for arbeidsrettet dialog + name: dialog_metrikker + permission: READWRITE env: - name: APP_CLUSTER_NAME value: dev-gcp diff --git a/nais/nais-prod-gcp.yaml b/nais/nais-prod-gcp.yaml index 37c618ce9..3839972ec 100644 --- a/nais/nais-prod-gcp.yaml +++ b/nais/nais-prod-gcp.yaml @@ -115,6 +115,10 @@ spec: envVarPrefix: DB users: - name: datastream + bigQueryDatasets: + - description: Funksjonelle metrikker for arbeidsrettet dialog + name: dialog_metrikker + permission: READWRITE env: - name: APP_CLUSTER_NAME value: prod-gcp diff --git a/pom.xml b/pom.xml index 79b955f65..cbb7acd2a 100644 --- a/pom.xml +++ b/pom.xml @@ -259,6 +259,11 @@ lombok true + + org.jetbrains.kotlin + kotlin-maven-lombok + ${kotlin.version} + @@ -283,6 +288,18 @@ ${kotlin.version} + + com.google.cloud + google-cloud-bigquery + 2.43.2 + + + com.google.cloud + libraries-bom + 26.49.0 + pom + + @@ -379,6 +396,27 @@ kotlin-maven-plugin org.jetbrains.kotlin ${kotlin.version} + + + lombok + + + + + + + + org.jetbrains.kotlin + kotlin-maven-lombok + ${kotlin.version} + + + org.projectlombok + lombok + 1.18.20 + compile + + true @@ -448,6 +486,7 @@ org.jacoco jacoco-maven-plugin + 0.8.12 org.openapitools diff --git a/src/main/java/no/nav/fo/veilarbdialog/eskaleringsvarsel/EskaleringsvarselController.java b/src/main/java/no/nav/fo/veilarbdialog/eskaleringsvarsel/EskaleringsvarselController.java index ca9105d69..eb61307c2 100644 --- a/src/main/java/no/nav/fo/veilarbdialog/eskaleringsvarsel/EskaleringsvarselController.java +++ b/src/main/java/no/nav/fo/veilarbdialog/eskaleringsvarsel/EskaleringsvarselController.java @@ -38,7 +38,7 @@ public class EskaleringsvarselController { @OnlyInternBruker public EskaleringsvarselDto start(@RequestBody StartEskaleringDto startEskaleringDto) { authService.sjekkTilgangTilPerson(startEskaleringDto.fnr()); - EskaleringsvarselEntity eskaleringsvarselEntity = eskaleringsvarselService.start(startEskaleringDto.fnr(), startEskaleringDto.begrunnelse(), startEskaleringDto.overskrift(), startEskaleringDto.tekst()); + EskaleringsvarselEntity eskaleringsvarselEntity = eskaleringsvarselService.start(startEskaleringDto); return EskaleringsvarselDto.fromEntity(eskaleringsvarselEntity); } @@ -48,7 +48,7 @@ public void stop(@RequestBody StopEskaleringDto stopEskaleringDto) { authService.sjekkTilgangTilPerson(stopEskaleringDto.fnr()); NavIdent navIdent = authService.getInnloggetVeilederIdent(); - Optional eskaleringsvarselEntity = eskaleringsvarselService.stop(stopEskaleringDto.fnr(), stopEskaleringDto.begrunnelse(), stopEskaleringDto.skalSendeHenvendelse(), navIdent); + Optional eskaleringsvarselEntity = eskaleringsvarselService.stop(stopEskaleringDto, navIdent); if (eskaleringsvarselEntity.isEmpty()) { throw new ResponseStatusException(HttpStatus.CONFLICT, "Ingen gjeldende eskaleringsvarsel"); } diff --git a/src/main/java/no/nav/fo/veilarbdialog/eskaleringsvarsel/EskaleringsvarselService.java b/src/main/java/no/nav/fo/veilarbdialog/eskaleringsvarsel/EskaleringsvarselService.java deleted file mode 100644 index faa74727e..000000000 --- a/src/main/java/no/nav/fo/veilarbdialog/eskaleringsvarsel/EskaleringsvarselService.java +++ /dev/null @@ -1,146 +0,0 @@ -package no.nav.fo.veilarbdialog.eskaleringsvarsel; - -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import no.nav.common.client.aktoroppslag.AktorOppslagClient; -import no.nav.common.types.identer.AktorId; -import no.nav.common.types.identer.Fnr; -import no.nav.common.types.identer.NavIdent; -import no.nav.fo.veilarbdialog.brukernotifikasjon.Brukernotifikasjon; -import no.nav.fo.veilarbdialog.brukernotifikasjon.BrukernotifikasjonService; -import no.nav.fo.veilarbdialog.brukernotifikasjon.BrukernotifikasjonTekst; -import no.nav.fo.veilarbdialog.brukernotifikasjon.BrukernotifikasjonsType; -import no.nav.fo.veilarbdialog.brukernotifikasjon.entity.BrukernotifikasjonEntity; -import no.nav.fo.veilarbdialog.domain.*; -import no.nav.fo.veilarbdialog.eskaleringsvarsel.entity.EskaleringsvarselEntity; -import no.nav.fo.veilarbdialog.eskaleringsvarsel.exceptions.AktivEskaleringException; -import no.nav.fo.veilarbdialog.eskaleringsvarsel.exceptions.BrukerIkkeUnderOppfolgingException; -import no.nav.fo.veilarbdialog.eskaleringsvarsel.exceptions.BrukerKanIkkeVarslesException; -import no.nav.fo.veilarbdialog.metrics.FunksjonelleMetrikker; -import no.nav.fo.veilarbdialog.oppfolging.siste_periode.SistePeriodeService; -import no.nav.fo.veilarbdialog.oppfolging.v2.OppfolgingV2Client; -import no.nav.fo.veilarbdialog.service.DialogDataService; -import no.nav.poao.dab.spring_auth.IAuthService; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; -import java.util.Optional; -import java.util.UUID; - -@Slf4j -@RequiredArgsConstructor -@Service -public class EskaleringsvarselService { - - private final BrukernotifikasjonService brukernotifikasjonService; - private final EskaleringsvarselRepository eskaleringsvarselRepository; - private final DialogDataService dialogDataService; - private final IAuthService authService; - private final AktorOppslagClient aktorOppslagClient; - private final OppfolgingV2Client oppfolgingClient; - private final SistePeriodeService sistePeriodeService; - private final FunksjonelleMetrikker funksjonelleMetrikker; - - @Transactional - public EskaleringsvarselEntity start(Fnr fnr, String begrunnelse, String overskrift, String tekst) { - - if (hentGjeldende(fnr).isPresent()) { - throw new AktivEskaleringException("Brukeren har allerede en aktiv eskalering."); - } - - if (!brukernotifikasjonService.kanVarsles(fnr)) { - funksjonelleMetrikker.nyBrukernotifikasjon(false, BrukernotifikasjonsType.OPPGAVE); - throw new BrukerKanIkkeVarslesException(); - } - - if (!oppfolgingClient.erUnderOppfolging(fnr)) { - throw new BrukerIkkeUnderOppfolgingException(); - } - - NyHenvendelseDTO nyHenvendelseDTO = new NyHenvendelseDTO() - .setTekst(tekst) - .setOverskrift(overskrift) - .setEgenskaper(List.of(Egenskap.ESKALERINGSVARSEL)); - - DialogData dialogData = dialogDataService.opprettHenvendelse(nyHenvendelseDTO, Person.fnr(fnr.get())); - - var dialogStatus = DialogStatus.builder() - .dialogId(dialogData.getId()) - .venterPaSvar(true) - .build(); - - dialogData = dialogDataService.oppdaterVentePaSvarTidspunkt(dialogStatus); - dialogDataService.oppdaterFerdigbehandletTidspunkt(dialogData.getId(), true); - dialogDataService.sendPaaKafka(dialogData.getAktorId()); - dialogDataService.markerDialogSomLest(dialogData.getId()); - - UUID brukernotifikasjonId = UUID.randomUUID(); - UUID gjeldendeOppfolgingsperiodeId = sistePeriodeService.hentGjeldendeOppfolgingsperiodeMedFallback(AktorId.of(dialogData.getAktorId())); - - Brukernotifikasjon brukernotifikasjon = new Brukernotifikasjon( - brukernotifikasjonId, - dialogData.getId(), - fnr, - BrukernotifikasjonTekst.OPPGAVE_BRUKERNOTIFIKASJON_TEKST, - gjeldendeOppfolgingsperiodeId, - BrukernotifikasjonsType.OPPGAVE, - dialogDataService.utledDialogLink(dialogData.getId()) - ); - - - BrukernotifikasjonEntity brukernotifikasjonEntity = brukernotifikasjonService.bestillBrukernotifikasjon(brukernotifikasjon, AktorId.of(dialogData.getAktorId())); - - EskaleringsvarselEntity eskaleringsvarselEntity = eskaleringsvarselRepository.opprett( - dialogData.getId(), - brukernotifikasjonEntity.id(), - dialogData.getAktorId(), - authService.getLoggedInnUser().get(), - begrunnelse - ); - - funksjonelleMetrikker.nyBrukernotifikasjon(true, BrukernotifikasjonsType.OPPGAVE); - log.info("Eskaleringsvarsel sendt eventId={}", brukernotifikasjonId); - - return eskaleringsvarselEntity; - } - - @Transactional - public Optional stop(Fnr fnr, String begrunnelse, boolean skalSendeHenvendelse, NavIdent avsluttetAv) { - EskaleringsvarselEntity eskaleringsvarsel = hentGjeldende(fnr).orElse(null); - - if (eskaleringsvarsel == null) { - return Optional.empty(); - } - - if (skalSendeHenvendelse) { - NyHenvendelseDTO nyHenvendelse = new NyHenvendelseDTO() - .setDialogId(Long.toString(eskaleringsvarsel.tilhorendeDialogId())) - .setTekst(begrunnelse); - dialogDataService.opprettHenvendelse(nyHenvendelse, Person.fnr(fnr.get())); - } - eskaleringsvarselRepository.stop(eskaleringsvarsel.varselId(), begrunnelse, avsluttetAv); - - brukernotifikasjonService.bestillDone(eskaleringsvarsel.tilhorendeBrukernotifikasjonId()); - - return eskaleringsvarselRepository.hentVarsel(eskaleringsvarsel.varselId()); - } - - @Transactional - public boolean stop(UUID oppfolgingsperiode) { - return eskaleringsvarselRepository.stopPeriode(oppfolgingsperiode); - } - - public Optional hentGjeldende(Fnr fnr) { - AktorId aktorId = aktorOppslagClient.hentAktorId(fnr); - - return eskaleringsvarselRepository.hentGjeldende(aktorId); - } - - - public List historikk(Fnr fnr) { - AktorId aktorId = aktorOppslagClient.hentAktorId(fnr); - return eskaleringsvarselRepository.hentHistorikk(aktorId); - } - -} diff --git a/src/main/java/no/nav/fo/veilarbdialog/eskaleringsvarsel/dto/StartEskaleringDto.java b/src/main/java/no/nav/fo/veilarbdialog/eskaleringsvarsel/dto/StartEskaleringDto.java index 722fff063..f365a7b3a 100644 --- a/src/main/java/no/nav/fo/veilarbdialog/eskaleringsvarsel/dto/StartEskaleringDto.java +++ b/src/main/java/no/nav/fo/veilarbdialog/eskaleringsvarsel/dto/StartEskaleringDto.java @@ -6,6 +6,7 @@ public record StartEskaleringDto( Fnr fnr, String begrunnelse, String overskrift, - String tekst + String tekst, + String begrunnelseType ) { } diff --git a/src/main/java/no/nav/fo/veilarbdialog/service/ServiceConfig.java b/src/main/java/no/nav/fo/veilarbdialog/service/ServiceConfig.java index cfd3c9798..952a14d74 100644 --- a/src/main/java/no/nav/fo/veilarbdialog/service/ServiceConfig.java +++ b/src/main/java/no/nav/fo/veilarbdialog/service/ServiceConfig.java @@ -1,28 +1,17 @@ package no.nav.fo.veilarbdialog.service; -import lombok.Getter; import no.nav.common.token_client.builder.AzureAdTokenClientBuilder; import no.nav.common.token_client.builder.TokenXTokenClientBuilder; import no.nav.common.token_client.client.AzureAdMachineToMachineTokenClient; import no.nav.common.token_client.client.AzureAdOnBehalfOfTokenClient; import no.nav.common.token_client.client.TokenXOnBehalfOfTokenClient; -import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; -import static lombok.AccessLevel.PACKAGE; - @Configuration -@Getter(PACKAGE) public class ServiceConfig { - @Value("${application.dialog.url}") - private String arbeidsrettetDialogUrl; - - @Value("${spring.application.name}") - private String applicationName; - @Bean @Profile("!local") public AzureAdMachineToMachineTokenClient azureAdMachineToMachineTokenClient() { diff --git a/src/main/kotlin/no/nav/fo/veilarbdialog/eskaleringsvarsel/BegrunnelseTypeEnum.kt b/src/main/kotlin/no/nav/fo/veilarbdialog/eskaleringsvarsel/BegrunnelseTypeEnum.kt new file mode 100644 index 000000000..b67333c1b --- /dev/null +++ b/src/main/kotlin/no/nav/fo/veilarbdialog/eskaleringsvarsel/BegrunnelseTypeEnum.kt @@ -0,0 +1,18 @@ +package no.nav.fo.veilarbdialog.eskaleringsvarsel + +enum class StansVarselBegrunnelseType( + val tekst: String // Ikke bruk denne til noe, den er bare forklaring av enumen +) { + dagpenger("Dagpenger: Stans og tidsbegrenset bortfall"), + dagpenger_vesentlig_avvik_fra_oppleringsplanen("Dagpenger: Vesentlig avvik fra opplæringsplanen."), + dagpenger_fortsatt_utdanning_etter_opphort_utdanning("Dagpenger: Fortsatt utdanning etter opphørt utdanning."), + ikke_mott_mote("Arbeidsavklaringspenger: Ikke møtt til møte"), + ikke_deltatt_aktivitet("Arbeidsavklaringspenger: Ikke deltatt på planlagt aktivitet eller bidrar ikke for å komme i arbeid"), + ikke_deltatt_tiltak("Arbeidsavklaringspenger: Ikke deltatt på tiltak"), + ikke_lenger_nedsatt_arbeidsevne("Arbeidsavklaringspenger: Ikke lenger nedsatt arbeidsevne"), + uutnyttet_arbeidsevne("Arbeidsavklaringspenger: Reduksjon i utbetaling på grunn av arbeidsevne som ikke er utnyttet"), + stans_aap_i_periode("Arbeidsavklaringspenger: Stans av AAP i perioden som arbeidssøker"), + overgangsstonad("Overgangsstønad"), + sykepenger("Sykepenger") +} + diff --git a/src/main/kotlin/no/nav/fo/veilarbdialog/eskaleringsvarsel/EskaleringsvarselService.kt b/src/main/kotlin/no/nav/fo/veilarbdialog/eskaleringsvarsel/EskaleringsvarselService.kt new file mode 100644 index 000000000..7b4cc41ac --- /dev/null +++ b/src/main/kotlin/no/nav/fo/veilarbdialog/eskaleringsvarsel/EskaleringsvarselService.kt @@ -0,0 +1,149 @@ +package no.nav.fo.veilarbdialog.eskaleringsvarsel + +import lombok.RequiredArgsConstructor +import lombok.extern.slf4j.Slf4j +import no.nav.common.client.aktoroppslag.AktorOppslagClient +import no.nav.common.types.identer.AktorId +import no.nav.common.types.identer.Fnr +import no.nav.common.types.identer.NavIdent +import no.nav.fo.veilarbdialog.brukernotifikasjon.Brukernotifikasjon +import no.nav.fo.veilarbdialog.brukernotifikasjon.BrukernotifikasjonService +import no.nav.fo.veilarbdialog.brukernotifikasjon.BrukernotifikasjonTekst +import no.nav.fo.veilarbdialog.brukernotifikasjon.BrukernotifikasjonsType +import no.nav.fo.veilarbdialog.domain.* +import no.nav.fo.veilarbdialog.eskaleringsvarsel.dto.StartEskaleringDto +import no.nav.fo.veilarbdialog.eskaleringsvarsel.dto.StopEskaleringDto +import no.nav.fo.veilarbdialog.eskaleringsvarsel.entity.EskaleringsvarselEntity +import no.nav.fo.veilarbdialog.eskaleringsvarsel.exceptions.AktivEskaleringException +import no.nav.fo.veilarbdialog.eskaleringsvarsel.exceptions.BrukerIkkeUnderOppfolgingException +import no.nav.fo.veilarbdialog.eskaleringsvarsel.exceptions.BrukerKanIkkeVarslesException +import no.nav.fo.veilarbdialog.eventsLogger.BigQueryClient +import no.nav.fo.veilarbdialog.eventsLogger.EventType +import no.nav.fo.veilarbdialog.metrics.FunksjonelleMetrikker +import no.nav.fo.veilarbdialog.oppfolging.siste_periode.SistePeriodeService +import no.nav.fo.veilarbdialog.oppfolging.v2.OppfolgingV2Client +import no.nav.fo.veilarbdialog.service.DialogDataService +import no.nav.poao.dab.spring_auth.IAuthService +import org.slf4j.LoggerFactory +import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional +import java.util.* + +@Slf4j +@RequiredArgsConstructor +@Service +open class EskaleringsvarselService( + private val brukernotifikasjonService: BrukernotifikasjonService, + private val eskaleringsvarselRepository: EskaleringsvarselRepository, + private val dialogDataService: DialogDataService, + private val authService: IAuthService, + private val aktorOppslagClient: AktorOppslagClient, + private val oppfolgingClient: OppfolgingV2Client, + private val sistePeriodeService: SistePeriodeService, + private val funksjonelleMetrikker: FunksjonelleMetrikker, + private val bigQueryClient: BigQueryClient, +) { + + private val log = LoggerFactory.getLogger(EskaleringsvarselService::class.java) + + @Transactional + open fun start(stansVarsel: StartEskaleringDto): EskaleringsvarselEntity { + if (hentGjeldende(stansVarsel.fnr).isPresent) { + throw AktivEskaleringException("Brukeren har allerede en aktiv eskalering.") + } + + if (!brukernotifikasjonService.kanVarsles(stansVarsel.fnr)) { + funksjonelleMetrikker.nyBrukernotifikasjon(false, BrukernotifikasjonsType.OPPGAVE) + throw BrukerKanIkkeVarslesException() + } + + if (!oppfolgingClient.erUnderOppfolging(stansVarsel.fnr)) { + throw BrukerIkkeUnderOppfolgingException() + } + + val nyHenvendelseDTO = NyHenvendelseDTO() + .setTekst(stansVarsel.tekst) + .setOverskrift(stansVarsel.overskrift) + .setEgenskaper(java.util.List.of(Egenskap.ESKALERINGSVARSEL)) + + var dialogData = dialogDataService.opprettHenvendelse(nyHenvendelseDTO, Person.fnr(stansVarsel.fnr.get())) + + val dialogStatus = DialogStatus.builder() + .dialogId(dialogData.id) + .venterPaSvar(true) + .build() + + dialogData = dialogDataService.oppdaterVentePaSvarTidspunkt(dialogStatus) + dialogDataService.oppdaterFerdigbehandletTidspunkt(dialogData.id, true) + dialogDataService.sendPaaKafka(dialogData.aktorId) + dialogDataService.markerDialogSomLest(dialogData.id) + + val brukernotifikasjonId = UUID.randomUUID() + val gjeldendeOppfolgingsperiodeId = + sistePeriodeService.hentGjeldendeOppfolgingsperiodeMedFallback(AktorId.of(dialogData.aktorId)) + + val brukernotifikasjon = Brukernotifikasjon( + brukernotifikasjonId, + dialogData.id, + stansVarsel.fnr, + BrukernotifikasjonTekst.OPPGAVE_BRUKERNOTIFIKASJON_TEKST, + gjeldendeOppfolgingsperiodeId, + BrukernotifikasjonsType.OPPGAVE, + dialogDataService.utledDialogLink(dialogData.id) + ) + + val brukernotifikasjonEntity = + brukernotifikasjonService.bestillBrukernotifikasjon(brukernotifikasjon, AktorId.of(dialogData.aktorId)) + + val eskaleringsvarselEntity = eskaleringsvarselRepository.opprett( + dialogData.id, + brukernotifikasjonEntity.id, + dialogData.aktorId, + authService.getLoggedInnUser().get(), + stansVarsel.begrunnelse + ) + + funksjonelleMetrikker.nyBrukernotifikasjon(true, BrukernotifikasjonsType.OPPGAVE) + log.info("Eskaleringsvarsel sendt eventId={}", brukernotifikasjonId) + + bigQueryClient.logEvent(eskaleringsvarselEntity, EventType.FORHAANDSVARSEL_OPPRETTET, stansVarsel.begrunnelseType) + return eskaleringsvarselEntity + } + + @Transactional + open fun stop(stopVarselDto: StopEskaleringDto, avsluttetAv: NavIdent): Optional { + val eskaleringsvarsel = hentGjeldende(stopVarselDto.fnr).orElse(null) + ?: return Optional.empty() // Exit early with no errormessage?! + + if (stopVarselDto.skalSendeHenvendelse) { + val nyHenvendelse = NyHenvendelseDTO() + .setDialogId(eskaleringsvarsel.tilhorendeDialogId.toString()) + .setTekst(stopVarselDto.begrunnelse) + dialogDataService.opprettHenvendelse(nyHenvendelse, Person.fnr(stopVarselDto.fnr.get())) + } + + eskaleringsvarselRepository.stop(eskaleringsvarsel.varselId, stopVarselDto.begrunnelse, avsluttetAv) + brukernotifikasjonService.bestillDone(eskaleringsvarsel.tilhorendeBrukernotifikasjonId) + + val eskaleringsvarselEntity = eskaleringsvarselRepository.hentVarsel(eskaleringsvarsel.varselId) + eskaleringsvarselEntity.ifPresent { varsel -> + bigQueryClient.logEvent(varsel, EventType.FORHAANDSVARSEL_INAKTIVERT) + } + return eskaleringsvarselEntity + } + + @Transactional + open fun stop(oppfolgingsperiode: UUID?): Boolean { + return eskaleringsvarselRepository.stopPeriode(oppfolgingsperiode) + } + + open fun hentGjeldende(fnr: Fnr?): Optional { + val aktorId = aktorOppslagClient.hentAktorId(fnr) + return eskaleringsvarselRepository.hentGjeldende(aktorId) + } + + open fun historikk(fnr: Fnr?): List { + val aktorId = aktorOppslagClient.hentAktorId(fnr) + return eskaleringsvarselRepository.hentHistorikk(aktorId) + } +} diff --git a/src/main/kotlin/no/nav/fo/veilarbdialog/eventsLogger/BigQueryClient.kt b/src/main/kotlin/no/nav/fo/veilarbdialog/eventsLogger/BigQueryClient.kt new file mode 100644 index 000000000..56baf2674 --- /dev/null +++ b/src/main/kotlin/no/nav/fo/veilarbdialog/eventsLogger/BigQueryClient.kt @@ -0,0 +1,63 @@ +package no.nav.fo.veilarbdialog.eventsLogger + +import com.google.cloud.bigquery.BigQueryOptions +import com.google.cloud.bigquery.InsertAllRequest +import com.google.cloud.bigquery.TableId +import no.nav.fo.veilarbdialog.eskaleringsvarsel.entity.EskaleringsvarselEntity +import org.slf4j.LoggerFactory +import java.time.ZonedDateTime + +enum class EventType { + FORHAANDSVARSEL_OPPRETTET, + FORHAANDSVARSEL_INAKTIVERT +} + +interface BigQueryClient { + fun logEvent(eskaleringsvarselEntity: EskaleringsvarselEntity, eventType: EventType, begrunnelseType: String? = null) +} + +class BigQueryClientImplementation(projectId: String): BigQueryClient { + val FORHAANSVARSEL_EVENTS = "FORHAANDSVARSEL_EVENTS" + val DATASET_NAME = "dialog_metrikker" + val forhaandsvarselEventsTable = TableId.of(DATASET_NAME, FORHAANSVARSEL_EVENTS) + + private fun TableId.insertRequest(row: Map): InsertAllRequest { + return InsertAllRequest.newBuilder(this).addRow(row).build() + } + + val bigQuery = BigQueryOptions.newBuilder().setProjectId(projectId).build().service + val log = LoggerFactory.getLogger(this.javaClass) + + override fun logEvent( + eskaleringsvarselEntity: EskaleringsvarselEntity, + eventType: EventType, + begrunnelseType: String? + ) { + runCatching { + val forhaandsvarselRow = mapOf( + "id" to eskaleringsvarselEntity.varselId, + "opprettet" to eskaleringsvarselEntity.opprettetDato.toOffsetDateTime().toString(), + "timestamp" to ZonedDateTime.now().toOffsetDateTime().toString(), + "event" to eventType.name, + ) + (begrunnelseType?.let { mapOf("begrunnelseType" to it) } ?: emptyMap()) + val insertRequest = forhaandsvarselEventsTable.insertRequest(forhaandsvarselRow) + insertWhileToleratingErrors(insertRequest) + } + .onFailure { + log.warn("Kunne ikke lage event i bigquery", it) + } + + } + + private fun insertWhileToleratingErrors(insertRequest: InsertAllRequest) { + runCatching { + val response = bigQuery.insertAll(insertRequest) + val errors = response.insertErrors + if (errors.isNotEmpty()) { + log.error("Error inserting bigquery rows", errors) + } + }.onFailure { + log.error("BigQuery error", it) + } + } +} diff --git a/src/main/kotlin/no/nav/fo/veilarbdialog/eventsLogger/BigQueryConfig.kt b/src/main/kotlin/no/nav/fo/veilarbdialog/eventsLogger/BigQueryConfig.kt new file mode 100644 index 000000000..cec32936f --- /dev/null +++ b/src/main/kotlin/no/nav/fo/veilarbdialog/eventsLogger/BigQueryConfig.kt @@ -0,0 +1,15 @@ +package no.nav.fo.veilarbdialog.eventsLogger + +import org.springframework.beans.factory.annotation.Value +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.context.annotation.Profile + +@Configuration +open class BigQueryConfig(@Value("\${application.gcp.projectId}") val projectId: String) { + + @Bean + open fun bigQueryClient(): BigQueryClient { + return BigQueryClientImplementation(projectId) + } +} diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index f4de095ed..6e7793c9d 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -162,6 +162,8 @@ application: henvendelse: maksalder: ms: 172800000 + gcp: + projectId: ${GCP_TEAM_PROJECT_ID} unleash: appName: ${NAIS_APP_NAME} diff --git a/src/test/java/no/nav/fo/veilarbdialog/brukernotifikasjon/kvittering/EksternVarslingKvitteringTest.java b/src/test/java/no/nav/fo/veilarbdialog/brukernotifikasjon/kvittering/EksternVarslingKvitteringTest.java index 37579781b..e5e3a5757 100644 --- a/src/test/java/no/nav/fo/veilarbdialog/brukernotifikasjon/kvittering/EksternVarslingKvitteringTest.java +++ b/src/test/java/no/nav/fo/veilarbdialog/brukernotifikasjon/kvittering/EksternVarslingKvitteringTest.java @@ -74,7 +74,7 @@ void skal_oppdatere_brukernotifikasjon() { MockVeileder veileder = MockNavService.createVeileder(bruker); StartEskaleringDto startEskaleringDto = - new StartEskaleringDto(Fnr.of(bruker.getFnr()), "begrunnelse", "overskrift", "henvendelseTekst"); + new StartEskaleringDto(Fnr.of(bruker.getFnr()), "begrunnelse", "overskrift", "henvendelseTekst", null); EskaleringsvarselDto startEskalering = dialogTestService.startEskalering(veileder, startEskaleringDto); BrukernotifikasjonEntity opprinneligBrukernotifikasjon = brukernotifikasjonRepository.hentBrukernotifikasjonForDialogId(startEskalering.tilhorendeDialogId(), BrukernotifikasjonsType.OPPGAVE).get(0); diff --git a/src/test/java/no/nav/fo/veilarbdialog/config/ApplicationTestConfig.java b/src/test/java/no/nav/fo/veilarbdialog/config/ApplicationTestConfig.java index 9e1e18fa2..b949fb8bc 100644 --- a/src/test/java/no/nav/fo/veilarbdialog/config/ApplicationTestConfig.java +++ b/src/test/java/no/nav/fo/veilarbdialog/config/ApplicationTestConfig.java @@ -1,13 +1,11 @@ package no.nav.fo.veilarbdialog.config; +import no.nav.fo.veilarbdialog.eventsLogger.BigQueryClient; import io.getunleash.Unleash; -import io.zonky.test.db.postgres.embedded.EmbeddedPostgres; import no.nav.common.token_client.client.AzureAdMachineToMachineTokenClient; import no.nav.common.token_client.client.AzureAdOnBehalfOfTokenClient; import no.nav.common.token_client.client.TokenXOnBehalfOfTokenClient; -import no.nav.fo.veilarbdialog.db.DataSourceConfig; import no.nav.fo.veilarbdialog.db.dao.LocalDatabaseSingleton; -import org.mockito.Mockito; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; @@ -66,4 +64,9 @@ Unleash unleash() { return mock(Unleash.class); } + @Bean + BigQueryClient bigQueryClient() { + return mock(BigQueryClient.class); + } + } diff --git a/src/test/java/no/nav/fo/veilarbdialog/eskaleringsvarsel/EskaleringsvarselControllerTest.java b/src/test/java/no/nav/fo/veilarbdialog/eskaleringsvarsel/EskaleringsvarselControllerTest.java index 321d8f678..0b23f9d17 100644 --- a/src/test/java/no/nav/fo/veilarbdialog/eskaleringsvarsel/EskaleringsvarselControllerTest.java +++ b/src/test/java/no/nav/fo/veilarbdialog/eskaleringsvarsel/EskaleringsvarselControllerTest.java @@ -97,6 +97,10 @@ void setupL() { } + private StartEskaleringDto lagEskaleringsVarsel(MockBruker bruker) { + return new StartEskaleringDto(Fnr.of(bruker.getFnr()), "begrunnelse", "overskrift", "henvendelseTekst", null); + } + @Test void start_eskalering_happy_case() { @@ -114,7 +118,7 @@ void start_eskalering_happy_case() { String eventLink; StartEskaleringDto startEskaleringDto = - new StartEskaleringDto(Fnr.of(bruker.getFnr()), begrunnelse, overskrift, henvendelseTekst); + new StartEskaleringDto(Fnr.of(bruker.getFnr()), begrunnelse, overskrift, henvendelseTekst, null); EskaleringsvarselDto startEskalering = dialogTestService.startEskalering(veileder, startEskaleringDto); @@ -171,7 +175,7 @@ void stop_eskalering_med_henvendelse() { String avsluttBegrunnelse = "Du har gjort aktiviteten vi ba om."; Fnr brukerFnr = Fnr.of(bruker.getFnr()); - StartEskaleringDto startEskaleringDto = new StartEskaleringDto(brukerFnr, "begrunnelse", "overskrift", "tekst"); + StartEskaleringDto startEskaleringDto = lagEskaleringsVarsel(bruker); EskaleringsvarselDto eskaleringsvarsel = dialogTestService.startEskalering(veileder, startEskaleringDto); StopEskaleringDto stopEskaleringDto = new StopEskaleringDto(brukerFnr, avsluttBegrunnelse, true); @@ -219,7 +223,7 @@ void stop_eskalering_uten_henvendelse() { String avsluttBegrunnelse = "Fordi ..."; Fnr brukerFnr = Fnr.of(bruker.getFnr()); - StartEskaleringDto startEskaleringDto = new StartEskaleringDto(brukerFnr, "begrunnelse", "overskrift", "tekst"); + StartEskaleringDto startEskaleringDto = lagEskaleringsVarsel(bruker); EskaleringsvarselDto eskaleringsvarsel = dialogTestService.startEskalering(veileder, startEskaleringDto); StopEskaleringDto stopEskaleringDto = new StopEskaleringDto(brukerFnr, avsluttBegrunnelse, false); @@ -263,8 +267,7 @@ void bruker_kan_ikke_varsles() { MockVeileder veileder = MockNavService.createVeileder(bruker); - StartEskaleringDto startEskaleringDto = - new StartEskaleringDto(Fnr.of(bruker.getFnr()), "begrunnelse", "overskrift", "henvendelseTekst"); + StartEskaleringDto startEskaleringDto = lagEskaleringsVarsel(bruker); Response response = tryStartEskalering(veileder, startEskaleringDto); assertThat(response.statusCode()).isEqualTo(HttpStatus.CONFLICT.value()); @@ -280,8 +283,7 @@ void bruker_ikke_under_oppfolging() { MockVeileder veileder = MockNavService.createVeileder(bruker); - StartEskaleringDto startEskaleringDto = - new StartEskaleringDto(Fnr.of(bruker.getFnr()), "begrunnelse", "overskrift", "henvendelseTekst"); + StartEskaleringDto startEskaleringDto = lagEskaleringsVarsel(bruker); Response response = tryStartEskalering(veileder, startEskaleringDto); assertThat(response.statusCode()).isEqualTo(HttpStatus.CONFLICT.value()); @@ -293,8 +295,7 @@ void bruker_ikke_under_oppfolging() { void bruker_har_allerede_aktiv_eskalering() { MockBruker bruker = MockNavService.createHappyBruker(); MockVeileder veileder = MockNavService.createVeileder(bruker); - StartEskaleringDto startEskaleringDto = - new StartEskaleringDto(Fnr.of(bruker.getFnr()), "begrunnelse", "overskrift", "henvendelseTekst"); + StartEskaleringDto startEskaleringDto = lagEskaleringsVarsel(bruker); dialogTestService.startEskalering(veileder, startEskaleringDto); Response response = tryStartEskalering(veileder, startEskaleringDto); assertThat(response.statusCode()).isEqualTo(HttpStatus.CONFLICT.value()); @@ -304,8 +305,7 @@ void bruker_har_allerede_aktiv_eskalering() { void test_historikk() { MockBruker bruker = MockNavService.createHappyBruker(); MockVeileder veileder = MockNavService.createVeileder(bruker); - StartEskaleringDto startEskaleringDto = - new StartEskaleringDto(Fnr.of(bruker.getFnr()), "begrunnelse", "overskrift", "henvendelseTekst"); + StartEskaleringDto startEskaleringDto = lagEskaleringsVarsel(bruker); dialogTestService.startEskalering(veileder, startEskaleringDto); StopEskaleringDto stopEskaleringDto = new StopEskaleringDto(Fnr.of(bruker.getFnr()), "avsluttbegrunnelse", false); @@ -344,8 +344,7 @@ void skal_kun_prosessere_en_ved_samtidige_kall() throws Exception { MockBruker bruker = MockNavService.createHappyBruker(); MockVeileder veileder = MockNavService.createVeileder(bruker); - StartEskaleringDto startEskaleringDto = - new StartEskaleringDto(Fnr.of(bruker.getFnr()), "begrunnelse", "Dialog overskrift", "henvendelseTekst"); + StartEskaleringDto startEskaleringDto = lagEskaleringsVarsel(bruker); for (int i = 0; i < antallKall; i++) { bakgrunnService.submit(() -> { @@ -371,7 +370,7 @@ void hentGjeldendeSomEksternbruker() { MockBruker bruker = MockNavService.createHappyBruker(); MockVeileder veileder = MockNavService.createVeileder(bruker); StartEskaleringDto startEskaleringDto = - new StartEskaleringDto(Fnr.of(bruker.getFnr()), "begrunnelse", "overskrift", "henvendelseTekst"); + new StartEskaleringDto(Fnr.of(bruker.getFnr()), "begrunnelse", "overskrift", "henvendelseTekst", null); dialogTestService.startEskalering(veileder, startEskaleringDto); bruker.createRequest() @@ -387,8 +386,7 @@ void hentGjeldendeSomEksternbruker() { void hentGjeldendeSomVeilederUtenFnrParam() { MockBruker bruker = MockNavService.createHappyBruker(); MockVeileder veileder = MockNavService.createVeileder(bruker); - StartEskaleringDto startEskaleringDto = - new StartEskaleringDto(Fnr.of(bruker.getFnr()), "begrunnelse", "overskrift", "henvendelseTekst"); + StartEskaleringDto startEskaleringDto = lagEskaleringsVarsel(bruker); dialogTestService.startEskalering(veileder, startEskaleringDto); veileder.createRequest() @@ -400,15 +398,10 @@ void hentGjeldendeSomVeilederUtenFnrParam() { @Test void send_done_naar_eskalering_lest_av_bruker() { - MockBruker bruker = MockNavService.createHappyBruker(); MockVeileder veileder = MockNavService.createVeileder(bruker); - String begrunnelse = "Fordi ..."; - String overskrift = "Dialog tittel"; - String henvendelseTekst = "Henvendelsestekst... lang tekst"; - StartEskaleringDto startEskaleringDto = - new StartEskaleringDto(Fnr.of(bruker.getFnr()), begrunnelse, overskrift, henvendelseTekst); + StartEskaleringDto startEskaleringDto = lagEskaleringsVarsel(bruker); EskaleringsvarselDto startEskalering = dialogTestService.startEskalering(veileder, startEskaleringDto); lesHenvendelse(bruker, startEskalering.tilhorendeDialogId()); @@ -425,8 +418,7 @@ void send_done_naar_eskalering_lest_av_bruker() { void unngaaDobleNotifikasjonerPaaEskaleringsvarsel() throws InterruptedException { MockBruker bruker = MockNavService.createHappyBruker(); MockVeileder veileder = MockNavService.createVeileder(bruker); - StartEskaleringDto startEskaleringDto = - new StartEskaleringDto(Fnr.of(bruker.getFnr()), "begrunnelse", "overskrift", "henvendelseTekst"); + StartEskaleringDto startEskaleringDto = lagEskaleringsVarsel(bruker); var initialEndOffsets = KafkaTestUtils.getEndOffsets(brukerNotifikasjonBeskjedConsumer, brukernotifikasjonBeskjedTopic); dialogTestService.startEskalering(veileder, startEskaleringDto); diff --git a/src/test/java/no/nav/fo/veilarbdialog/graphql/DialogGraphqlControllerTest.java b/src/test/java/no/nav/fo/veilarbdialog/graphql/DialogGraphqlControllerTest.java index b30bc02b1..7782c1392 100644 --- a/src/test/java/no/nav/fo/veilarbdialog/graphql/DialogGraphqlControllerTest.java +++ b/src/test/java/no/nav/fo/veilarbdialog/graphql/DialogGraphqlControllerTest.java @@ -64,7 +64,8 @@ private void startVarsel(MockVeileder veileder, MockBruker bruker) { Fnr.of(bruker.getFnr()), "Fordi", "VARSEL", - "tekst" + "tekst", + null )); } diff --git a/src/test/java/no/nav/fo/veilarbdialog/oppfolging/siste_periode/OppfolgingsperiodeConsumerTest.java b/src/test/java/no/nav/fo/veilarbdialog/oppfolging/siste_periode/OppfolgingsperiodeConsumerTest.java index e53408b91..937ba7749 100644 --- a/src/test/java/no/nav/fo/veilarbdialog/oppfolging/siste_periode/OppfolgingsperiodeConsumerTest.java +++ b/src/test/java/no/nav/fo/veilarbdialog/oppfolging/siste_periode/OppfolgingsperiodeConsumerTest.java @@ -121,7 +121,7 @@ void skal_avslutte_gjeldende_varsler_og_notifikasjoner() { opprettEllerEndreOppfolgingsperiodeForBruker(startOppfolging); StartEskaleringDto startEskaleringDto = - new StartEskaleringDto(Fnr.of(mockBruker.getFnr()), "begrunnelse", "overskrift", "henvendelseTekst"); + new StartEskaleringDto(Fnr.of(mockBruker.getFnr()), "begrunnelse", "overskrift", "henvendelseTekst", null); EskaleringsvarselDto startEskalering = dialogTestService.startEskalering(mockVeileder, startEskaleringDto); OppfolgingsperiodeV1 stopOppfolging = OppfolgingsperiodeV1.builder() diff --git a/src/test/resources/application.yaml b/src/test/resources/application.yaml index 6bb9136f1..f9439156a 100644 --- a/src/test/resources/application.yaml +++ b/src/test/resources/application.yaml @@ -132,6 +132,8 @@ application: henvendelse: maksalder: ms: 2000 + gcp: + projectId: test wiremock: server: port: 0