diff --git a/domenetjenester/iay/src/main/java/no/nav/foreldrepenger/abakus/domene/iay/InntektArbeidYtelseRepository.java b/domenetjenester/iay/src/main/java/no/nav/foreldrepenger/abakus/domene/iay/InntektArbeidYtelseRepository.java index 260f87331..fc936c7c6 100644 --- a/domenetjenester/iay/src/main/java/no/nav/foreldrepenger/abakus/domene/iay/InntektArbeidYtelseRepository.java +++ b/domenetjenester/iay/src/main/java/no/nav/foreldrepenger/abakus/domene/iay/InntektArbeidYtelseRepository.java @@ -70,7 +70,7 @@ public InntektArbeidYtelseGrunnlag hentInntektArbeidYtelseForBehandling(KoblingR public Optional hentIAYAggregatFor(KoblingReferanse koblingReferanse, UUID eksternReferanse) { TypedQuery query = entityManager.createQuery( - "SELECT iay " + " FROM InntektArbeidYtelser iay " + " WHERE iay.eksternReferanse = :eksternReferanse", InntektArbeidYtelseAggregat.class); + "SELECT iay FROM InntektArbeidYtelser iay WHERE iay.eksternReferanse = :eksternReferanse", InntektArbeidYtelseAggregat.class); query.setParameter("eksternReferanse", eksternReferanse); var res = HibernateVerktøy.hentUniktResultat(query); diff --git a/domenetjenester/iay/src/main/java/no/nav/foreldrepenger/abakus/domene/iay/arbeidsforhold/ForvaltningReferanseTjeneste.java b/domenetjenester/iay/src/main/java/no/nav/foreldrepenger/abakus/domene/iay/arbeidsforhold/ForvaltningReferanseTjeneste.java deleted file mode 100644 index c119c86c0..000000000 --- a/domenetjenester/iay/src/main/java/no/nav/foreldrepenger/abakus/domene/iay/arbeidsforhold/ForvaltningReferanseTjeneste.java +++ /dev/null @@ -1,9 +0,0 @@ -package no.nav.foreldrepenger.abakus.domene.iay.arbeidsforhold; - -public class ForvaltningReferanseTjeneste { - - public static void leggTilReferanse(ArbeidsforholdInformasjon informasjon, ArbeidsforholdReferanse arbeidsforholdReferanse) { - informasjon.leggTilNyReferanse(arbeidsforholdReferanse); - } - -} diff --git a/web/src/main/java/no/nav/foreldrepenger/abakus/app/vedlikehold/ForvaltningRestTjeneste.java b/web/src/main/java/no/nav/foreldrepenger/abakus/app/vedlikehold/ForvaltningRestTjeneste.java index 2cf1dd429..d0c2d64c6 100644 --- a/web/src/main/java/no/nav/foreldrepenger/abakus/app/vedlikehold/ForvaltningRestTjeneste.java +++ b/web/src/main/java/no/nav/foreldrepenger/abakus/app/vedlikehold/ForvaltningRestTjeneste.java @@ -5,6 +5,8 @@ import java.util.List; import java.util.function.Function; +import no.nav.foreldrepenger.abakus.rydding.OppryddingTjeneste; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -46,6 +48,7 @@ public class ForvaltningRestTjeneste { private static final String GJELDENDE = "gjeldende"; private InntektArbeidYtelseTjeneste iayTjeneste; + private OppryddingTjeneste oppryddingTjeneste; private EntityManager entityManager; @@ -55,9 +58,11 @@ public ForvaltningRestTjeneste() { @Inject public ForvaltningRestTjeneste(EntityManager entityManager, - InntektArbeidYtelseTjeneste iayTjeneste) { + InntektArbeidYtelseTjeneste iayTjeneste, + OppryddingTjeneste oppryddingTjeneste) { this.entityManager = entityManager; this.iayTjeneste = iayTjeneste; + this.oppryddingTjeneste = oppryddingTjeneste; } @POST @@ -129,6 +134,18 @@ public Response oppdaterAktoerId(@TilpassetAbacAttributt(supplierClass = Forvalt return Response.ok(antall).build(); } + @POST + @Path("/ryddOppGrunnlagUtenReferanse") + @Consumes(APPLICATION_JSON) + @Produces(APPLICATION_JSON) + @Operation(description = "Trigger ryddejobben som fjerner alle inaktive grunnlag uten referanse", tags = "FORVALTNING", responses = {@ApiResponse(responseCode = "200", description = "Taskene blir opprettet og grunnlag blir slettet asynkront.")}) + @BeskyttetRessurs(actionType = ActionType.CREATE, resourceType = ResourceType.DRIFT, sporingslogg = true) + public Response ryddOppGrunnlagUtenReferanse() { + LOG.info("FORVALTNING ABAKUS ryddOppGrunnlagUtenReferanse"); + oppryddingTjeneste.fjernAlleIayAggregatUtenReferanse(); + return Response.ok().build(); + } + private int oppdaterAktørIdFor(String gammel, String gjeldende) { int antall = 0; antall += entityManager.createNativeQuery("UPDATE kobling SET bruker_aktoer_id = :gjeldende WHERE bruker_aktoer_id = :gammel") diff --git a/web/src/main/java/no/nav/foreldrepenger/abakus/kobling/AvsluttKoblingTjeneste.java b/web/src/main/java/no/nav/foreldrepenger/abakus/kobling/AvsluttKoblingTjeneste.java index c3d09fca4..c44df5c3c 100644 --- a/web/src/main/java/no/nav/foreldrepenger/abakus/kobling/AvsluttKoblingTjeneste.java +++ b/web/src/main/java/no/nav/foreldrepenger/abakus/kobling/AvsluttKoblingTjeneste.java @@ -7,15 +7,12 @@ import jakarta.inject.Inject; import no.nav.abakus.iaygrunnlag.kodeverk.YtelseType; import no.nav.foreldrepenger.abakus.iay.InntektArbeidYtelseTjeneste; -import no.nav.foreldrepenger.konfig.Environment; @ApplicationScoped public class AvsluttKoblingTjeneste { private static final Logger LOG = LoggerFactory.getLogger(AvsluttKoblingTjeneste.class); - private static final Environment ENV = Environment.current(); - private KoblingTjeneste koblingTjeneste; private InntektArbeidYtelseTjeneste iayTjeneste; diff --git a/web/src/main/java/no/nav/foreldrepenger/abakus/rydding/OppryddingIAYAggregatRepository.java b/web/src/main/java/no/nav/foreldrepenger/abakus/rydding/OppryddingIAYAggregatRepository.java new file mode 100644 index 000000000..dbd5afd4d --- /dev/null +++ b/web/src/main/java/no/nav/foreldrepenger/abakus/rydding/OppryddingIAYAggregatRepository.java @@ -0,0 +1,260 @@ +package no.nav.foreldrepenger.abakus.rydding; + +import static java.util.Collections.emptyList; + +import java.util.List; +import java.util.Objects; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import jakarta.persistence.EntityManager; +import no.nav.foreldrepenger.abakus.domene.iay.InntektArbeidYtelseAggregat; + +@ApplicationScoped +public class OppryddingIAYAggregatRepository { + private static final Logger LOG = LoggerFactory.getLogger(OppryddingIAYAggregatRepository.class); + protected static final String PARAM_IAY_ID = "iayId"; + protected static final String PARAM_RELATERT_YTELSE_ID_LIST = "relatertYtelseIdList"; + + private EntityManager entityManager; + + OppryddingIAYAggregatRepository() { + // CDI proxy + } + + @Inject + public OppryddingIAYAggregatRepository(EntityManager entityManager) { + Objects.requireNonNull(entityManager, "entityManager"); + this.entityManager = entityManager; + } + + public List hentIayAggregaterUtenReferanse(Integer maxResults) { + @SuppressWarnings("unchecked") List result = entityManager.createNativeQuery( + "select distinct id from iay_inntekt_arbeid_ytelser iay where " + + "not exists (select 1 from gr_arbeid_inntekt gr where iay.id = gr.register_id or iay.id = gr.saksbehandlet_id)") + .setMaxResults(maxResults) + .getResultList(); + if (result.isEmpty()) { + LOG.info("Fant ingen IAY-aggregater uten grunnlag referanse"); + return emptyList(); + } + LOG.info("Fant {} IAY-aggregater uten grunnlag referanse", result.size()); + return result.stream().map(Number::longValue).toList(); + } + + public void slettIayAggregat(Long id) { + var iay = entityManager.find(InntektArbeidYtelseAggregat.class, id); + if (iay != null) { + slettIayAktørIntekt(id); + slettIayAktørArbeid(id); + slettIayAktørYtelse(id); + entityManager.remove(iay); + entityManager.flush(); // Sørger for at endringer er lagret før vi går videre + } + } + + private void slettIayAktørYtelse(Long iayIdForSletting) { + var aktørYtelseIdList = hentAktørYtelseFor(iayIdForSletting); + if (!aktørYtelseIdList.isEmpty()) { + var relatertYtelseIdList = hentRelaterteYtelserFor(aktørYtelseIdList); + if (!relatertYtelseIdList.isEmpty()) { + var ytelseGrunnlagIdList = hentYtelseGrunnlagFor(relatertYtelseIdList); + if (!ytelseGrunnlagIdList.isEmpty()) { + fjernYtelseStørrelseFor(ytelseGrunnlagIdList); + fjernYtelseGrunnlagFor(relatertYtelseIdList); + } + var ytelseAnvistIdList = hentYtelseAnvistFor(relatertYtelseIdList); + if (!ytelseAnvistIdList.isEmpty()) { + fjernYtelseAnvistAndelFor(ytelseAnvistIdList); + fjernYtelseAnvistFor(relatertYtelseIdList); + } + fjernRelatertYtelseFor(aktørYtelseIdList); + } + fjernAktørYtelseFor(iayIdForSletting); + } + } + + private List hentAktørYtelseFor(Long iayIdForSletting) { + @SuppressWarnings("unchecked") List result = entityManager.createNativeQuery( + "select distinct id from iay_aktoer_ytelse where inntekt_arbeid_ytelser_id = :iayId") + .setParameter(PARAM_IAY_ID, iayIdForSletting) + .getResultList(); + return result.stream().map(Number::longValue).toList(); + } + + private List hentRelaterteYtelserFor(List aktørYtelseIdList) { + @SuppressWarnings("unchecked") List result = entityManager.createNativeQuery( + "select distinct id from iay_relatert_ytelse where aktoer_ytelse_id in (:aktoerYtelseIdList)") + .setParameter("aktoerYtelseIdList", aktørYtelseIdList) + .getResultList(); + return result.stream().map(Number::longValue).toList(); + } + + private List hentYtelseGrunnlagFor(List relatertYtelseIdList) { + @SuppressWarnings("unchecked") List result = entityManager.createNativeQuery( + "select distinct id from iay_ytelse_grunnlag where ytelse_id in (:relatertYtelseIdList)") + .setParameter(PARAM_RELATERT_YTELSE_ID_LIST, relatertYtelseIdList) + .getResultList(); + return result.stream().map(Number::longValue).toList(); + } + + private List hentYtelseAnvistFor(List relatertYtelseIdList) { + @SuppressWarnings("unchecked") List result = entityManager.createNativeQuery( + "select distinct id from iay_ytelse_anvist where ytelse_id in (:relatertYtelseIdList)") + .setParameter(PARAM_RELATERT_YTELSE_ID_LIST, relatertYtelseIdList) + .getResultList(); + return result.stream().map(Number::longValue).toList(); + } + + private void fjernYtelseStørrelseFor(List ytelseGrunnlagIdList) { + var antallFjernet = entityManager.createNativeQuery("delete from iay_ytelse_stoerrelse where ytelse_grunnlag_id in (:ytelseGrunnlagIdList)") + .setParameter("ytelseGrunnlagIdList", ytelseGrunnlagIdList) + .executeUpdate(); + LOG.info("Fjernet {} ytelse størrelser for ytelse grunnlag: {}", antallFjernet, ytelseGrunnlagIdList); + } + + private void fjernYtelseGrunnlagFor(List relatertYtelseIdList) { + var antallFjernet = entityManager.createNativeQuery("delete from iay_ytelse_grunnlag where ytelse_id in (:relatertYtelseIdList)") + .setParameter(PARAM_RELATERT_YTELSE_ID_LIST, relatertYtelseIdList) + .executeUpdate(); + LOG.info("Fjernet {} ytelse grunnlag for relatert ytelse: {}", antallFjernet, relatertYtelseIdList); + } + + private void fjernYtelseAnvistAndelFor(List ytelseAnvistIdList) { + var antallFjernet = entityManager.createNativeQuery("delete from iay_ytelse_anvist_andel where ytelse_anvist_id in (:ytelseAnvistIdList)") + .setParameter("ytelseAnvistIdList", ytelseAnvistIdList) + .executeUpdate(); + LOG.info("Fjernet {} ytelse anvist andeler for ytelse anvist: {}", antallFjernet, ytelseAnvistIdList); + } + + private void fjernYtelseAnvistFor(List relatertYtelseIdList) { + var antallFjernet = entityManager.createNativeQuery("delete from iay_ytelse_anvist where ytelse_id in (:relatertYtelseIdList)") + .setParameter(PARAM_RELATERT_YTELSE_ID_LIST, relatertYtelseIdList) + .executeUpdate(); + LOG.info("Fjernet {} ytelse anvist for relatert ytelse: {}", antallFjernet, relatertYtelseIdList); + } + + private void fjernRelatertYtelseFor(List aktørYtelseIdList) { + var antallFjernet = entityManager.createNativeQuery("delete from iay_relatert_ytelse where aktoer_ytelse_id in (:aktoerYtelseIdList)") + .setParameter("aktoerYtelseIdList", aktørYtelseIdList) + .executeUpdate(); + LOG.info("Fjernet {} relatert ytelse for aktør ytelse: {}", antallFjernet, aktørYtelseIdList); + } + + private void fjernAktørYtelseFor(Long iayIdForSletting) { + var antallFjernet = entityManager.createNativeQuery("delete from iay_aktoer_ytelse where inntekt_arbeid_ytelser_id = :iayId") + .setParameter(PARAM_IAY_ID, iayIdForSletting) + .executeUpdate(); + LOG.info("Fjernet {} aktør ytelse for iay-aggregat: {}", antallFjernet, iayIdForSletting); + } + + private void slettIayAktørArbeid(Long iayIdForSletting) { + var aktørArbeidIdList = hentAktørArbeidFor(iayIdForSletting); + if (!aktørArbeidIdList.isEmpty()) { + var yrkesaktivitetIdList = hentYrkesaktiviteterFor(aktørArbeidIdList); + if (!yrkesaktivitetIdList.isEmpty()) { + fjernPermisjonerFor(yrkesaktivitetIdList); + fjernAktivitetsAvtalerFor(yrkesaktivitetIdList); + fjernYrkesaktiviteterFor(aktørArbeidIdList); + } + fjernAktørArbeidFor(iayIdForSletting); + } + } + + private List hentAktørArbeidFor(Long iayIdForSletting) { + @SuppressWarnings("unchecked") List result = entityManager.createNativeQuery( + "select distinct id from iay_aktoer_arbeid where inntekt_arbeid_ytelser_id = :iayId") + .setParameter(PARAM_IAY_ID, iayIdForSletting) + .getResultList(); + return result.stream().map(Number::longValue).toList(); + } + + private List hentYrkesaktiviteterFor(List aktørArbeidIdList) { + @SuppressWarnings("unchecked") List result = entityManager.createNativeQuery( + "select distinct id from iay_yrkesaktivitet where aktoer_arbeid_id in (:aktoerArbeidIdList)") + .setParameter("aktoerArbeidIdList", aktørArbeidIdList) + .getResultList(); + return result.stream().map(Number::longValue).toList(); + } + + private void fjernPermisjonerFor(List yrkesaktivitetIdList) { + var antallFjernet = entityManager.createNativeQuery("delete from iay_permisjon where yrkesaktivitet_id in (:yrkesaktivitetIdList)") + .setParameter("yrkesaktivitetIdList", yrkesaktivitetIdList) + .executeUpdate(); + LOG.info("Fjernet {} permisjoner for yrkesaktiviteter: {}", antallFjernet, yrkesaktivitetIdList); + } + + private void fjernAktivitetsAvtalerFor(List yrkesaktivitetIdList) { + var antallFjernet = entityManager.createNativeQuery("delete from iay_aktivitets_avtale where yrkesaktivitet_id in (:yrkesaktivitetIdList)") + .setParameter("yrkesaktivitetIdList", yrkesaktivitetIdList) + .executeUpdate(); + LOG.info("Fjernet {} aktivitets avtaler for yrkesaktiviteter: {}", antallFjernet, yrkesaktivitetIdList); + } + + private void fjernYrkesaktiviteterFor(List aktørArbeidIdList) { + var antallFjernet = entityManager.createNativeQuery("delete from iay_yrkesaktivitet where aktoer_arbeid_id in (:aktoerArbeidIdList)") + .setParameter("aktoerArbeidIdList", aktørArbeidIdList) + .executeUpdate(); + LOG.info("Fjernet {} yrkesaktiviteter for aktør arbeid: {}", antallFjernet, aktørArbeidIdList); + } + + private void fjernAktørArbeidFor(Long iayIdForSletting) { + var antallFjernet = entityManager.createNativeQuery("delete from iay_aktoer_arbeid where inntekt_arbeid_ytelser_id = :iayId") + .setParameter(PARAM_IAY_ID, iayIdForSletting) + .executeUpdate(); + LOG.info("Fjernet {} aktør arbeid for iay-aggregat: {}", antallFjernet, iayIdForSletting); + } + + private void slettIayAktørIntekt(Long iayIdForSletting) { + var aktørInntektIdList = hentAktørInntekterFor(iayIdForSletting); + if (!aktørInntektIdList.isEmpty()) { + var inntektIdList = hentInntekterFor(aktørInntektIdList); + if (!inntektIdList.isEmpty()) { + fjernInntektsposterFor(inntektIdList); + fjernInntekterFor(aktørInntektIdList); + } + fjernAktørInntektFor(iayIdForSletting); + } + } + + private List hentAktørInntekterFor(Long iayIdForSletting) { + @SuppressWarnings("unchecked") List result = entityManager.createNativeQuery( + "select distinct id from iay_aktoer_inntekt where inntekt_arbeid_ytelser_id = :iayId") + .setParameter(PARAM_IAY_ID, iayIdForSletting) + .getResultList(); + return result.stream().map(Number::longValue).toList(); + } + + private List hentInntekterFor(List aktørInntektIdList) { + @SuppressWarnings("unchecked") List result = entityManager.createNativeQuery( + "select distinct id from iay_inntekt where aktoer_inntekt_id in (:aktoerInntektIdList)") + .setParameter("aktoerInntektIdList", aktørInntektIdList) + .getResultList(); + return result.stream().map(Number::longValue).toList(); + } + + private void fjernInntektsposterFor(List inntektIdList) { + var antallFjernet = entityManager.createNativeQuery("delete from iay_inntektspost where inntekt_id in (:inntektIdList)") + .setParameter("inntektIdList", inntektIdList) + .executeUpdate(); + LOG.info("Fjernet {} inntektsposter for inntekter: {}", antallFjernet, inntektIdList); + } + + private void fjernInntekterFor(List aktørInntektIdList) { + var antallFjernet = entityManager.createNativeQuery("delete from iay_inntekt where aktoer_inntekt_id in (:aktoerInntektIdList)") + .setParameter("aktoerInntektIdList", aktørInntektIdList) + .executeUpdate(); + LOG.info("Fjernet {} inntekter for aktør inntekter: {}", antallFjernet, aktørInntektIdList); + + } + + private void fjernAktørInntektFor(Long iayIdForSletting) { + var antallFjernet = entityManager.createNativeQuery("delete from iay_aktoer_inntekt where inntekt_arbeid_ytelser_id = :iayId") + .setParameter(PARAM_IAY_ID, iayIdForSletting) + .executeUpdate(); + LOG.info("Fjernet {} aktør inntekter for iay-aggregat: {}", antallFjernet, iayIdForSletting); + } +} diff --git a/web/src/main/java/no/nav/foreldrepenger/abakus/rydding/OppryddingTjeneste.java b/web/src/main/java/no/nav/foreldrepenger/abakus/rydding/OppryddingTjeneste.java new file mode 100644 index 000000000..128f83d95 --- /dev/null +++ b/web/src/main/java/no/nav/foreldrepenger/abakus/rydding/OppryddingTjeneste.java @@ -0,0 +1,49 @@ +package no.nav.foreldrepenger.abakus.rydding; + +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import no.nav.foreldrepenger.abakus.rydding.task.FjernIAYGrunnlagUtenReferanseTask; +import no.nav.vedtak.felles.prosesstask.api.ProsessTaskData; +import no.nav.vedtak.felles.prosesstask.api.ProsessTaskTjeneste; +import no.nav.vedtak.mapper.json.DefaultJsonMapper; + +import static no.nav.foreldrepenger.abakus.rydding.task.FjernIAYGrunnlagUtenReferanseTask.MAX_PARTITION_SIZE; + +@ApplicationScoped +public class OppryddingTjeneste { + private static final Logger LOG = LoggerFactory.getLogger(OppryddingTjeneste.class); + private OppryddingIAYAggregatRepository iayOppryddingRepository; + private ProsessTaskTjeneste taskTjeneste; + + OppryddingTjeneste() { + // CDI proxy + } + + @Inject + public OppryddingTjeneste(OppryddingIAYAggregatRepository iayOppryddingRepository, ProsessTaskTjeneste taskTjeneste) { + this.iayOppryddingRepository = iayOppryddingRepository; + this.taskTjeneste = taskTjeneste; + } + + public void fjernAlleIayAggregatUtenReferanse() { + var iayAggregatUtenReferanse = iayOppryddingRepository.hentIayAggregaterUtenReferanse(MAX_PARTITION_SIZE); + if (iayAggregatUtenReferanse.isEmpty()) { + LOG.info("Ingen IAY aggregat for sletting."); + return; + } + LOG.info("Fjerner {} IAY-aggregater uten referanse.", iayAggregatUtenReferanse.size()); + opprettFjernIayAggregatTask(iayAggregatUtenReferanse); + } + + private void opprettFjernIayAggregatTask(List iayIdsList) { + LOG.info("Oppretter task for å fjerne {} IAY-aggregater uten referanse.", iayIdsList.size()); + var prosessTaskData = ProsessTaskData.forProsessTask(FjernIAYGrunnlagUtenReferanseTask.class); + prosessTaskData.setPayload(DefaultJsonMapper.toJson(iayIdsList)); + taskTjeneste.lagre(prosessTaskData); + } +} diff --git a/web/src/main/java/no/nav/foreldrepenger/abakus/rydding/task/FjernAlleGrunnlagUtenReferanseBatchTask.java b/web/src/main/java/no/nav/foreldrepenger/abakus/rydding/task/FjernAlleGrunnlagUtenReferanseBatchTask.java new file mode 100644 index 000000000..3e906802f --- /dev/null +++ b/web/src/main/java/no/nav/foreldrepenger/abakus/rydding/task/FjernAlleGrunnlagUtenReferanseBatchTask.java @@ -0,0 +1,25 @@ +package no.nav.foreldrepenger.abakus.rydding.task; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import no.nav.foreldrepenger.abakus.rydding.OppryddingTjeneste; +import no.nav.vedtak.felles.prosesstask.api.ProsessTask; +import no.nav.vedtak.felles.prosesstask.api.ProsessTaskData; +import no.nav.vedtak.felles.prosesstask.api.ProsessTaskHandler; + +@ApplicationScoped +@ProsessTask(value = "opprydding.grunnlag.uten.referanse", cronExpression = "0 0 3 * * *", maxFailedRuns = 1) +public class FjernAlleGrunnlagUtenReferanseBatchTask implements ProsessTaskHandler { + + private final OppryddingTjeneste oppryddingTjeneste; + + @Inject + public FjernAlleGrunnlagUtenReferanseBatchTask(OppryddingTjeneste oppryddingTjeneste) { + this.oppryddingTjeneste = oppryddingTjeneste; + } + + @Override + public void doTask(ProsessTaskData prosessTaskData) { + oppryddingTjeneste.fjernAlleIayAggregatUtenReferanse(); + } +} diff --git a/web/src/main/java/no/nav/foreldrepenger/abakus/rydding/task/FjernIAYGrunnlagUtenReferanseTask.java b/web/src/main/java/no/nav/foreldrepenger/abakus/rydding/task/FjernIAYGrunnlagUtenReferanseTask.java new file mode 100644 index 000000000..da293f13f --- /dev/null +++ b/web/src/main/java/no/nav/foreldrepenger/abakus/rydding/task/FjernIAYGrunnlagUtenReferanseTask.java @@ -0,0 +1,51 @@ +package no.nav.foreldrepenger.abakus.rydding.task; + +import java.util.List; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import no.nav.foreldrepenger.abakus.rydding.OppryddingIAYAggregatRepository; +import no.nav.vedtak.felles.prosesstask.api.ProsessTask; +import no.nav.vedtak.felles.prosesstask.api.ProsessTaskData; +import no.nav.vedtak.felles.prosesstask.api.ProsessTaskHandler; +import no.nav.vedtak.felles.prosesstask.api.ProsessTaskTjeneste; +import no.nav.vedtak.mapper.json.DefaultJsonMapper; + +@ApplicationScoped +@ProsessTask(value = "opprydding.iayGrunnlag.uten.referanse", maxFailedRuns = 2) +public class FjernIAYGrunnlagUtenReferanseTask implements ProsessTaskHandler { + public static final int MAX_PARTITION_SIZE = 250; + private static final Logger LOG = LoggerFactory.getLogger(FjernIAYGrunnlagUtenReferanseTask.class); + private final OppryddingIAYAggregatRepository iayAggregatRepository; + private final ProsessTaskTjeneste taskTjeneste; + + @Inject + public FjernIAYGrunnlagUtenReferanseTask(OppryddingIAYAggregatRepository iayAggregatRepository, ProsessTaskTjeneste taskTjeneste) { + this.iayAggregatRepository = iayAggregatRepository; + this.taskTjeneste = taskTjeneste; + } + + @Override + public void doTask(ProsessTaskData prosessTaskData) { + Set iayAggregatUtenReferanse = DefaultJsonMapper.fromJson(prosessTaskData.getPayloadAsString(), Set.class); + LOG.info("Fjerner {} IAY-aggregater uten referanse.", iayAggregatUtenReferanse.size()); + iayAggregatUtenReferanse.forEach(iayId -> iayAggregatRepository.slettIayAggregat(iayId.longValue())); + LOG.info("Slettet {} IAY-aggregater uten referanse", iayAggregatUtenReferanse.size()); + + var nyeAggregaterTilSletting = iayAggregatRepository.hentIayAggregaterUtenReferanse(MAX_PARTITION_SIZE); + if (!nyeAggregaterTilSletting.isEmpty()) { + opprettFjernIayAggregatTask(nyeAggregaterTilSletting); + } + } + + private void opprettFjernIayAggregatTask(List iayIdsList) { + LOG.info("Oppretter en ny task for å fjerne {} IAY-aggregater uten referanse.", iayIdsList.size()); + var prosessTaskData = ProsessTaskData.forProsessTask(FjernIAYGrunnlagUtenReferanseTask.class); + prosessTaskData.setPayload(DefaultJsonMapper.toJson(iayIdsList)); + taskTjeneste.lagre(prosessTaskData); + } +} diff --git a/web/src/test/java/no/nav/foreldrepenger/abakus/rydding/OppryddingIAYAggregatRepositoryTest.java b/web/src/test/java/no/nav/foreldrepenger/abakus/rydding/OppryddingIAYAggregatRepositoryTest.java new file mode 100644 index 000000000..596f1c2b9 --- /dev/null +++ b/web/src/test/java/no/nav/foreldrepenger/abakus/rydding/OppryddingIAYAggregatRepositoryTest.java @@ -0,0 +1,72 @@ +package no.nav.foreldrepenger.abakus.rydding; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Optional; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import jakarta.persistence.EntityManager; +import no.nav.foreldrepenger.abakus.dbstoette.JpaExtension; +import no.nav.foreldrepenger.abakus.domene.iay.InntektArbeidYtelseAggregatBuilder; +import no.nav.foreldrepenger.abakus.domene.iay.VersjonType; +import no.nav.vedtak.felles.testutilities.db.EntityManagerAwareTest; + +@ExtendWith(JpaExtension.class) +class OppryddingIAYAggregatRepositoryTest extends EntityManagerAwareTest { + + private OppryddingIAYAggregatRepository repository; + + @BeforeEach + void setUp(EntityManager entityManager) { + repository = new OppryddingIAYAggregatRepository(entityManager); + } + + @Test + void hentIayAggregaterUtenReferanse_medReferanse_ok() { + opprettEmptyIayAggregat(VersjonType.REGISTER); + + var iayAggregater = repository.hentIayAggregaterUtenReferanse(250); + + assertThat(iayAggregater).hasSize(1); + } + + @Test + void slettIayAggregat_register_ok() { + opprettEmptyIayAggregat(VersjonType.REGISTER); + + var iayAggregater = repository.hentIayAggregaterUtenReferanse(250); + assertThat(iayAggregater).hasSize(1); + + repository.slettIayAggregat(iayAggregater.getFirst()); + flushAndClear(); + + assertThat(repository.hentIayAggregaterUtenReferanse(250)).isEmpty(); + } + + @Test + void slettIayAggregat_saksbehandlet_ok() { + opprettEmptyIayAggregat(VersjonType.SAKSBEHANDLET); + + var iayAggregater = repository.hentIayAggregaterUtenReferanse(250); + assertThat(iayAggregater).hasSize(1); + + repository.slettIayAggregat(iayAggregater.getFirst()); + flushAndClear(); + + assertThat(repository.hentIayAggregaterUtenReferanse(250)).isEmpty(); + } + + private void opprettEmptyIayAggregat(VersjonType versjonType) { + var iayAggregat = InntektArbeidYtelseAggregatBuilder.oppdatere(Optional.empty(), versjonType).build(); + getEntityManager().persist(iayAggregat); + flushAndClear(); + } + + private void flushAndClear() { + getEntityManager().flush(); + getEntityManager().clear(); + } +} diff --git a/web/src/test/java/no/nav/foreldrepenger/abakus/rydding/OppryddingTjenesteTest.java b/web/src/test/java/no/nav/foreldrepenger/abakus/rydding/OppryddingTjenesteTest.java new file mode 100644 index 000000000..c8b376fdc --- /dev/null +++ b/web/src/test/java/no/nav/foreldrepenger/abakus/rydding/OppryddingTjenesteTest.java @@ -0,0 +1,56 @@ +package no.nav.foreldrepenger.abakus.rydding; + +import static no.nav.foreldrepenger.abakus.rydding.task.FjernIAYGrunnlagUtenReferanseTask.MAX_PARTITION_SIZE; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; +import static org.mockito.Mockito.when; + +import java.util.List; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import no.nav.vedtak.felles.prosesstask.api.ProsessTaskData; +import no.nav.vedtak.felles.prosesstask.api.ProsessTaskTjeneste; + +@ExtendWith(MockitoExtension.class) +class OppryddingTjenesteTest { + + @Mock + private OppryddingIAYAggregatRepository oppryddingIAYAggregatRepository; + @Mock + private ProsessTaskTjeneste prosessTaskTjeneste; + + private OppryddingTjeneste oppryddingTjeneste; + + @BeforeEach + void setUp() { + oppryddingTjeneste = new OppryddingTjeneste(oppryddingIAYAggregatRepository, prosessTaskTjeneste); + } + + @Test + void testFjernAlleIayAggregatUtenReferanse_noAggregates_ok() { + when(oppryddingIAYAggregatRepository.hentIayAggregaterUtenReferanse(MAX_PARTITION_SIZE)).thenReturn(List.of()); + + oppryddingTjeneste.fjernAlleIayAggregatUtenReferanse(); + + verify(oppryddingIAYAggregatRepository, times(1)).hentIayAggregaterUtenReferanse(MAX_PARTITION_SIZE); + verifyNoInteractions(prosessTaskTjeneste); + } + + @Test + void testFjernAlleIayAggregatUtenReferanse_withAggregates_ok() { + var aggregates = List.of(1L, 2L, 3L); + when(oppryddingIAYAggregatRepository.hentIayAggregaterUtenReferanse(MAX_PARTITION_SIZE)).thenReturn(aggregates); + + oppryddingTjeneste.fjernAlleIayAggregatUtenReferanse(); + + verify(oppryddingIAYAggregatRepository).hentIayAggregaterUtenReferanse(MAX_PARTITION_SIZE); + verify(prosessTaskTjeneste, times(1)).lagre(any(ProsessTaskData.class)); + } +} diff --git a/web/src/test/java/no/nav/foreldrepenger/abakus/rydding/task/FjernAlleGrunnlagUtenReferanseBatchTaskTest.java b/web/src/test/java/no/nav/foreldrepenger/abakus/rydding/task/FjernAlleGrunnlagUtenReferanseBatchTaskTest.java new file mode 100644 index 000000000..ba78e804c --- /dev/null +++ b/web/src/test/java/no/nav/foreldrepenger/abakus/rydding/task/FjernAlleGrunnlagUtenReferanseBatchTaskTest.java @@ -0,0 +1,32 @@ +package no.nav.foreldrepenger.abakus.rydding.task; + +import static org.mockito.Mockito.verify; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import no.nav.foreldrepenger.abakus.rydding.OppryddingTjeneste; +import no.nav.vedtak.felles.prosesstask.api.ProsessTaskData; + +@ExtendWith(MockitoExtension.class) +class FjernAlleGrunnlagUtenReferanseBatchTaskTest { + + @Mock + private OppryddingTjeneste oppryddingTjeneste; + + private FjernAlleGrunnlagUtenReferanseBatchTask task; + + @BeforeEach + void setUp() { + task = new FjernAlleGrunnlagUtenReferanseBatchTask(oppryddingTjeneste); + } + + @Test + void doTask() { + task.doTask(ProsessTaskData.forProsessTask(FjernAlleGrunnlagUtenReferanseBatchTask.class)); + verify(oppryddingTjeneste).fjernAlleIayAggregatUtenReferanse(); + } +} diff --git a/web/src/test/java/no/nav/foreldrepenger/abakus/rydding/task/FjernIAYGrunnlagUtenReferanseTaskTest.java b/web/src/test/java/no/nav/foreldrepenger/abakus/rydding/task/FjernIAYGrunnlagUtenReferanseTaskTest.java new file mode 100644 index 000000000..050bfda0f --- /dev/null +++ b/web/src/test/java/no/nav/foreldrepenger/abakus/rydding/task/FjernIAYGrunnlagUtenReferanseTaskTest.java @@ -0,0 +1,94 @@ +package no.nav.foreldrepenger.abakus.rydding.task; + +import static java.util.Collections.emptySet; +import static no.nav.foreldrepenger.abakus.rydding.task.FjernIAYGrunnlagUtenReferanseTask.MAX_PARTITION_SIZE; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.List; +import java.util.Set; +import java.util.stream.LongStream; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import no.nav.foreldrepenger.abakus.rydding.OppryddingIAYAggregatRepository; +import no.nav.vedtak.felles.prosesstask.api.ProsessTaskData; +import no.nav.vedtak.felles.prosesstask.api.ProsessTaskTjeneste; +import no.nav.vedtak.mapper.json.DefaultJsonMapper; + +@ExtendWith(MockitoExtension.class) +class FjernIAYGrunnlagUtenReferanseTaskTest { + + @Mock + private OppryddingIAYAggregatRepository oppryddingIAYAggregatRepository; + @Mock + private ProsessTaskTjeneste prosessTaskTjeneste; + @Captor + private ArgumentCaptor longCaptor; + @Captor ArgumentCaptor prosessTaskDataCaptor; + + private FjernIAYGrunnlagUtenReferanseTask task; + + @BeforeEach + void setUp() { + task = new FjernIAYGrunnlagUtenReferanseTask(oppryddingIAYAggregatRepository, prosessTaskTjeneste); + } + + @Test + void testDoTask_withValidPayload() { + var iayIds = Set.of(1L, 2L, 3L); + var payload = DefaultJsonMapper.toJson(iayIds); + var prosessTaskData = ProsessTaskData.forProsessTask(FjernIAYGrunnlagUtenReferanseTask.class); + prosessTaskData.setPayload(payload); + + task.doTask(prosessTaskData); + + verify(prosessTaskTjeneste, never()).lagre(any(ProsessTaskData.class)); + verify(oppryddingIAYAggregatRepository, times(3)).slettIayAggregat(longCaptor.capture()); + var capturedIds = Set.copyOf(longCaptor.getAllValues()); + assertEquals(iayIds, capturedIds); + } + + @Test + void testDoTask_withEmptyPayload() { + Set iayIds = emptySet(); + var payload = DefaultJsonMapper.toJson(iayIds); + var prosessTaskData = ProsessTaskData.forProsessTask(FjernIAYGrunnlagUtenReferanseTask.class); + prosessTaskData.setPayload(payload); + + task.doTask(prosessTaskData); + + verify(prosessTaskTjeneste, never()).lagre(any(ProsessTaskData.class)); + verify(oppryddingIAYAggregatRepository, never()).slettIayAggregat(anyLong()); + } + + @Test + void testDoTask_withValidPayload_over_max_partition_size() { + var iayIds = LongStream.rangeClosed(1, MAX_PARTITION_SIZE).boxed().toList(); + var payload = DefaultJsonMapper.toJson(iayIds); + var prosessTaskData = ProsessTaskData.forProsessTask(FjernIAYGrunnlagUtenReferanseTask.class); + prosessTaskData.setPayload(payload); + when(oppryddingIAYAggregatRepository.hentIayAggregaterUtenReferanse(MAX_PARTITION_SIZE)).thenReturn(iayIds.subList(0, MAX_PARTITION_SIZE - 5)); + + task.doTask(prosessTaskData); + + verify(oppryddingIAYAggregatRepository, times(MAX_PARTITION_SIZE)).slettIayAggregat(longCaptor.capture()); + var capturedIds = List.copyOf(longCaptor.getAllValues()); + assertEquals(iayIds, capturedIds); + verify(prosessTaskTjeneste).lagre(prosessTaskDataCaptor.capture()); + var nextProsesstaskPayload = DefaultJsonMapper.fromJson(prosessTaskDataCaptor.getValue().getPayloadAsString(), List.class); + assertThat(nextProsesstaskPayload).hasSize(MAX_PARTITION_SIZE - 5); + } +}