diff --git a/apps/testnav-ident-pool/src/main/java/no/nav/testnav/identpool/config/SecurityConfig.java b/apps/testnav-ident-pool/src/main/java/no/nav/testnav/identpool/config/SecurityConfig.java index b4f02ff8b89..3b917270a0c 100644 --- a/apps/testnav-ident-pool/src/main/java/no/nav/testnav/identpool/config/SecurityConfig.java +++ b/apps/testnav-ident-pool/src/main/java/no/nav/testnav/identpool/config/SecurityConfig.java @@ -6,6 +6,7 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; +import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.web.SecurityFilterChain; @@ -19,15 +20,20 @@ public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Excepti httpSecurity.sessionManagement(sessionConfig -> sessionConfig.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .csrf(AbstractHttpConfigurer::disable) .authorizeHttpRequests(authorizeConfig -> authorizeConfig.requestMatchers( - "/internal/**", - "/webjars/**", - "/swagger-resources/**", - "/v3/api-docs/**", - "/swagger-ui/**", - "/swagger", - "/error", - "/swagger-ui.html" - ).permitAll().requestMatchers("/api/**").fullyAuthenticated()) + "/internal/**", + "/webjars/**", + "/swagger-resources/**", + "/v3/api-docs/**", + "/swagger-ui/**", + "/swagger", + "/error", + "/swagger-ui.html", + "/h2/**", + "/member/**") + .permitAll() + .requestMatchers("/api/**") + .fullyAuthenticated()) + .headers(headers -> headers.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable)) .oauth2ResourceServer(oauth2RSConfig -> oauth2RSConfig.jwt(Customizer.withDefaults())); return httpSecurity.build(); diff --git a/apps/testnav-ident-pool/src/main/java/no/nav/testnav/identpool/service/DatabaseService.java b/apps/testnav-ident-pool/src/main/java/no/nav/testnav/identpool/service/DatabaseService.java index ab9579e7172..1c75f38baee 100644 --- a/apps/testnav-ident-pool/src/main/java/no/nav/testnav/identpool/service/DatabaseService.java +++ b/apps/testnav-ident-pool/src/main/java/no/nav/testnav/identpool/service/DatabaseService.java @@ -12,11 +12,8 @@ import org.springframework.stereotype.Service; import java.security.SecureRandom; -import java.util.ArrayList; -import java.util.HashMap; import java.util.HashSet; -import java.util.List; -import java.util.Objects; +import java.util.Random; import java.util.Set; import static java.util.Objects.nonNull; @@ -26,77 +23,58 @@ @RequiredArgsConstructor public class DatabaseService { + private static final Random RANDOM = new SecureRandom(); + private final IdentRepository identRepository; private final MapperFacade mapperFacade; public Set hentLedigeIdenterFraDatabase(HentIdenterRequest request) { - Set identEntities = new HashSet<>(); - - HentIdenterRequest availableIdentsRequest = mapperFacade.map(request, HentIdenterRequest.class); - - var firstPage = findPage(availableIdentsRequest, Rekvireringsstatus.LEDIG, 0); - var pageCache = new HashMap>(); - pageCache.put(0, firstPage); - - int totalPages = firstPage.getTotalPages(); - if (totalPages > 0) { - List usedIdents = new ArrayList<>(); - SecureRandom rand = new SecureRandom(); - for (var i = 0; i < request.getAntall(); i++) { - var randomPageNumber = rand.nextInt(totalPages); - pageCache.computeIfAbsent(randomPageNumber, k -> - findPage(availableIdentsRequest, Rekvireringsstatus.LEDIG, randomPageNumber)); - - List content = pageCache.get(randomPageNumber).getContent(); - for (Ident ident : content) { - if (!usedIdents.contains(ident.getPersonidentifikator())) { - usedIdents.add(ident.getPersonidentifikator()); - identEntities.add(ident); - break; - } - } - } + + var availableIdentsRequest = mapperFacade.map(request, HentIdenterRequest.class); + + var antall = getAntall(availableIdentsRequest); + + if (antall == 0) { + return new HashSet<>(); } - return identEntities; - } - private Page findPage(HentIdenterRequest request, Rekvireringsstatus rekvireringsstatus, int page) { + if (antall > request.getAntall()) { + var resultat = getPage(request, PageRequest.of(RANDOM.nextInt(antall/request.getAntall()), request.getAntall())); + return new HashSet<>(resultat.getContent()); + } - return identRepository.findAll( - rekvireringsstatus, request.getIdenttype(), request.getKjoenn(), request.getFoedtFoer(), - request.getFoedtEtter(), isTrue(request.getSyntetisk()), PageRequest.of(page, request.getAntall())); + return new HashSet<>( + getPage(request, PageRequest.of(0, request.getAntall())) + .getContent()); } - private int getAntall(HentIdenterRequest request, - Rekvireringsstatus rekvireringsstatus) { + private int getAntall(HentIdenterRequest request) { return nonNull(request.getKjoenn()) ? identRepository.countAllByRekvireringsstatusAndIdenttypeAndSyntetiskAndKjoennAndFoedselsdatoBetween( - rekvireringsstatus, request.getIdenttype(), + Rekvireringsstatus.LEDIG, request.getIdenttype(), isTrue(request.getSyntetisk()), request.getKjoenn(), request.getFoedtEtter(), request.getFoedtFoer()) : identRepository.countAllByRekvireringsstatusAndIdenttypeAndSyntetiskAndFoedselsdatoBetween( - rekvireringsstatus, request.getIdenttype(), + Rekvireringsstatus.LEDIG, request.getIdenttype(), isTrue(request.getSyntetisk()), request.getFoedtEtter(), request.getFoedtFoer()); } - private Page findPage(HentIdenterRequest request, - Rekvireringsstatus rekvireringsstatus, - Pageable page) { + private Page getPage(HentIdenterRequest request, Pageable page) { return nonNull(request.getKjoenn()) ? identRepository.findAllByRekvireringsstatusAndIdenttypeAndSyntetiskAndKjoennAndFoedselsdatoBetween( - rekvireringsstatus, request.getIdenttype(), + Rekvireringsstatus.LEDIG, request.getIdenttype(), isTrue(request.getSyntetisk()), request.getKjoenn(), request.getFoedtEtter(), request.getFoedtFoer(), page ) : identRepository.findAllByRekvireringsstatusAndIdenttypeAndSyntetiskAndFoedselsdatoBetween( - rekvireringsstatus, request.getIdenttype(), + Rekvireringsstatus.LEDIG, request.getIdenttype(), isTrue(request.getSyntetisk()), request.getFoedtEtter(), request.getFoedtFoer(), page ); diff --git a/apps/testnav-ident-pool/src/main/java/no/nav/testnav/identpool/service/IdentGeneratorService.java b/apps/testnav-ident-pool/src/main/java/no/nav/testnav/identpool/service/IdentGeneratorService.java index d17c7a5ae2d..3de97f20546 100644 --- a/apps/testnav-ident-pool/src/main/java/no/nav/testnav/identpool/service/IdentGeneratorService.java +++ b/apps/testnav-ident-pool/src/main/java/no/nav/testnav/identpool/service/IdentGeneratorService.java @@ -12,6 +12,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Random; import java.util.Set; import java.util.function.BiFunction; import java.util.function.Function; @@ -31,7 +32,7 @@ public class IdentGeneratorService { private static final int SYNTETISK = 4; - private static final SecureRandom random = new SecureRandom(); + private static final Random random = new SecureRandom(); private static String addSyntetiskIdentifier(String format) { return String.format("%s%1d%s", format.substring(0, 2), Integer.parseInt(format.substring(2, 3)) + SYNTETISK, format.substring(3)); @@ -67,15 +68,14 @@ public Set genererIdenter(HentIdenterRequest request, Set idente request.setFoedtFoer(request.getFoedtEtter().plusDays(1)); } - var identer = identerIIdentPool; - var antall = request.getAntall() + identer.size(); + var antall = request.getAntall() + identerIIdentPool.size(); var iteratorRange = (request.getKjoenn() == null) ? 1 : 2; var numberOfDates = toIntExact(ChronoUnit.DAYS.between(request.getFoedtEtter(), request.getFoedtFoer())); Function numberFormat = numberFormatter.getOrDefault(request.getIdenttype(), IdentGeneratorUtil::randomFormat); - while (identer.size() < antall) { + while (identerIIdentPool.size() < antall) { var birthdate = request.getFoedtEtter().plusDays(random.nextInt(numberOfDates)); var format = numberFormat.apply(birthdate); if (isTrue(request.getSyntetisk())) { @@ -83,29 +83,32 @@ public Set genererIdenter(HentIdenterRequest request, Set idente } var yearRange = getYearRange(birthdate); - var originalSize = identer.size(); + var originalSize = identerIIdentPool.size(); var genderNumber = getGenderNumber(yearRange, request.getKjoenn()); var startIndex = getStartIndex(yearRange.get(0), request.getKjoenn()); for (int i = startIndex; identerIIdentPool.size() == originalSize && i < genderNumber; i += iteratorRange) { String fnr = generateFnr(String.format(format, i)); if (fnr != null) { - identer.add(fnr); + identerIIdentPool.add(fnr); } } - for (int i = genderNumber; identer.size() == originalSize && i < yearRange.get(1); i += iteratorRange) { - String fnr = generateFnr(String.format(format, i)); + for (int i = genderNumber; identerIIdentPool.size() == originalSize && i < yearRange.get(1); i += iteratorRange) { + var fnr = generateFnr(String.format(format, i)); if (fnr != null) { - identer.add(fnr); + identerIIdentPool.add(fnr); } } if (identerIIdentPool.size() == originalSize) { - throw new IllegalArgumentException("Kan ikke finne ønsket antall fødselsnummer med angitte kriterier"); + break; } } - return identer; + if (identerIIdentPool.isEmpty()) { + throw new IllegalArgumentException("Finner ingen fødselsnummer med angitte kriterier"); + } + return identerIIdentPool; } private void validateDates(LocalDate foedtEtter, LocalDate foedtFoer) { diff --git a/apps/testnav-ident-pool/src/main/java/no/nav/testnav/identpool/service/PoolService.java b/apps/testnav-ident-pool/src/main/java/no/nav/testnav/identpool/service/PoolService.java index 12468574b74..3e3bcb94828 100644 --- a/apps/testnav-ident-pool/src/main/java/no/nav/testnav/identpool/service/PoolService.java +++ b/apps/testnav-ident-pool/src/main/java/no/nav/testnav/identpool/service/PoolService.java @@ -3,7 +3,6 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import no.nav.testnav.identpool.domain.Ident; -import no.nav.testnav.identpool.domain.Identtype; import no.nav.testnav.identpool.domain.Rekvireringsstatus; import no.nav.testnav.identpool.dto.TpsStatusDTO; import no.nav.testnav.identpool.exception.ForFaaLedigeIdenterException; @@ -14,7 +13,6 @@ import java.util.Iterator; import java.util.List; import java.util.Set; -import java.util.stream.Collectors; import static java.lang.String.format; import static java.time.format.DateTimeFormatter.ISO_DATE; @@ -69,7 +67,8 @@ public synchronized List allocateIdenter(HentIdenterRequest request) { if (missingIdentCount > 0) { - var tpsStatusDTOS = identerAvailService.generateAndCheckIdenter(request, ATTEMPT_OBTAIN); + var tpsStatusDTOS = identerAvailService.generateAndCheckIdenter(request, + isTrue(request.getSyntetisk()) ? ATTEMPT_OBTAIN * 6 : ATTEMPT_OBTAIN); List identerFraTps = tpsStatusDTOS.stream() .map(this::buildIdent) diff --git a/apps/testnav-ident-pool/src/main/resources/application-local.yml b/apps/testnav-ident-pool/src/main/resources/application-local.yml index dab53564868..69e57990421 100644 --- a/apps/testnav-ident-pool/src/main/resources/application-local.yml +++ b/apps/testnav-ident-pool/src/main/resources/application-local.yml @@ -1,27 +1,17 @@ spring: - cloud: - vault: - connection-timeout: 15000 - fail-fast: true - host: vault.adeo.no - port: 443 - read-timeout: 30000 + h2: + console: + enabled: true + path: /h2 datasource: - hikari: - maximum-pool-size: 3 - minimum-idle: 1 - url: jdbc:postgresql://localhost:5432/ident-pool-test - username: postgres - flyway: - baseline-on-migrate: true - enabled: true # Disabled by default as you should probably think twice before running Flyway-migrations - locations: classpath:/db/migration - jpa: - properties: - hibernate: - dialect: org.hibernate.dialect.PostgreSQLDialect - default-schema: public - showSql: true + url: jdbc:h2:mem:testdb + username: sa + password: + driverClassName: org.h2.Driver + sql: + init: + mode: always + data-locations: classpath:/db/dev/h2-default-config.sql consumers: tps: diff --git a/apps/testnav-ident-pool/src/main/resources/application-prod.yaml b/apps/testnav-ident-pool/src/main/resources/application-prod.yaml index 1e3bd334c34..6ca2a2eedec 100644 --- a/apps/testnav-ident-pool/src/main/resources/application-prod.yaml +++ b/apps/testnav-ident-pool/src/main/resources/application-prod.yaml @@ -1,8 +1,13 @@ spring: + oauth2: + tokenx: + issuer-uri: ${TOKEN_X_ISSUER} + jwk-set-uri: ${TOKEN_X_JWKS_URI} + accepted-audience: ${TOKEN_X_CLIENT_ID} datasource: url: jdbc:postgresql://${NAIS_DATABASE_TESTNAV_IDENTPOOL_TESTNAV_IDENTPOOL_HOST}:${NAIS_DATABASE_TESTNAV_IDENTPOOL_TESTNAV_IDENTPOOL_PORT}/${NAIS_DATABASE_TESTNAV_IDENTPOOL_TESTNAV_IDENTPOOL_DATABASE}?user=${NAIS_DATABASE_TESTNAV_IDENTPOOL_TESTNAV_IDENTPOOL_USERNAME}&password=${NAIS_DATABASE_TESTNAV_IDENTPOOL_TESTNAV_IDENTPOOL_PASSWORD} driverClassName: org.postgresql.Driver hikari: maximum-pool-size: 3 - minimum-idle: 1 \ No newline at end of file + minimum-idle: 1 diff --git a/apps/testnav-ident-pool/src/main/resources/application.yaml b/apps/testnav-ident-pool/src/main/resources/application.yaml index f411431ba17..1aa6e5379e4 100644 --- a/apps/testnav-ident-pool/src/main/resources/application.yaml +++ b/apps/testnav-ident-pool/src/main/resources/application.yaml @@ -45,11 +45,6 @@ spring: issuer-uri: https://login.microsoftonline.com/62366534-1ec3-4962-8869-9b5535279d0b/v2.0 #The client_id of this application accepted-audience: ${azure.app.client.id}, api://${azure.app.client.id} - tokenx: - issuer-uri: ${TOKEN_X_ISSUER} - jwk-set-uri: ${TOKEN_X_JWKS_URI} - accepted-audience: ${TOKEN_X_CLIENT_ID} - springdoc: swagger-ui: diff --git a/apps/testnav-ident-pool/src/main/resources/db/dev/h2-default-config.sql b/apps/testnav-ident-pool/src/main/resources/db/dev/h2-default-config.sql new file mode 100644 index 00000000000..818c31b1025 --- /dev/null +++ b/apps/testnav-ident-pool/src/main/resources/db/dev/h2-default-config.sql @@ -0,0 +1,34 @@ + +insert into personidentifikator values(1,'FNR','13048226064','I_BRUK',false,'1982-04-13','KVINNE','TPS',false); +insert into personidentifikator values(2,'FNR','03058225613','I_BRUK',false,'1982-05-03','KVINNE','TPS',false); +insert into personidentifikator values(3,'FNR','25078225966','I_BRUK',false,'1982-07-25','MANN','TPS',false); +insert into personidentifikator values(4,'FNR','16118225841','I_BRUK',false,'1982-11-16','KVINNE','TPS',false); +insert into personidentifikator values(5,'FNR','30128225516','I_BRUK',false,'1982-12-30','MANN','TPS',false); +insert into personidentifikator values(6,'FNR','03128225772','I_BRUK',false,'1982-12-03','MANN','TPS',false); +insert into personidentifikator values(7,'FNR','22098225777','I_BRUK',false,'1982-09-22','MANN','TPS',false); +insert into personidentifikator values(8,'FNR','26028225864','I_BRUK',false,'1982-02-26','KVINNE','TPS',false); +insert into personidentifikator values(9,'FNR','09048225990','I_BRUK',false,'1982-04-09','MANN','TPS',false); +insert into personidentifikator values(10,'FNR','14496205422','LEDIG',false,'1962-09-14','KVINNE',null,true); +insert into personidentifikator values(11,'FNR','14496208650','LEDIG',false,'1962-09-14','KVINNE',null,true); +insert into personidentifikator values(12,'FNR','14496201087','LEDIG',false,'1962-09-14','KVINNE',null,true); +insert into personidentifikator values(13,'FNR','14496209444','LEDIG',false,'1962-09-14','KVINNE',null,true); +insert into personidentifikator values(14,'FNR','14496205260','LEDIG',false,'1962-09-14','KVINNE',null,true); +insert into personidentifikator values(15,'FNR','14496209282','LEDIG',false,'1962-09-14','KVINNE',null,true); +insert into personidentifikator values(16,'FNR','14496200889','LEDIG',false,'1962-09-14','KVINNE',null,true); +insert into personidentifikator values(17,'FNR','14496201834','LEDIG',false,'1962-09-14','KVINNE',null,true); +insert into personidentifikator values(18,'FNR','14496202628','LEDIG',false,'1962-09-14','KVINNE',null,true); +insert into personidentifikator values(19,'FNR','14496206801','LEDIG',false,'1962-09-14','KVINNE',null,true); +insert into personidentifikator values(20,'FNR','14496201672','LEDIG',false,'1962-09-14','KVINNE',null,true); +insert into personidentifikator values(21,'FNR','14496204205','LEDIG',false,'1962-09-14','KVINNE',null,true); +insert into personidentifikator values(22,'FNR','14496203411','LEDIG',false,'1962-09-14','KVINNE',null,true); +insert into personidentifikator values(23,'FNR','14496202466','LEDIG',false,'1962-09-14','KVINNE',null,true); +insert into personidentifikator values(24,'FNR','14496205856','LEDIG',false,'1962-09-14','KVINNE',null,true); +insert into personidentifikator values(25,'FNR','14496204043','LEDIG',false,'1962-09-14','KVINNE',null,true); +insert into personidentifikator values(26,'FNR','14496208227','LEDIG',false,'1962-09-14','KVINNE',null,true); +insert into personidentifikator values(27,'FNR','14496206488','LEDIG',false,'1962-09-14','KVINNE',null,true); +insert into personidentifikator values(28,'FNR','14496203098','LEDIG',false,'1962-09-14','KVINNE',null,true); +insert into personidentifikator values(29,'FNR','14496205694','LEDIG',false,'1962-09-14','KVINNE',null,true); +insert into personidentifikator values(30,'FNR','14496207433','LEDIG',false,'1962-09-14','KVINNE',null,true); +insert into personidentifikator values(31,'FNR','14496209010','LEDIG',false,'1962-09-14','KVINNE',null,true); + +commit; \ No newline at end of file