Skip to content

Commit d9a1fdb

Browse files
authored
feature: Legge til KDI fengselinstitusjon (#4238)
1 parent e66b5a8 commit d9a1fdb

65 files changed

Lines changed: 1938 additions & 227 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/dolly-backend/src/main/java/no/nav/dolly/bestilling/instdata/InstdataClient.java

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
import lombok.extern.slf4j.Slf4j;
55
import ma.glasnost.orika.MapperFacade;
66
import no.nav.dolly.bestilling.ClientRegister;
7+
import no.nav.dolly.bestilling.instdata.domain.InstdataKdiDTO;
78
import no.nav.dolly.bestilling.instdata.domain.InstdataResponse;
9+
import no.nav.dolly.bestilling.instdata.service.InstKdiHendelseService;
810
import no.nav.dolly.domain.jpa.BestillingProgress;
911
import no.nav.dolly.domain.resultset.RsDollyUtvidetBestilling;
1012
import no.nav.dolly.domain.resultset.dolly.DollyPerson;
@@ -21,32 +23,70 @@
2123
import java.util.stream.Collectors;
2224

2325
import static java.util.Collections.emptyList;
26+
import static java.util.Objects.isNull;
27+
import static java.util.Objects.nonNull;
2428

2529
@Slf4j
2630
@Service
2731
@RequiredArgsConstructor
2832
public class InstdataClient implements ClientRegister {
2933

34+
private static final String INST2_STATUS = "INST2_STATUS#%s";
35+
private static final String KDI_STATUS = "KDI_STATUS#%s";
36+
3037
private final MapperFacade mapperFacade;
3138
private final InstdataConsumer instdataConsumer;
3239
private final ErrorStatusDecoder errorStatusDecoder;
3340
private final TransactionHelperService transactionHelperService;
41+
private final InstKdiHendelseService instKdiHendelseService;
3442

3543
@Override
3644
public Mono<BestillingProgress> gjenopprett(RsDollyUtvidetBestilling bestilling, DollyPerson dollyPerson, BestillingProgress progress, boolean isOpprettEndre) {
3745

46+
if (bestilling.getInstdata().isEmpty() && isNull(bestilling.getInstdataKdi())) {
47+
48+
return Mono.empty();
49+
}
50+
51+
return Flux.merge(doInst2Bestilling(bestilling, dollyPerson, isOpprettEndre)
52+
.map(INST2_STATUS::formatted),
53+
doInstKdiBestilling(bestilling, dollyPerson, progress.getBestillingId(), isOpprettEndre)
54+
.map(KDI_STATUS::formatted))
55+
.collect(Collectors.joining("|"))
56+
.flatMap(resultat -> oppdaterStatus(progress, resultat));
57+
}
58+
59+
private Mono<String> doInstKdiBestilling(RsDollyUtvidetBestilling bestilling, DollyPerson dollyPerson, Long bestillingId, boolean isOpprettEndre) {
60+
61+
return Mono.just(bestilling)
62+
.filter(bestilling1 -> nonNull(bestilling1.getInstdataKdi()))
63+
.flatMap(bestilling1 -> instKdiHendelseService.getOppdaterBestilling(bestilling1, bestillingId, isOpprettEndre))
64+
.flatMap(instKdiData -> instdataConsumer.getMiljoer()
65+
.flatMapMany(miljoer -> Flux.fromIterable(miljoer.getKdiEnvironments())
66+
.filter(miljoe -> bestilling.getEnvironments().contains(miljoe))
67+
.map(miljoe -> {
68+
var context = MappingContextUtils.getMappingContext();
69+
context.setProperty("ident", dollyPerson.getIdent());
70+
context.setProperty("miljoe", miljoe);
71+
return mapperFacade.map(instKdiData, InstdataKdiDTO.class, context);
72+
}))
73+
.flatMap(instKdiRequest -> postInstdataKdi(instKdiRequest, dollyPerson.getIdent()))
74+
.collect(Collectors.joining(",")));
75+
}
76+
77+
private Flux<String> doInst2Bestilling(RsDollyUtvidetBestilling bestilling, DollyPerson dollyPerson, boolean isOpprettEndre) {
78+
3879
var context = MappingContextUtils.getMappingContext();
3980
context.setProperty("ident", dollyPerson.getIdent());
4081

4182
return Mono.just(bestilling.getInstdata())
4283
.filter(rsInstdata -> !rsInstdata.isEmpty())
43-
.flatMap(rsInstdata -> Mono.just(mapperFacade.mapAsList(rsInstdata, Instdata.class, context)))
84+
.flatMapMany(rsInstdata -> Mono.just(mapperFacade.mapAsList(rsInstdata, Instdata.class, context)))
4485
.flatMap(instdata -> instdataConsumer.getMiljoer()
45-
.flatMap(miljoer -> Flux.fromIterable(miljoer)
86+
.flatMapMany(miljoer -> Flux.fromIterable(miljoer.getInstitusjonsoppholdEnvironments())
4687
.filter(miljoe -> bestilling.getEnvironments().contains(miljoe))
4788
.flatMap(miljoe -> postInstdata(isOpprettEndre, instdata, miljoe))
48-
.collect(Collectors.joining(",")))
49-
.flatMap(status -> oppdaterStatus(progress, status)));
89+
.collect(Collectors.joining(","))));
5090
}
5191

5292
private Mono<BestillingProgress> oppdaterStatus(BestillingProgress progress, String status) {
@@ -60,7 +100,9 @@ private Mono<BestillingProgress> oppdaterStatus(BestillingProgress progress, Str
60100
public void release(List<String> identer) {
61101

62102
instdataConsumer.deleteInstdata(identer)
63-
.subscribe(response -> log.info("Slettet antall {} identer fra Instdata", response.size()));
103+
.subscribe(_ -> log.info("Slettet identer fra Instdata (inst 2)"));
104+
instdataConsumer.deleteInstKdiData(identer)
105+
.subscribe(_ -> log.info("Slettet identer fra Institusjonsopphold fengsel (KDI)"));
64106
}
65107

66108
private Mono<List<Instdata>> filterInstdata(List<Instdata> instdataRequest, String miljoe) {
@@ -100,4 +142,15 @@ private Mono<String> postInstdata(boolean isNewOpphold, List<Instdata> instdata,
100142
}
101143
});
102144
}
145+
146+
private Mono<String> postInstdataKdi(InstdataKdiDTO instdata, String ident) {
147+
148+
return instdataConsumer.postInstdataKdi(instdata, ident)
149+
.map(response -> String.format("%s:%s".formatted(
150+
instdata.getEnvironment(),
151+
response.getStatus().is2xxSuccessful() ? "OK" :
152+
ErrorStatusDecoder.encodeStatus(errorStatusDecoder.getErrorText(response.getStatus(),
153+
response.getFeilmelding())))));
154+
155+
}
103156
}

apps/dolly-backend/src/main/java/no/nav/dolly/bestilling/instdata/InstdataConsumer.java

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@
55
import no.nav.dolly.bestilling.instdata.command.InstdataDeleteCommand;
66
import no.nav.dolly.bestilling.instdata.command.InstdataGetCommand;
77
import no.nav.dolly.bestilling.instdata.command.InstdataGetMiljoerCommand;
8+
import no.nav.dolly.bestilling.instdata.command.InstdataKdiDeleteCommand;
9+
import no.nav.dolly.bestilling.instdata.command.InstdataKdiPostCommand;
810
import no.nav.dolly.bestilling.instdata.command.InstdataPostCommand;
9-
import no.nav.dolly.bestilling.instdata.domain.DeleteResponse;
11+
import no.nav.dolly.bestilling.instdata.domain.InstdataKdiDTO;
12+
import no.nav.dolly.bestilling.instdata.domain.InstdataKdiResponse;
1013
import no.nav.dolly.bestilling.instdata.domain.InstdataResponse;
11-
import no.nav.dolly.bestilling.instdata.domain.InstitusjonsoppholdRespons;
14+
import no.nav.dolly.bestilling.instdata.domain.MiljoerResponse;
1215
import no.nav.dolly.config.Consumers;
1316
import no.nav.dolly.domain.resultset.inst.Instdata;
1417
import no.nav.dolly.metrics.Timed;
@@ -43,30 +46,42 @@ public InstdataConsumer(
4346
}
4447

4548
@Timed(name = "providers", tags = {"operation", "inst_getMiljoer"})
46-
public Mono<List<String>> getMiljoer() {
49+
public Mono<MiljoerResponse> getMiljoer() {
4750

4851
return tokenService.exchange(serverProperties)
4952
.flatMap(token -> new InstdataGetMiljoerCommand(webClient, token.getTokenValue()).call());
5053
}
5154

5255
@Timed(name = "providers", tags = {"operation", "inst_getInstdata"})
53-
public Mono<InstitusjonsoppholdRespons> getInstdata(String ident, String environment) {
56+
public Mono<InstdataResponse> getInstdata(String ident, String environment) {
5457

5558
return tokenService.exchange(serverProperties)
5659
.flatMap(token -> new InstdataGetCommand(webClient, ident, environment, token.getTokenValue()).call());
5760
}
5861

5962
@Timed(name = "providers", tags = {"operation", "inst_deleteInstdata"})
60-
public Mono<List<DeleteResponse>> deleteInstdata(List<String> identer) {
63+
public Mono<List<InstdataResponse>> deleteInstdata(List<String> identer) {
6164

6265
return tokenService.exchange(serverProperties)
6366
.flatMap(token -> new InstdataGetMiljoerCommand(webClient, token.getTokenValue()).call()
6467
.flatMap(miljoer -> Flux.fromIterable(identer)
6568
.flatMap(ident -> new InstdataDeleteCommand(webClient,
66-
ident, miljoer, token.getTokenValue()).call())
69+
ident, miljoer.getInstitusjonsoppholdEnvironments(), token.getTokenValue()).call())
6770
.collectList()));
6871
}
6972

73+
@Timed(name = "providers", tags = {"operation", "inst_deleteInstdataKdi"})
74+
public Mono<List<InstdataKdiResponse>> deleteInstKdiData(List<String> identer) {
75+
76+
return tokenService.exchange(serverProperties)
77+
.flatMap(token -> new InstdataGetMiljoerCommand(webClient, token.getTokenValue()).call()
78+
.flatMapMany(miljoer -> Flux.fromIterable(identer)
79+
.flatMap(ident -> Flux.fromIterable(miljoer.getKdiEnvironments())
80+
.flatMap(miljoe -> new InstdataKdiDeleteCommand(webClient,
81+
ident, miljoe, token.getTokenValue()).call())))
82+
.collectList());
83+
}
84+
7085
@Timed(name = "providers", tags = {"operation", "inst_postInstdata"})
7186
public Flux<InstdataResponse> postInstdata(List<Instdata> instdata, String environment) {
7287

@@ -77,6 +92,15 @@ public Flux<InstdataResponse> postInstdata(List<Instdata> instdata, String envir
7792
token.getTokenValue()).call()));
7893
}
7994

95+
@Timed(name = "providers", tags = {"operation", "inst_postInstdataKdi"})
96+
public Mono<InstdataKdiResponse> postInstdataKdi(InstdataKdiDTO instdata, String ident) {
97+
98+
log.info("Instdata KDI oppretting {}", instdata);
99+
return tokenService.exchange(serverProperties)
100+
.flatMap(token -> new InstdataKdiPostCommand(webClient, ident, instdata,
101+
token.getTokenValue()).call());
102+
}
103+
80104
@Override
81105
public String serviceUrl() {
82106
return serverProperties.getUrl();

apps/dolly-backend/src/main/java/no/nav/dolly/bestilling/instdata/command/InstdataDeleteCommand.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
import lombok.RequiredArgsConstructor;
44
import lombok.extern.slf4j.Slf4j;
5-
import no.nav.dolly.bestilling.instdata.domain.DeleteResponse;
65
import no.nav.dolly.bestilling.instdata.domain.InstdataRequest;
6+
import no.nav.dolly.bestilling.instdata.domain.InstdataResponse;
77
import no.nav.testnav.libs.reactivecore.web.WebClientError;
88
import no.nav.testnav.libs.reactivecore.web.WebClientHeader;
99
import org.springframework.http.HttpStatus;
@@ -16,7 +16,7 @@
1616

1717
@RequiredArgsConstructor
1818
@Slf4j
19-
public class InstdataDeleteCommand implements Callable<Mono<DeleteResponse>> {
19+
public class InstdataDeleteCommand implements Callable<Mono<InstdataResponse>> {
2020

2121
private static final String INSTDATA_URL = "/inst/api/v1/institusjonsopphold/person/slett";
2222

@@ -26,7 +26,7 @@ public class InstdataDeleteCommand implements Callable<Mono<DeleteResponse>> {
2626
private final String token;
2727

2828
@Override
29-
public Mono<DeleteResponse> call() {
29+
public Mono<InstdataResponse> call() {
3030

3131
return webClient
3232
.post()
@@ -40,14 +40,15 @@ public Mono<DeleteResponse> call() {
4040
.build())
4141
.retrieve()
4242
.toBodilessEntity()
43-
.map(resultat -> DeleteResponse.builder()
44-
.ident(ident)
43+
.map(resultat -> InstdataResponse.builder()
4544
.status(HttpStatus.valueOf(resultat.getStatusCode().value()))
45+
.personident(ident)
46+
.environments(miljoer)
4647
.build())
4748
.doOnError(
4849
throwable -> !(throwable instanceof WebClientResponseException.BadRequest),
4950
WebClientError.logTo(log))
5051
.retryWhen(WebClientError.is5xxException())
51-
.onErrorResume(throwable -> DeleteResponse.of(WebClientError.describe(throwable), ident));
52+
.onErrorResume(throwable -> InstdataResponse.of(WebClientError.describe(throwable), ident, miljoer));
5253
}
5354
}

apps/dolly-backend/src/main/java/no/nav/dolly/bestilling/instdata/command/InstdataGetCommand.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@
33
import lombok.RequiredArgsConstructor;
44
import lombok.extern.slf4j.Slf4j;
55
import no.nav.dolly.bestilling.instdata.domain.InstdataRequest;
6-
import no.nav.dolly.bestilling.instdata.domain.InstitusjonsoppholdRespons;
6+
import no.nav.dolly.bestilling.instdata.domain.InstdataResponse;
77
import no.nav.dolly.domain.resultset.inst.Instdata;
88
import no.nav.testnav.libs.reactivecore.web.WebClientError;
99
import no.nav.testnav.libs.reactivecore.web.WebClientHeader;
1010
import org.springframework.core.ParameterizedTypeReference;
1111
import org.springframework.http.HttpHeaders;
12+
import org.springframework.http.HttpStatus;
1213
import org.springframework.web.reactive.function.client.WebClient;
1314
import reactor.core.publisher.Mono;
1415

@@ -18,7 +19,7 @@
1819

1920
@Slf4j
2021
@RequiredArgsConstructor
21-
public class InstdataGetCommand implements Callable<Mono<InstitusjonsoppholdRespons>> {
22+
public class InstdataGetCommand implements Callable<Mono<InstdataResponse>> {
2223

2324
private static final String INSTDATA_URL = "/inst/api/v1/institusjonsopphold/person/soek";
2425

@@ -28,7 +29,7 @@ public class InstdataGetCommand implements Callable<Mono<InstitusjonsoppholdResp
2829
private final String token;
2930

3031
@Override
31-
public Mono<InstitusjonsoppholdRespons> call() {
32+
public Mono<InstdataResponse> call() {
3233
return webClient
3334
.post()
3435
.uri(builder -> builder.path(INSTDATA_URL)
@@ -42,11 +43,15 @@ public Mono<InstitusjonsoppholdRespons> call() {
4243
.retrieve()
4344
.bodyToMono(new ParameterizedTypeReference<Map<String, List<Instdata>>>() {
4445
})
45-
.map(resultat -> InstitusjonsoppholdRespons.builder()
46+
.map(resultat -> InstdataResponse.builder()
47+
.status(HttpStatus.OK)
48+
.personident(ident)
49+
.environments(List.of(miljoe))
4650
.institusjonsopphold(resultat)
4751
.build())
4852
.doOnError(error -> log.error("Henting av institusjonsopphold feilet", error))
4953
.retryWhen(WebClientError.is5xxException())
50-
.onErrorResume(error -> Mono.just(new InstitusjonsoppholdRespons()));
54+
.onErrorResume(throwable -> InstdataResponse.of(WebClientError.describe(throwable),
55+
ident, List.of(miljoe)));
5156
}
5257
}

apps/dolly-backend/src/main/java/no/nav/dolly/bestilling/instdata/command/InstdataGetMiljoerCommand.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,21 @@
88
import org.springframework.web.reactive.function.client.WebClient;
99
import reactor.core.publisher.Mono;
1010

11+
import java.time.Duration;
1112
import java.util.List;
1213
import java.util.concurrent.Callable;
1314

1415
@RequiredArgsConstructor
1516
@Slf4j
16-
public class InstdataGetMiljoerCommand implements Callable<Mono<List<String>>> {
17+
public class InstdataGetMiljoerCommand implements Callable<Mono<MiljoerResponse>> {
1718

1819
private static final String INSTMILJO_URL = "/inst/api/v1/environment";
1920

2021
private final WebClient webClient;
2122
private final String token;
2223

2324
@Override
24-
public Mono<List<String>> call() {
25+
public Mono<MiljoerResponse> call() {
2526

2627
return webClient
2728
.get()
@@ -31,10 +32,13 @@ public Mono<List<String>> call() {
3132
.headers(WebClientHeader.bearer(token))
3233
.retrieve()
3334
.bodyToMono(MiljoerResponse.class)
34-
.map(MiljoerResponse::getInstitusjonsoppholdEnvironments)
3535
.doOnError(WebClientError.logTo(log))
3636
.retryWhen(WebClientError.is5xxException())
3737
.onErrorResume(error ->
38-
Mono.just(List.of("q1", "q2")));
38+
Mono.just(MiljoerResponse.builder()
39+
.institusjonsoppholdEnvironments(List.of("q1", "q2"))
40+
.kdiEnvironments(List.of("q2"))
41+
.build()))
42+
.cache(Duration.ofSeconds(60));
3943
}
4044
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package no.nav.dolly.bestilling.instdata.command;
2+
3+
import lombok.RequiredArgsConstructor;
4+
import lombok.extern.slf4j.Slf4j;
5+
import no.nav.dolly.bestilling.instdata.domain.InstdataKdiResponse;
6+
import no.nav.dolly.bestilling.instdata.domain.InstdataRequest;
7+
import no.nav.testnav.libs.reactivecore.web.WebClientError;
8+
import no.nav.testnav.libs.reactivecore.web.WebClientHeader;
9+
import org.springframework.http.HttpMethod;
10+
import org.springframework.http.HttpStatus;
11+
import org.springframework.web.reactive.function.client.WebClient;
12+
import org.springframework.web.reactive.function.client.WebClientResponseException;
13+
import reactor.core.publisher.Mono;
14+
15+
import java.util.concurrent.Callable;
16+
17+
@RequiredArgsConstructor
18+
@Slf4j
19+
public class InstdataKdiDeleteCommand implements Callable<Mono<InstdataKdiResponse>> {
20+
21+
private static final String INSTDATA_KDI_URL = "/inst/api/v2/kdi/person";
22+
23+
private final WebClient webClient;
24+
private final String ident;
25+
private final String miljoe;
26+
private final String token;
27+
28+
@Override
29+
public Mono<InstdataKdiResponse> call() {
30+
31+
return webClient
32+
.method(HttpMethod.DELETE)
33+
.uri(uriBuilder -> uriBuilder
34+
.path(INSTDATA_KDI_URL)
35+
.build())
36+
.headers(WebClientHeader.bearer(token))
37+
.bodyValue(InstdataRequest.builder()
38+
.norskident(ident)
39+
.environment(miljoe)
40+
.build())
41+
.retrieve()
42+
.toBodilessEntity()
43+
.map(resultat -> InstdataKdiResponse.builder()
44+
.ident(ident)
45+
.status(HttpStatus.valueOf(resultat.getStatusCode().value()))
46+
.environment(miljoe)
47+
.build())
48+
.doOnError(throwable ->
49+
!(throwable instanceof WebClientResponseException.BadRequest),
50+
WebClientError.logTo(log))
51+
.retryWhen(WebClientError.is5xxException())
52+
.onErrorResume(throwable -> InstdataKdiResponse.of(WebClientError.describe(throwable), ident, miljoe));
53+
}
54+
}

0 commit comments

Comments
 (0)