Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 28 Next »

Bas-startern bör användas av alla utvecklade tjänster och den innehåller funktionalitet och konfiguration för:

För att förenkla användning inaktiverar startern följande Spring Boot-auto-konfigurationer:

  • org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration

  • org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration

  • org.zalando.problem.spring.web.autoconfigure.security.ProblemSecurityAutoConfiguration

Felhantering

Se Felhantering

RequestId-hantering

TODO

Truststore

Truststore-funktionalitet innebär att man kan skapa en “in-memory”-truststore baserat på SSL-certifikat (i PEM-format). Detta eliminerar behovet av att skapa separata truststore-/keystore filer med hjälp av t.ex. keytool. Det enda som behövs är att lägga certifikatet i katalogen classpath:truststore/.

Truststore används även av “spring-cloud-config-server-client”-funktionaliteten. I det fallet har även ett certifikat till “config-servern” bundlats med dept44-startern. Behovet av att varje klient måste sätta upp en egen truststore-fil för config-serverns SSL-cert är därmed undanröjt.

Inställning

Default-värde

Beskrivning

dept44.truststore.path

truststore/*

Anger sökväg till de certifikat klienten lagt till (om inte default-katalogen “truststore/” används)

Miljövariabel-hantering

För att underlätta extern (läs: ej versionshanterad) hantering av credentials finns möjligheten att lägga till dessa som miljövariabler i en fil med namnet “.env”.

Filen skall ligga i classpath-rooten (t.ex. i projekt-rooten).

Det går att lägga till variabler på två olika sätt:

Med hjälp av Spring Boot:s teminologi

Exempel:

.env

example.variable=Hello World

application.properties får inte innehålla variabel med samma namn (eftersom property-filen har högre rang än env-filen)

#example.variable=Goodbye World <- denna måste tas bort eller kommenteras ut

I exemplet ovan kommer example.variable att ha värdet ‘Hello World’ när applikationen startar.

Med hjälp av spring-dotenv:s teminologi

Exempel:

.env

EXAMPLE_VARIABLE=Hello World

Variabeln kan sedan användas i applikationen.

application.properties:

example.name = ${env.EXAMPLE_VARIABLE:}

Mer information: https://github.com/paulschwarz/spring-dotenv

Loggning

Generell loggning sker med hjälp av SLF4J, t.ex.:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
...
public class MyClass {
    private static final Logger LOG = LoggerFactory.getLogger(MyClass.class);
    ...

    public void doSomething(String s) {
        LOG.debug("Doing something with {}", s);
    }
}

Loggning av trafik, såväl för inkommande och utgående requests och responses sker med hjälp av biblioteket Logbook.

Inställningar
(Auto-konfigurationsklass: se.sundsvall.dept44.configuration.LogbookConfiguration)

Inställning

Default-värde

Beskrivning

logbook.logger.name

se.sundsvall.dept44.payload

Anger den logg-kategori som trafikloggningen ska göras i

logbook.excluded.paths

/,/webjars/**,/api-docs**,/swagger-resources,/swagger-resources/**,/error,/csrf,/swagger-ui.html,/swagger-ui/**,/favicon.ico,/actuator,/actuator/**

Anger de sökvägar som ska exkluderas från trafikloggning

Viktigt att komma ihåg om man sätter om logg-kategorin är att man då även sätter om loggnivån på den konfigurerade loggkategorin till TRACE - om det inte görs kommer ingen trafikloggning att dyka upp i applikationens logg.

Jackson (serialisering/deserialisering av JSON och YAML)


Jackson används för serialisering av objekt till JSON och tillbaka - d.v.s. deserialisering av JSON till objekt. Konfigurationen som görs i ramverket innefattar bland annat:

  • null-värden exkluderas vid serialisering

  • den JSON-data som genereras är indenterad, för ökad läsbarhet

  • okända attribut ignoreras vid deserialisering

Vidare används Jackson för serialisering av objekt till YAML och tillbaka.

Inställningar
(Auto-konfigurationsklass: se.sundsvall.dept44.configuration.ObjectMapperConfiguration)

OpenAPI och Swagger UI

För att generera OpenAPI v3.x-specifikation och tillhandahålla ett Swagger UI används SpringDoc.

Minimal konfiguration i application.properties:

openapi.name=ett-api
openapi.title=Ett API
openapi.version=1.0

OpenAPI-specifikationen exponeras på /api-docs. Som standard serveras OpenAPI-specifikationen som JSON, med kan även fås som YAML genom att sätta Accept-headern till application/yaml. YAML-representation av OpenAPI-specifikationen kan även nås via /api-docs.yaml.

Vidare läggs en endpoint /api-docs till i tjänstens Swagger UI som kommer att vara åtkomlig utan autentisering, där man kan hämta OpenAPI-specifikationen.

Se nedan för övriga valbara inställningar.

Inställningar

(Auto-konfiguration: se.sundsvall.dept44.configuration.openapi.OpenApiConfiguration)

Inställning

Default-värde

Beskrivning

openapi.enabled

true

Anger om OpenAPI-specifikation ska genereras och Swagger UI konfigureras

openapi.name (obligatorisk så länge openapi.enabled inte är false)

-

Namn som används för att generera URL till API-dokumentation. Får bara innehålla bokstäver, siffror, underscore och bindestreck

openapi.title (obligatorisk så länge openapi.enabled inte är false)

-

Titel som ska användas i OpenAPI-specifikationen

openapi.version (obligatorisk så länge openapi.enabled inte är false)

-

Versionsnummer som ska användas i OpenAPI-specifikationen

openapi.license.name

MIT

Namn på den licens som ska ingå i OpenAPI-specifikationen

openapi.license.url

https://opensource.org/licenses/MIT

Länk till den licens som ska ingå i OpenAPI-specifikationen

openapi.contact.name

-

Namnet på den kontakt som ska ingå i OpenAPI-specifikationen

openapi.contact.email

-

E-postadressen till den kontakt som ska ingå i OpenAPI-specifikationen

openapi.contact.url

-

URL för den kontakt som ska ingå i OpenAPI-specifikationen

openapi.security-scheme.oauth2.flow.tokenUrl

-

TODO

openapi.servers[n].url

-

TODO

openapi.servers[n].description

-

TODO

openapi.extensions.<extension>.... (Map)

-

Eventuella tillägg till OpenAPI-specifikationen

(se https://swagger.io/docs/specification/openapi-extensions/)

Circuit breaker och health-indicator

Dept44 erbjuder en möjlighet att addera “circuit-breakers” och “health-indicators” på en resurs (t.ex. en integrationsklient). Dept44 använder sig av Resilience4j för detta syfte. Detta ramverk möjliggör mycket mer funktionalitet än vad som beskrivs här. T.ex. RateLimiter, TimeLimiter, Retry, osv. För ytterligare info hänvisas till dokumentationen av Resilience4j. I detta avsnitt beskrivs enbart funktionalitet kopplad till s.k. “circuit-breakers” och “health-indicators”.

Genom att lägga till en “circuit-breaker” på en resurs får man automatiskt även en “health-indicator”. Dessa går hand i hand och återspeglar varandras status. Om en “circuit-breaker” öppnas kommer således motsvarande “health-indicator” att rapportera “DOWN”. Den “health-indicator” som skapas kommer att per automatik exponeras under sökvägen “/actuator/health” och kan plockas upp av t.ex. Spring boot admin om tjänsten anslutit sig mot en sådan server.

Komma igång

Börja med att annotera din resurs. Resursen brukar vanligtvis var t.ex. en integrationsklient, databas-klient, etc.:

@FeignClient(name = "MyFeignClient", url = "${integration.backend.url}", configuration = MyFeignClientConfiguration.class)
@CircuitBreaker(name = "MyFeignClient")
public interface MyFeignClient {
...
}

[2] Skapar en “Circuit breaker” samt “Health indicator” med namnet “MyFeignClient”. Annoteringen kan placeras på både klass och metodnivå.


Ovanstående är allt som krävs för att att skapa en “Circuit breaker” som bryter kretsen om resursen kastar en exception. Kretsen kommer vid dessa tillfällen att hållas öppen under en kort tidsperiod (default 60 sekunder), innan den övergår till ett “halvöppet läge”. I det “halv-öppna” läget tillåts ett konfigurerbart antal anrop för att utvärdera resursens status. Under tiden som kretsen hålls öppen kommer den automatiskt registrerade health-indicatorn att visa “DOWN” för denna resurs. När resursen åter fungerar bra kommer kretsen att stängas helt och “health-indicatorn” visar “UP”.

Vill man anpassa detta beteende för att t.ex. ändra kretsens öppettid, vilka exceptions som skall ignoreras, osv, kan man använda sig av alla standardinställningar som erbjuds av Resilience4j.

Exempel på inställningar i application.properties:

resilience4j.circuitbreaker.instances.MyFeignClient.ignoreExceptions=se.sundsvall.dept44.exception.ClientProblem                   [default: ej satt]
resilience4j.circuitbreaker.instances.MyFeignClient.failureRateThreshold=60                                                        [default: 50]
resilience4j.circuitbreaker.instances.MyFeignClient.waitDurationInOpenState=200s                                                   [default: 60s]
resilience4j.circuitbreaker.instances.MyFeignClient.allowHealthIndicatorToFail=false                                               [default: true]
resilience4j.circuitbreaker.instances.MyFeignClient.slidingWindowSize=20                                                           [default: 10]
resilience4j.circuitbreaker.instances.MyFeignClient.permittedNumberOfCallsInHalfOpenState=10                                       [default: 5]

resilience4j.circuitbreaker.configs.mySharedConfig.baseConfig=default
resilience4j.circuitbreaker.configs.mySharedConfig.slidingWindowSize=50
resilience4j.circuitbreaker.instances.MyOtherFeignClient.baseConfig=mySharedConfig

[1] Låter resursen “MyFeignClient” ignorera en lista av Exceptions. Kastas dessa fel markeras anropet som “successful”. Kan t.ex. vara bra att låter fel i HTTP-400 serien ignoreras (dessa betyder ju inte att integrationen har problem.)
[2] Tröskelvärde för antal fel (inom slidingWindowSize) som skall öppna kretsen och markera “health-indicator” som “DOWN”. Anges i procent.
[3] Den tid som kretsen hålls öppen innan den övergår till ett “halv-öppet” läge.
[4] Låter applicationens “health” återspeglas av enskilda “health-indicator:s”. M.a.o. om en “health-indicator” är “DOWN” så blir applicationens health också “DOWN”, om denna property är true.
[5] Storleken på den buffer som används för att spara och utvärdera resultatet på anropen när kretsen är sluten.
[6] Antal tillåtna anrop som tillåts när kretsen är “halv-öppen”.
[8] Skapar en egen konfigurationsprofil (mySharedConfig) som “ärver” från default (definierad i dept44).
[9] Skriver över default-värden för en property i mySharedConfig
[10] Sätter aktuella värden i konfigurationsprofilen till en resurs (myOtherSharedConfig). Denna mekanism (d.v.s. rad: 8, 9, 10) är bra om man t.ex. har flera “circuit-breakers” som måste tilldelas andra värden än default, för att slippa upprepningar.

Viktiga endpoints

Path

Beskrivning

Exempel

/actuator/health

Här visas alla health-indicators och deras aktuella status (hälsovärde).

{
  "status" : "UP",
  "components" : {
    "circuitBreakers" : {
      "status" : "UP",
      "details" : {
        "MyFeignClient" : {
          "status" : "UP",
          "details" : {
            "failureRate" : "-1.0%",
            "failureRateThreshold" : "50.0%",
            "slowCallRate" : "-1.0%",
            "slowCallRateThreshold" : "100.0%",
            "bufferedCalls" : 1,
            "slowCalls" : 0,
            "slowFailedCalls" : 0,
            "failedCalls" : 1,
            "notPermittedCalls" : 0,
            "state" : "CLOSED"
          }
        }
      }
    }
  }
}

/actuator/circuitbreakerevents

De senaste [n] resultaten av anrop som övervakas av en CircuitBreaker.

Storleken på event-buffern sätts via attributet “eventConsumerBufferSize”. Default är 100 poster per circuit-breaker.

Denna endpoint kan vara bra att använda när man vill se orsaken till att en krets öppnats och en health-indicator rapporterar “DOWN”.

{
  "circuitBreakerEvents" : [ {
    "circuitBreakerName" : "MyFeignClient",
    "type" : "ERROR",
    "creationTime" : "2022-06-14T10:45:00.967115+02:00[Europe/Stockholm]",
    "errorMessage" : "javax.validation.Exception: test.uuid: not a valid UUID",
    "durationInMs" : 16
  }, {
    "circuitBreakerName" : "MyFeignClient",
    "type" : "IGNORED_ERROR",
    "creationTime" : "2022-06-14T10:46:08.104328300+02:00[Europe/Stockholm]",
    "errorMessage" : "about:blank{502, Bad Gateway, POB error: {detail=, status=401 Unauthorized, title=Authorization has been denied for this request.}}",
    "durationInMs" : 289
  } ] 
}

/actuator/circuitbreakers

Listar alla registrerade circuitbreakers i applikationen.

{
  "circuitBreakers" : [ "MyFeignClient", "MyOtherFeignClient" ]
}


  • No labels