diff --git a/frontend/arena-adapter-manager/src/core/api.tsx b/frontend/arena-adapter-manager/src/core/api.tsx index c73e6fac9d..ea7856ffe7 100644 --- a/frontend/arena-adapter-manager/src/core/api.tsx +++ b/frontend/arena-adapter-manager/src/core/api.tsx @@ -13,8 +13,13 @@ export class ApiError extends Error { } } -export const getTopics = () => - fetch("/mulighetsrommet-arena-adapter/topics", { +export enum ApiBase { + ARENA_ADAPTER = "/mulighetsrommet-arena-adapter", + MR_API = "/mulighetsrommet-api/api/internal/maam", +} + +export const getTopics = (base: ApiBase) => + fetch(`${base}/topics`, { method: "GET", headers: getDefaultHeaders(), }) @@ -29,8 +34,8 @@ export const getArenaTables = () => .then(parseJson) .catch((error) => toastError("Klarte ikke laste ArenaTables", error)); -export const putTopicRunningState = (topics: Topic[]) => - fetch("/mulighetsrommet-arena-adapter/topics", { +export const putTopicRunningState = (base: ApiBase, topics: Topic[]) => + fetch(`${base}/topics`, { method: "PUT", headers: { ...getDefaultHeaders(), @@ -107,8 +112,8 @@ export type MrApiTask = | "initial-load-mulighetsrommet-tiltaksgjennomforinger" | "sync-navansatte"; -export const runTask = (task: MrApiTask) => - fetch(`/mulighetsrommet-api/api/v1/internal/tasks/${task}`, { +export const runTask = (base: ApiBase, task: MrApiTask) => + fetch(`${base}/tasks/${task}`, { method: "POST", headers: getDefaultHeaders(), }) diff --git a/frontend/arena-adapter-manager/src/core/hooks.ts b/frontend/arena-adapter-manager/src/core/hooks.ts index 75f510380b..c19c3d483c 100644 --- a/frontend/arena-adapter-manager/src/core/hooks.ts +++ b/frontend/arena-adapter-manager/src/core/hooks.ts @@ -1,18 +1,18 @@ import { useEffect, useState } from "react"; import { Topic } from "../domain"; -import { getArenaTables, getTopics } from "./api"; +import { ApiBase, getArenaTables, getTopics } from "./api"; -export function useTopics() { +export function useTopics(base: ApiBase) { const [topics, setTopics] = useState([]); const [isLoading, setIsLoading] = useState(true); useEffect(() => { const fetchTopics = async () => { - const t = await getTopics(); + const t = await getTopics(base); setTopics(t ?? []); setIsLoading(false); }; fetchTopics(); - }, []); + }, [base]); return { topics, isTopicsLoading: isLoading, setTopics }; } diff --git a/frontend/arena-adapter-manager/src/pages/MrApiManagement.tsx b/frontend/arena-adapter-manager/src/pages/MrApiManagement.tsx index 7aaffbcbb7..4e7d537274 100644 --- a/frontend/arena-adapter-manager/src/pages/MrApiManagement.tsx +++ b/frontend/arena-adapter-manager/src/pages/MrApiManagement.tsx @@ -1,14 +1,19 @@ -import { Box, Heading, VStack, Link } from "@chakra-ui/react"; +import { Box, Heading, Link, VStack } from "@chakra-ui/react"; import { UpdateVirksomhet } from "../sections/UpdateVirksomhet"; import { RunTask } from "../sections/RunTask"; +import TopicOverview from "../sections/TopicOverview.tsx"; +import { ApiBase } from "../core/api.tsx"; export function MrApiManagement() { return ( mr-api + + - + +

Genererer en rapport med alle valideringsfeil på gjennomføringer og laster rapporten opp til en @@ -19,16 +24,19 @@ export function MrApiManagement() { migrere.

- + + Starter en initial load av alle gjennomføringer med opphav = MR_ADMIN_FLATE. - + +

Starter en initial load av alle gjennomføringer i API.

Dette inkluderer både gjennomføringer med opphav = ARENA og opphav = MR_ADMIN_FLATE.

- + + Synkoniserer NAV-ansatte fra relevante AD-grupper.
diff --git a/frontend/arena-adapter-manager/src/pages/MrArenaAdapterManagement.tsx b/frontend/arena-adapter-manager/src/pages/MrArenaAdapterManagement.tsx index 00d243e8cc..28b47b6025 100644 --- a/frontend/arena-adapter-manager/src/pages/MrArenaAdapterManagement.tsx +++ b/frontend/arena-adapter-manager/src/pages/MrArenaAdapterManagement.tsx @@ -3,13 +3,14 @@ import ReplayEvents from "../sections/ReplayEvents"; import TopicOverview from "../sections/TopicOverview"; import ReplayEvent from "../sections/ReplayEvent"; import DeleteEvents from "../sections/DeleteEvents"; +import { ApiBase } from "../core/api.tsx"; export function MrArenaAdapterManagement() { return ( mr-arena-adapter - + diff --git a/frontend/arena-adapter-manager/src/sections/RunTask.tsx b/frontend/arena-adapter-manager/src/sections/RunTask.tsx index 1ef06e7fee..e2a8e952be 100644 --- a/frontend/arena-adapter-manager/src/sections/RunTask.tsx +++ b/frontend/arena-adapter-manager/src/sections/RunTask.tsx @@ -1,9 +1,10 @@ import { Button } from "@chakra-ui/react"; import { ReactNode, useState } from "react"; import { Section } from "../components/Section"; -import { MrApiTask, runTask } from "../core/api"; +import { ApiBase, MrApiTask, runTask } from "../core/api"; interface Props { + base: ApiBase; task: MrApiTask; children: ReactNode; } @@ -13,7 +14,7 @@ export function RunTask(props: Props) { const executeTask = async () => { setLoading(true); - await runTask(props.task); + await runTask(props.base, props.task); setLoading(false); }; diff --git a/frontend/arena-adapter-manager/src/sections/TopicOverview.tsx b/frontend/arena-adapter-manager/src/sections/TopicOverview.tsx index e3158f3b3e..1529e993a2 100644 --- a/frontend/arena-adapter-manager/src/sections/TopicOverview.tsx +++ b/frontend/arena-adapter-manager/src/sections/TopicOverview.tsx @@ -13,24 +13,27 @@ import { } from "@chakra-ui/react"; import { ChangeEvent, useState } from "react"; import { Section } from "../components/Section"; -import { putTopicRunningState } from "../core/api"; +import { ApiBase, putTopicRunningState } from "../core/api"; import { useTopics } from "../core/hooks"; -function TopicOverview() { - const { topics, isTopicsLoading, setTopics } = useTopics(); +interface Props { + base: ApiBase; +} + +function TopicOverview({ base }: Props) { + const { topics, isTopicsLoading, setTopics } = useTopics(base); const [isSaveLoading, setIsSaveLoading] = useState(false); const setRunningState = (event: ChangeEvent) => { const changedTopics = [...topics]; - changedTopics[ - changedTopics.map((t) => t.topic).indexOf(event.currentTarget.name) - ].running = event.currentTarget.checked; + changedTopics[changedTopics.map((t) => t.topic).indexOf(event.currentTarget.name)].running = + event.currentTarget.checked; setTopics(changedTopics); }; const saveRunningState = async () => { setIsSaveLoading(true); - await putTopicRunningState(topics); + await putTopicRunningState(base, topics); setIsSaveLoading(false); }; @@ -74,11 +77,7 @@ function TopicOverview() { - diff --git a/mulighetsrommet-api/src/main/kotlin/no/nav/mulighetsrommet/api/Application.kt b/mulighetsrommet-api/src/main/kotlin/no/nav/mulighetsrommet/api/Application.kt index 5853d6ce1a..b9d9412c79 100644 --- a/mulighetsrommet-api/src/main/kotlin/no/nav/mulighetsrommet/api/Application.kt +++ b/mulighetsrommet-api/src/main/kotlin/no/nav/mulighetsrommet/api/Application.kt @@ -9,7 +9,7 @@ import no.nav.mulighetsrommet.api.plugins.* import no.nav.mulighetsrommet.api.plugins.AuthProvider import no.nav.mulighetsrommet.api.routes.featuretoggles.featureTogglesRoute import no.nav.mulighetsrommet.api.routes.internal.frontendLoggerRoutes -import no.nav.mulighetsrommet.api.routes.internal.tasks +import no.nav.mulighetsrommet.api.routes.internal.maamRoutes import no.nav.mulighetsrommet.api.routes.v1.* import no.nav.mulighetsrommet.database.Database import no.nav.mulighetsrommet.hoplite.loadConfiguration @@ -42,7 +42,7 @@ fun Application.configure(config: AppConfig) { routing { authenticate(AuthProvider.AZURE_AD_TEAM_MULIGHETSROMMET.name) { - tasks() + maamRoutes() } authenticate(AuthProvider.AZURE_AD_NAV_IDENT.name, AuthProvider.AZURE_AD_TILTAKSADMINISTRASJON_GENERELL.name) { diff --git a/mulighetsrommet-api/src/main/kotlin/no/nav/mulighetsrommet/api/routes/internal/MaamRoutes.kt b/mulighetsrommet-api/src/main/kotlin/no/nav/mulighetsrommet/api/routes/internal/MaamRoutes.kt new file mode 100644 index 0000000000..69fb256658 --- /dev/null +++ b/mulighetsrommet-api/src/main/kotlin/no/nav/mulighetsrommet/api/routes/internal/MaamRoutes.kt @@ -0,0 +1,74 @@ +package no.nav.mulighetsrommet.api.routes.internal + +import io.ktor.http.* +import io.ktor.server.application.* +import io.ktor.server.request.* +import io.ktor.server.response.* +import io.ktor.server.routing.* +import kotlinx.serialization.Serializable +import no.nav.mulighetsrommet.api.tasks.GenerateValidationReport +import no.nav.mulighetsrommet.api.tasks.InitialLoadTiltaksgjennomforinger +import no.nav.mulighetsrommet.api.tasks.InitialLoadTiltaksgjennomforingerInput +import no.nav.mulighetsrommet.api.tasks.SynchronizeNavAnsatte +import no.nav.mulighetsrommet.domain.constants.ArenaMigrering +import no.nav.mulighetsrommet.domain.serializers.UUIDSerializer +import no.nav.mulighetsrommet.kafka.KafkaConsumerOrchestrator +import no.nav.mulighetsrommet.kafka.Topic +import org.koin.ktor.ext.inject +import java.util.* + +fun Route.maamRoutes() { + route("/api/internal/maam") { + route("/tasks") { + val generateValidationReport: GenerateValidationReport by inject() + val initialLoadTiltaksgjennomforinger: InitialLoadTiltaksgjennomforinger by inject() + val synchronizeNavAnsatte: SynchronizeNavAnsatte by inject() + + post("generate-validation-report") { + val taskId = generateValidationReport.schedule() + + call.respond(HttpStatusCode.Accepted, ScheduleTaskResponse(id = taskId)) + } + + post("initial-load-tiltaksgjennomforinger") { + val input = InitialLoadTiltaksgjennomforingerInput(opphav = null) + val taskId = initialLoadTiltaksgjennomforinger.schedule(input) + + call.respond(HttpStatusCode.Accepted, ScheduleTaskResponse(id = taskId)) + } + + post("initial-load-mulighetsrommet-tiltaksgjennomforinger") { + val input = InitialLoadTiltaksgjennomforingerInput(opphav = ArenaMigrering.Opphav.MR_ADMIN_FLATE) + val taskId = initialLoadTiltaksgjennomforinger.schedule(input) + + call.respond(HttpStatusCode.Accepted, ScheduleTaskResponse(id = taskId)) + } + + post("sync-navansatte") { + val taskId = synchronizeNavAnsatte.schedule() + call.respond(HttpStatusCode.Accepted, ScheduleTaskResponse(id = taskId)) + } + } + + route("/topics") { + val kafka: KafkaConsumerOrchestrator by inject() + + get { + val topics = kafka.getTopics() + call.respond(topics) + } + + put { + val topics = call.receive>() + kafka.updateRunningTopics(topics) + call.respond(HttpStatusCode.OK) + } + } + } +} + +@Serializable +data class ScheduleTaskResponse( + @Serializable(with = UUIDSerializer::class) + val id: UUID, +) diff --git a/mulighetsrommet-api/src/main/kotlin/no/nav/mulighetsrommet/api/routes/internal/Tasks.kt b/mulighetsrommet-api/src/main/kotlin/no/nav/mulighetsrommet/api/routes/internal/Tasks.kt deleted file mode 100644 index 636e543703..0000000000 --- a/mulighetsrommet-api/src/main/kotlin/no/nav/mulighetsrommet/api/routes/internal/Tasks.kt +++ /dev/null @@ -1,54 +0,0 @@ -package no.nav.mulighetsrommet.api.routes.internal - -import io.ktor.http.* -import io.ktor.server.application.* -import io.ktor.server.response.* -import io.ktor.server.routing.* -import kotlinx.serialization.Serializable -import no.nav.mulighetsrommet.api.tasks.GenerateValidationReport -import no.nav.mulighetsrommet.api.tasks.InitialLoadTiltaksgjennomforinger -import no.nav.mulighetsrommet.api.tasks.InitialLoadTiltaksgjennomforingerInput -import no.nav.mulighetsrommet.api.tasks.SynchronizeNavAnsatte -import no.nav.mulighetsrommet.domain.constants.ArenaMigrering -import no.nav.mulighetsrommet.domain.serializers.UUIDSerializer -import org.koin.ktor.ext.inject -import java.util.* - -fun Route.tasks() { - val generateValidationReport: GenerateValidationReport by inject() - val initialLoadTiltaksgjennomforinger: InitialLoadTiltaksgjennomforinger by inject() - val synchronizeNavAnsatte: SynchronizeNavAnsatte by inject() - - route("api/v1/internal/tasks") { - post("generate-validation-report") { - val taskId = generateValidationReport.schedule() - - call.respond(HttpStatusCode.Accepted, ScheduleTaskResponse(id = taskId)) - } - - post("initial-load-tiltaksgjennomforinger") { - val input = InitialLoadTiltaksgjennomforingerInput(opphav = null) - val taskId = initialLoadTiltaksgjennomforinger.schedule(input) - - call.respond(HttpStatusCode.Accepted, ScheduleTaskResponse(id = taskId)) - } - - post("initial-load-mulighetsrommet-tiltaksgjennomforinger") { - val input = InitialLoadTiltaksgjennomforingerInput(opphav = ArenaMigrering.Opphav.MR_ADMIN_FLATE) - val taskId = initialLoadTiltaksgjennomforinger.schedule(input) - - call.respond(HttpStatusCode.Accepted, ScheduleTaskResponse(id = taskId)) - } - - post("sync-navansatte") { - val taskId = synchronizeNavAnsatte.schedule() - call.respond(HttpStatusCode.Accepted, ScheduleTaskResponse(id = taskId)) - } - } -} - -@Serializable -data class ScheduleTaskResponse( - @Serializable(with = UUIDSerializer::class) - val id: UUID, -)