Skip to content

Commit

Permalink
Modul med metrikker gir mulighet til å telle antall ganger ett endepu…
Browse files Browse the repository at this point in the history
…nkt har blitt kallt
  • Loading branch information
stigebil committed Apr 18, 2024
1 parent a01cd9d commit e3e35e4
Show file tree
Hide file tree
Showing 14 changed files with 314 additions and 10 deletions.
2 changes: 1 addition & 1 deletion http-client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
<artifactId>kotlin-stdlib</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
Expand Down
2 changes: 1 addition & 1 deletion leader/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
<artifactId>kotlin-stdlib</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
Expand Down
114 changes: 114 additions & 0 deletions metrikker/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>no.nav.familie.felles</groupId>
<artifactId>felles</artifactId>
<version>${revision}${sha1}${changelist}</version>
</parent>

<artifactId>metrikker</artifactId>
<version>${revision}${sha1}${changelist}</version>
<name>Felles - Metrikker</name>
<description>Felles kode for metrikker</description>
<packaging>jar</packaging>

<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>${kotlin.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
</dependency>


<!-- Test -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.mockk</groupId>
<artifactId>mockk-jvm</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>testCompile</id>
<phase>test-compile</phase>
<goals>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package no.nav.familie.metrikker

import io.micrometer.core.instrument.Counter
import io.micrometer.core.instrument.Metrics
import jakarta.annotation.PostConstruct
import org.springframework.beans.factory.annotation.Value
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
import org.springframework.context.ApplicationContext
import org.springframework.stereotype.Component
import org.springframework.web.method.HandlerMethod
import org.springframework.web.servlet.mvc.method.RequestMappingInfo
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping

@Component
@ConditionalOnProperty("familie.tellAPIEndepunkterIBruk")
class TellAPIEndepunkterIBrukInitialiserer(
@Value("\${NAIS_APP_NAME}") private val applicationName: String,
private val applicationContext: ApplicationContext,
) {
init {
metrikker.clear()
}

@PostConstruct
fun populerMapMedCountersForRestEndepunkt() {
val requestMappingHandlerMapping: RequestMappingHandlerMapping =
applicationContext
.getBean("requestMappingHandlerMapping", RequestMappingHandlerMapping::class.java)
val requestMappings: Map<RequestMappingInfo, HandlerMethod> = requestMappingHandlerMapping.handlerMethods

requestMappings.forEach { (info, handler) ->
info.patternValues.forEach { path ->
if (path.startsWith("/api")) {
val metrikknavn = "$applicationName.${info.methodsCondition}$path".tilMetrikknavn()
val key = "${info.methodsCondition}$path"
metrikker.put(
key,
Metrics.counter(
metrikknavn,
METRIKK_TAG_TYPE,
"endepunkt",
METRIKK_PATH_TYPE,
path,
METRIKK_REQUEST_METODE_TYPE,
"${info.methodsCondition}",
),
)
}
}
}
}

private fun String.tilMetrikknavn() =
this
.replace("[", "")
.replace("]", "")
.replace("{", "")
.replace("}", "")
.replace("/", ".")
.replace("_", ".")

companion object {
private val metrikker = mutableMapOf<String, Counter>()
val metrikkerForEndepunkter
get() = metrikker.toMap()

private const val METRIKK_TAG_TYPE = "type"
private const val METRIKK_PATH_TYPE = "path"
private const val METRIKK_REQUEST_METODE_TYPE = "requestMetode"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package no.nav.familie.metrikker

import jakarta.servlet.http.HttpServletRequest
import jakarta.servlet.http.HttpServletResponse
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
import org.springframework.stereotype.Component
import org.springframework.web.servlet.AsyncHandlerInterceptor
import org.springframework.web.servlet.HandlerMapping

/**
* Sett property familie.tellAPIEndepunkterIBruk: true i application.yaml for å skru
* på metrikker for hvor mange ganger et endepunkt har blitt kalt
*/
@Component
@ConditionalOnProperty("familie.tellAPIEndepunkterIBruk")
class TellAPIEndepunkterIBrukInterceptor : AsyncHandlerInterceptor {
override fun preHandle(
request: HttpServletRequest,
response: HttpServletResponse,
handler: Any,
): Boolean {
val path = request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE) as String
TellAPIEndepunkterIBrukInitialiserer.metrikkerForEndepunkter.get("[${request.method}]$path")?.increment()
return super.preHandle(request, response, handler)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package no.nav.familie.metrikker

import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
import org.springframework.context.annotation.Configuration
import org.springframework.web.servlet.config.annotation.InterceptorRegistry
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer

@Configuration
@ConditionalOnProperty("familie.tellAPIEndepunkterIBruk")
open class TellAPIEndpunkterIBrukWebConfig : WebMvcConfigurer {
override fun addInterceptors(registry: InterceptorRegistry) {
registry.addInterceptor(TellAPIEndepunkterIBrukInterceptor()).addPathPatterns("/api/**")
super.addInterceptors(registry)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package no.nav.familie.metrikker

import io.mockk.clearAllMocks
import io.mockk.every
import io.mockk.mockk
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.springframework.context.ApplicationContext
import org.springframework.web.bind.annotation.RequestMethod
import org.springframework.web.servlet.mvc.condition.RequestMethodsRequestCondition
import org.springframework.web.servlet.mvc.method.RequestMappingInfo
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping

class TellAPIEndepunkterIBrukTest {
val applicationContext: ApplicationContext = mockk()
val requestMappingHandlerMapping: RequestMappingHandlerMapping = mockk()
val info: RequestMappingInfo = mockk()

@BeforeEach
fun setUp() {
clearAllMocks()
}

@Test
fun `skal opprette map med key og counter når det finnes en requestmapping`() {
settOppTestData("/api/foo", RequestMethod.GET)

TellAPIEndepunkterIBrukInitialiserer("test", applicationContext).populerMapMedCountersForRestEndepunkt()

assertThat(TellAPIEndepunkterIBrukInitialiserer.metrikkerForEndepunkter).hasSize(1)
assertThat(TellAPIEndepunkterIBrukInitialiserer.metrikkerForEndepunkter.containsKey("[GET]/api/foo")).isTrue()
assertThat(
TellAPIEndepunkterIBrukInitialiserer.metrikkerForEndepunkter.get("[GET]/api/foo")?.id?.name,
).isEqualTo("test.GET.api.foo")
}

@Test
fun `skal opprette map med key og counter når det finnes en requestmapping, hvor requesten har pathParam og navnet på counteren saneres`() {
settOppTestData("/api/foo/{fooId}", RequestMethod.POST)

TellAPIEndepunkterIBrukInitialiserer("test", applicationContext).populerMapMedCountersForRestEndepunkt()

assertThat(TellAPIEndepunkterIBrukInitialiserer.metrikkerForEndepunkter).hasSize(1)
assertThat(TellAPIEndepunkterIBrukInitialiserer.metrikkerForEndepunkter.containsKey("[POST]/api/foo/{fooId}")).isTrue()
assertThat(
TellAPIEndepunkterIBrukInitialiserer.metrikkerForEndepunkter.get("[POST]/api/foo/{fooId}")?.id?.name,
).isEqualTo("test.POST.api.foo.fooId")
}

@Test
fun `skal ikke opprette map med counter for annet enn pathparam som starter med api`() {
settOppTestData("/internal/foobar", RequestMethod.POST)

TellAPIEndepunkterIBrukInitialiserer("test", applicationContext).populerMapMedCountersForRestEndepunkt()

assertThat(TellAPIEndepunkterIBrukInitialiserer.metrikkerForEndepunkter).hasSize(0)
}

private fun settOppTestData(
path: String,
method: RequestMethod,
) {
every { info.patternValues } returns setOf(path)
every { info.methodsCondition } returns RequestMethodsRequestCondition(method)

every { requestMappingHandlerMapping.handlerMethods } returns
mapOf(Pair(info, mockk()))
every {
applicationContext.getBean(
"requestMappingHandlerMapping",
RequestMappingHandlerMapping::class.java,
)
} returns
requestMappingHandlerMapping
}
}
2 changes: 1 addition & 1 deletion modell/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
<artifactId>kotlin-stdlib</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
Expand Down
3 changes: 2 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
<module>kafka</module>
<module>valutakurs-klient</module>
<module>unleash</module>
<module>metrikker</module>
</modules>

<dependencyManagement>
Expand All @@ -60,7 +61,7 @@
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
<artifactId>kotlin-stdlib</artifactId>
<version>${kotlin.version}</version>
</dependency>
<dependency>
Expand Down
2 changes: 1 addition & 1 deletion sikkerhet/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
<artifactId>kotlin-stdlib</artifactId>
</dependency>
<dependency>
<groupId>no.nav.security</groupId>
Expand Down
2 changes: 1 addition & 1 deletion util/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
<artifactId>kotlin-stdlib</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
Expand Down
2 changes: 1 addition & 1 deletion valutakurs-klient/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
<artifactId>kotlin-stdlib</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import no.nav.familie.valutakurs.config.ValutakursRestClientConfig
import no.nav.familie.valutakurs.domene.ECBExchangeRatesData
import no.nav.familie.valutakurs.domene.ExchangeRate
import no.nav.familie.valutakurs.domene.toExchangeRates
import no.nav.familie.valutakurs.exception.IngenValutakursException
import no.nav.familie.valutakurs.exception.ValutakursException
import no.nav.familie.valutakurs.exception.ValutakursTransformationException
import org.springframework.beans.factory.annotation.Qualifier
import org.springframework.beans.factory.annotation.Value
Expand All @@ -16,8 +18,6 @@ import org.springframework.web.client.RestClientResponseException
import org.springframework.web.client.RestOperations
import java.net.URI
import java.time.LocalDate
import no.nav.familie.valutakurs.exception.IngenValutakursException
import no.nav.familie.valutakurs.exception.ValutakursException

@Component
@Import(ValutakursRestClientConfig::class)
Expand Down
Loading

0 comments on commit e3e35e4

Please sign in to comment.