-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1279 from navikt/innsyn
Innsyn
- Loading branch information
Showing
24 changed files
with
1,156 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
package no.nav.klage.innsyn | ||
|
||
class FileNotFoundInSafException(override val message: String = "Could not find document info in SAF"): RuntimeException() |
102 changes: 102 additions & 0 deletions
102
src/main/kotlin/no/nav/klage/innsyn/api/controller/InnsynController.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
package no.nav.klage.innsyn.api.controller | ||
|
||
import io.swagger.v3.oas.annotations.Operation | ||
import io.swagger.v3.oas.annotations.security.SecurityRequirement | ||
import io.swagger.v3.oas.annotations.tags.Tag | ||
import no.nav.klage.innsyn.api.view.InnsynResponse | ||
import no.nav.klage.innsyn.service.InnsynService | ||
import no.nav.klage.oppgave.config.SecurityConfiguration | ||
import no.nav.klage.oppgave.util.TokenUtil | ||
import no.nav.klage.oppgave.util.getLogger | ||
import no.nav.klage.oppgave.util.getSecureLogger | ||
import no.nav.klage.oppgave.util.logMethodDetails | ||
import no.nav.security.token.support.core.api.ProtectedWithClaims | ||
import org.springframework.core.io.FileSystemResource | ||
import org.springframework.core.io.Resource | ||
import org.springframework.http.HttpHeaders | ||
import org.springframework.http.MediaType | ||
import org.springframework.http.ResponseEntity | ||
import org.springframework.web.bind.annotation.GetMapping | ||
import org.springframework.web.bind.annotation.PathVariable | ||
import org.springframework.web.bind.annotation.RequestMapping | ||
import org.springframework.web.bind.annotation.RestController | ||
import java.io.FileInputStream | ||
import java.io.InputStream | ||
import java.nio.file.Files | ||
|
||
@RestController | ||
@Tag( | ||
name = "kabal-innsyn", | ||
description = "api for innsyn i brukeres saker" | ||
) | ||
|
||
@ProtectedWithClaims(issuer = SecurityConfiguration.TOKEN_X, claimMap = ["acr=Level4"]) | ||
@RequestMapping("api/innsyn") | ||
@SecurityRequirement(name = "bearerAuth") | ||
class InnsynController( | ||
private val innsynService: InnsynService, | ||
private val tokenUtil: TokenUtil, | ||
) { | ||
|
||
companion object { | ||
@Suppress("JAVA_CLASS_ON_COMPANION") | ||
private val logger = getLogger(javaClass.enclosingClass) | ||
private val secureLogger = getSecureLogger() | ||
} | ||
|
||
@Operation( | ||
summary = "Hent en brukers saker", | ||
description = "Hent en brukers saker, basert på brukerens ident hentet fra token" | ||
) | ||
@GetMapping("/saker") | ||
fun getSaker(): InnsynResponse { | ||
val identFromToken = tokenUtil.getSubjectFromTokenXToken() | ||
logMethodDetails( | ||
methodName = ::getSaker.name, | ||
innloggetIdent = identFromToken, | ||
logger = secureLogger, | ||
) | ||
|
||
return innsynService.getSakerForBruker(fnr = identFromToken) | ||
} | ||
|
||
@Operation( | ||
summary = "Hent et gitt dokument fra arkivet", | ||
description = "Henter alle dokumenter på en journalpost. Må være ført på innlogget bruker." | ||
) | ||
@GetMapping("/documents/{journalpostId}") | ||
fun getDocument( | ||
@PathVariable("journalpostId") journalpostId: String, | ||
): ResponseEntity<Resource> { | ||
val identFromToken = tokenUtil.getSubjectFromTokenXToken() | ||
logMethodDetails( | ||
methodName = ::getDocument.name, | ||
innloggetIdent = identFromToken, | ||
logger = secureLogger, | ||
) | ||
|
||
//TODO: Samkjør dette med metoden som brukes for merging av dokument inne i Kabal | ||
val (pathToMergedDocument, title) = innsynService.getJournalpostPdf(journalpostId = journalpostId) | ||
val responseHeaders = HttpHeaders() | ||
responseHeaders.contentType = MediaType.APPLICATION_PDF | ||
responseHeaders.add(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=\"$title.pdf\"") | ||
|
||
return ResponseEntity.ok() | ||
.headers(responseHeaders) | ||
.contentLength(pathToMergedDocument.toFile().length()) | ||
.body( | ||
object : FileSystemResource(pathToMergedDocument) { | ||
override fun getInputStream(): InputStream { | ||
return object : FileInputStream(pathToMergedDocument.toFile()) { | ||
override fun close() { | ||
super.close() | ||
//Override to do this after client has downloaded file | ||
Files.delete(file.toPath()) | ||
} | ||
} | ||
} | ||
}) | ||
|
||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package no.nav.klage.innsyn.api.view | ||
|
||
import java.time.LocalDate | ||
import java.time.LocalDateTime | ||
|
||
|
||
data class InnsynResponse( | ||
val saker: List<SakView>, | ||
// val active: List<SakView>, | ||
// val finished: List<SakView>, | ||
) | ||
|
||
data class SakView( | ||
val id: String, //created using fagsystemId and saksnummer | ||
val saksnummer: String, | ||
val ytelseId: String, | ||
val innsendingsytelseId: String, | ||
val events: List<Event>, | ||
val varsletBehandlingstid: VarsletBehandlingstid?, | ||
val mottattKlageinstans: LocalDate, | ||
) { | ||
data class Event( | ||
val type: EventType, | ||
val date: LocalDateTime, | ||
val relevantJournalpostId: String?, | ||
) { | ||
enum class EventType { | ||
KLAGE_MOTTATT_VEDTAKSINSTANS, | ||
KLAGE_MOTTATT_KLAGEINSTANS, | ||
KLAGE_AVSLUTTET_I_KLAGEINSTANS, | ||
ANKE_MOTTATT_KLAGEINSTANS, | ||
ANKE_SENDT_TRYGDERETTEN, | ||
ANKE_KJENNELSE_MOTTATT_FRA_TRYGDERETTEN, | ||
ANKE_AVSLUTTET_I_TRYGDERETTEN, //Do we need this, when we have ANKE_KJENNELSE_MOTTATT_FRA_TRYGDERETTEN? | ||
ANKE_AVSLUTTET_I_KLAGEINSTANS, | ||
} | ||
} | ||
|
||
data class VarsletBehandlingstid( | ||
val varsletBehandlingstidUnits: Int, | ||
val varsletBehandlingstidUnitTypeId: String, | ||
val varsletFrist: LocalDate, | ||
) | ||
} |
35 changes: 35 additions & 0 deletions
35
src/main/kotlin/no/nav/klage/innsyn/client/safselvbetjening/GetJournalpostByIdRequest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package no.nav.klage.innsyn.client.safselvbetjening | ||
|
||
|
||
data class GetJournalpostByIdGraphqlQuery( | ||
val query: String, | ||
val variables: GetJournalpostByIdVariables | ||
) | ||
|
||
data class GetJournalpostByIdVariables( | ||
val journalpostId: String | ||
) | ||
|
||
fun getJournalpostByIdQuery(journalpostId: String): GetJournalpostByIdGraphqlQuery { | ||
val query = GraphqlQuery::class.java.getResource("/safselvbetjening/getJournalpostById.graphql").readText() | ||
.replace("[\n\r]", "") | ||
return GetJournalpostByIdGraphqlQuery( | ||
query = query, | ||
variables = GetJournalpostByIdVariables(journalpostId = journalpostId) | ||
) | ||
} | ||
|
||
data class GraphqlQuery( | ||
val query: String, | ||
val variables: Variables | ||
) | ||
|
||
data class Variables( | ||
val ident: String, | ||
val navnHistorikk: Boolean, | ||
val grupper: List<IdentGruppe> = listOf(IdentGruppe.AKTORID, IdentGruppe.FOLKEREGISTERIDENT, IdentGruppe.NPID) | ||
) | ||
|
||
enum class IdentGruppe { | ||
FOLKEREGISTERIDENT, NPID, AKTORID | ||
} |
32 changes: 32 additions & 0 deletions
32
src/main/kotlin/no/nav/klage/innsyn/client/safselvbetjening/GetJournalpostByIdResponse.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package no.nav.klage.innsyn.client.safselvbetjening | ||
|
||
data class GetJournalpostByIdResponse(val data: GetJournalpostById?, val errors: List<PdlError>?) | ||
|
||
data class GetJournalpostById(val journalpostById: JournalpostById?) | ||
|
||
data class JournalpostById( | ||
val journalpostId: String, | ||
val tittel: String, | ||
val dokumenter: List<Dokument>, | ||
) | ||
|
||
data class Dokument( | ||
val dokumentInfoId: String, | ||
) | ||
|
||
data class PdlError( | ||
val message: String, | ||
val locations: List<PdlErrorLocation>, | ||
val path: List<String>?, | ||
val extensions: PdlErrorExtension | ||
) | ||
|
||
data class PdlErrorLocation( | ||
val line: Int?, | ||
val column: Int? | ||
) | ||
|
||
data class PdlErrorExtension( | ||
val code: String?, | ||
val classification: String | ||
) |
70 changes: 70 additions & 0 deletions
70
src/main/kotlin/no/nav/klage/innsyn/client/safselvbetjening/SafSelvbetjeningGraphQlClient.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package no.nav.klage.innsyn.client.safselvbetjening | ||
|
||
import no.nav.klage.oppgave.util.TokenUtil | ||
import no.nav.klage.oppgave.util.getLogger | ||
import no.nav.klage.oppgave.util.getSecureLogger | ||
import org.slf4j.Logger | ||
import org.springframework.http.HttpHeaders | ||
import org.springframework.http.HttpStatusCode | ||
import org.springframework.retry.annotation.Retryable | ||
import org.springframework.stereotype.Component | ||
import org.springframework.web.reactive.function.client.ClientResponse | ||
import org.springframework.web.reactive.function.client.WebClient | ||
import org.springframework.web.reactive.function.client.bodyToMono | ||
import reactor.core.publisher.Mono | ||
|
||
@Component | ||
class SafSelvbetjeningGraphQlClient( | ||
private val safSelvbetjeningWebClient: WebClient, | ||
private val tokenUtil: TokenUtil | ||
) { | ||
|
||
companion object { | ||
@Suppress("JAVA_CLASS_ON_COMPANION") | ||
private val logger = getLogger(javaClass.enclosingClass) | ||
private val secureLogger = getSecureLogger() | ||
} | ||
|
||
@Retryable | ||
fun getJournalpostById( | ||
journalpostId: String, | ||
): GetJournalpostByIdResponse { | ||
val response = runWithTimingAndLogging { | ||
safSelvbetjeningWebClient.post() | ||
.uri("graphql") | ||
.header( | ||
HttpHeaders.AUTHORIZATION, | ||
"Bearer ${tokenUtil.getOnBehalfOfTokenWithSafSelvbetjeningScope()}" | ||
) | ||
.bodyValue(getJournalpostByIdQuery(journalpostId = journalpostId)) | ||
.retrieve() | ||
.onStatus(HttpStatusCode::isError) { response -> | ||
logErrorResponse(response, ::getJournalpostById.name, secureLogger) | ||
} | ||
.bodyToMono<GetJournalpostByIdResponse>() | ||
.block() ?: throw RuntimeException("No connection to safselvbetjening") | ||
} | ||
|
||
return response | ||
} | ||
|
||
fun <T> runWithTimingAndLogging(block: () -> T): T { | ||
val start = System.currentTimeMillis() | ||
try { | ||
return block.invoke() | ||
} finally { | ||
val end = System.currentTimeMillis() | ||
logger.debug("Time it took to call saf: ${end - start} millis") | ||
} | ||
} | ||
|
||
fun logErrorResponse(response: ClientResponse, functionName: String, logger: Logger): Mono<RuntimeException> { | ||
return response.bodyToMono(String::class.java).map { | ||
val errorString = | ||
"Got ${response.statusCode()} when requesting $functionName - response body: '$it'" | ||
logger.error(errorString) | ||
RuntimeException(errorString) | ||
} | ||
} | ||
|
||
} |
Oops, something went wrong.