Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Sammanfattning av verktygsval, arbetsmetoder och rutiner för utvecklingsfasen av vår DevOps-cykel.

Table of Contents
minLevel1
maxLevel7

Utvecklingsmiljö

Med utvecklingsmiljö här avser vi den lokala miljön som utvecklare sitter med.

Generella verktyg

Som generell editor föreslår vi IntelliJ IDEA, Eclipse eller Visual Studio Code med lämpliga plugins (dokumentera en rekommenderad grunduppsättning). Det bör dock vara fritt att använda andra editors om en känner sig effektivare med dem, så länge inte byggmiljöer påverkas eller licensmässiga problem uppstår.

Finns det några andra verktyg som alla skall/bör använda sig av? Skriv i så fall lite om dem här.

Lämpliga plugins:

  • Lombok - Ett bibliotek för att automatiskt “generera” boilerplate-kod - Guide för att installera plugin för Eclipse och IntelliJ finns här.

  • SonarLint - Skannar kod för att hitta buggar och sårbarheter.

  • Snyk’s Vulnerability Scanner - Skannar beroenden och identifierar sårbarheter.

  • fler…

Språk och ramverk

Förstahandsvalet för utveckling av backendtjänster skall vara Java, med hjälp av ramverket Quarkus Spring Boot. Se bakgrunden till det nya beslutet.
För SpringBoot har ett gemensamt bibliotek utvecklats. Rekommendationen är att använda detta. Läs mer: Dept44

Databas

MariaDB används som databas i produktion. Både Quarkus och Spring Boot har bra stöd för integration mot MariaDB.
Ett tips är att använda Hibernate ORM för att generera upp databastabeller. Då , då det blir det väldigt enkelt att köra samma kod med t.ex. H2.

Spring Boot:

Maven dependenciesHär används med fördel JPA och Hibernate

  • Maven: mariadb-java-client, spring-boot-starter-data-jpa, spring-boot dependenciet drar in nödvändiga Hibernate-bibliotek

Quarkus:

  • quarkus-jdbc-mariadb

  • quarkus-hibernate-orm

...

Maven dependencies:

  • quarkus-jdbc-h2

OpenAPI

Vi genererar upp OpenAPI-specifikationer för våra applikationer. Detta gör vi för att få en bra dokumentation samtidigt som det gör det enkelt för klienter att anropa våra applikation.
Denna OpenAPI-specifikation används även för att skapa ett API i vår API-Gateway WSO2.

WSO2 stödjer idag versioner av OpenAPI upp till 3.0.2. Ange därför detta i applikationens .

Spring Boot:

Här används med fördel springdoc, spring-fox går att använda men kompabiliteten med senare versioner av spring boot är mindre bra och maven-dependency:t har inte uppdaterats sedan juli 2020.

  • Maven dependencies: springdoc-openapi-webmvc-core samt springdoc-openapi-ui

  • Kräver att man exponerar en OpenAPI-böna, beskrivs här under punkt 8.
    Url:en för swagger-ui styrs om m.h.a. följande property: springdoc.swagger-ui.path=/swagger-ui.html
    Url:en för openapi-dokumentationen styrs av följande property: springdoc.api-docs.path=/api-docs,
    Url:erna blir följande:

    • Swagger-ui: http://service:port/swagger-ui.html

    • Yaml: http://service:port/api-docs.yaml

    • eller i JSON: http://service:port/api-docs

OBS: Använder man ramverket Dept44 följer Springdoc med per automatik och konfigureras automatiskt.

Quarkus:

  • Maven dependency: quarkus-smallrye-openapi

  • application.properties:

...

  • mp.openapi.extensions.smallrye.openapi=3.0.2

Maven dependencies:

  • quarkus-smallrye-openapi

Namnsättning i Java-applikationer

Allt namnsätts på engelska.

Paket

  • Paket namnsätts med gemener.

  • Paketstrukturen ska inledas med se.sundsvall följt av namnet på tjänsten

  • Exempel:

    • se.sundsvall.casemanagement.util

    • se.sundsvall.database.casemanagement.api

  • (Förslag) Ett sätt att strukturera paketen är att separera den i ett slags utökat MVC-mönster, detta ger en tydlighet och gör det lätt att förstå vad som sker var i tjänsten:

    • api - här läggs resurser och dess domänobjekt, t.ex. request/response-klasser.

    • configuration - konfiguration för tjänsten.

    • domain - domänobjekt, t.ex. DTO:er för att slussa runt data i tjänsten.

    • integration - här skall integrationer mot övriga system separeras med ett paket per integration, även databas-integrationer läggs här.

    • service - logiklager för att sy ihop api och integration.

    • övriga paket skapas vid behov.

Klasser

  • Klasser namnsätts enligt UpperCamelCase.

  • Klassnamn ska vara substantiv.

  • Undvik förkortningar i klassnamn.

  • Exempel:

    • FeedbackSettingResource

    • Message

Metoder

  • Metoder namnsätts enligt lowerCamelCase.

  • Metodnamn ska vara verb.

  • Exempel:

    • convertDateToString

    • deleteFeedbackSetting

Variabler

  • Variabler namnsätts enligt lowerCamelCase.

  • Försök undvika variabelnamn med endast en bokstav, förutom temporära variabler (t.ex. for-loop).

  • Exempel:

    • personId

    • primaryContactMethod

Konstanter

  • Konstanter namnsätts med versaler.

  • Orden separeras med understreck ( _ ).

  • Exempel:

    • THE_REQUEST_MUST_CONTAIN_A_REQUEST_BODY

Kodhantering

Kodhantering sker idag internt på våran GitLab server Kod lagras primärt på Github https://gitlab.sundsvall.seFinns även möjlighet att ha kod i externa Github github.com/Sundsvallskommun/

Övrig kod som ej skall exponeras kan lagras på https://github.com/Sundsvallskommun/Där bör man fundera man fram om det man jobbar med ska ligga open source eller gitlab.sundsvall.se

Det mesta vi gör skall exponeras som open source, alternativt om det är för en intern tjänst. Detta dikterar bestämmer vart man ska lägga koden.

När ett nytt repository skapas i Gitlab då skapar driftansvariga även en Sandbox gren. Denna gren hanteras annorlunda än master grenen.

Hur fungerar det med branchhanteringen? När och hur skapas featurebrancher?koden läggs.

Branchhantering

  • “main” - Denna branch skall representera produktion, eller kod som skall läggas ut i produktion.
    Om kod som inte ligger i produktion pushas hit försvåras eventuella buggrättningar då buggfix-brancher måste tas ut från tidigare commits.

  • “develop” - Här sker löpande utveckling, som när den är produktionsduglig mergas till main.

    • Den löpande utvecklingen bör ske i mindre feature-brancher som tas från develop-branchen och döps utifrån task eller story i Jira.
      Bör prefixas med “API-XXX-” där XXX är numret på tasken/storyn.

Externa klienter (WIP)

För att kommunicera med övriga system behövs klient-kontrakt genereras som sedan kan tas in som ett maven-dependency.
Dessa kontrakt sparas i ett git-repo (förslag: “generated-clients”) där varje systems wsdl:er/openapi-doc läggs i separata kataloger och en klient genereras och pushas till nexus.
På detta vis kan flera tjänster dra nytta av samma klient utan att den behöver genereras upp i varje tjänst.

Uppdatering av “våra” kontrakt och klienter

Alla tjänster som exponerar ett API som någon av våra andra tjänster nyttjar bör läggas in i detta repo.
Varje ändring i tjänsten som resulterar i en API-förändring bör reflekteras i repot och en uppdaterad klient bör genereras och pushas till nexus.

Versionshantering av klienter

Våra egna klienter bör följa den version av API:et som ligger i API-managern så långt det går.

Anchor
test
test
Tester

Funktionella tester

...

Enhetstester (https://

...

www.

...

javatpoint.

...

com/unit-testing )

Vi skall Dessa tester ska fokusera på att testa enskilda isolerade komponenter och dess funktionalitet.

Vi ska enhetstesta vår kod med en kodtäckning på minst 80% samt en branch-täckning på 50%. En analys av kodtäckningen ska utföras vid varje commit och varna vid för låg kodtäckning.
Jacoco bör användas för att mäta kodtäckning.

Både positiva och negativa enhetstester skall ska implementeras.
Enhetstester skall Tänk på att skriva tester som inte bara ger täckning, det går att skriva tester som ger 100% coverage utan att egentligen testa någonting.

Dessa tester ska vara automatiska och exekveras vid varje commit,

Applikationstester

Förutom enhetstester skall vi dessutom implementera helhetstester av våra applikationer/mikrotjänster, från anrop till svar inklusive integrationer..

Integrationstester (https://www.javatpoint.com/integration-testing )

Dessa tester ska fokusera på att testa integrationerna mellan olika komponenter.

Exempel på integrationer som ska testas:

  • integration mot angränsade applikationer

  • integration mot databas

För att inte vara beroende av angränsade applikationers hälsa skall ska integrationer simuleras med hjälp av WireMock (http://wiremock.org/ ) eller liknande.
Både positiva och negativa applikationstester skall implementerasDatabasen som används kan vara en “in-memory”-databas, exempelvis H2.

Dessa tester skall minst ska vara automatiska och exekveras vid varje commit.

Integrationstester

Helhetstester inkluderande integrationer mot angränsade applikationer skall genomföras inför varje release.

Acceptanstestning

...

Systemtester (https://www.javatpoint.com/system-testing )

Dessa tester ska fokusera på att testa systemets helhet. Dessa tester ska omfatta hela lösningen i vilken “våra” applikationer/mikrotjänster är en delmängd.

Både positiva och negativa systemtester ska utföras.

Dessa tester kan antingen vara automatiska eller manuella och ska exekveras inför varje release.

Acceptanstester (https://www.javatpoint.com/acceptance-testing )

Acceptanstestning ska utföras av kunden. Dessa tester ska fokusera på att säkerställa att systemet motsvarar de specificerade kraven.

Dessa tester ska exekveras inför varje release.

Icke-funktionella tester

Prestandatester

Användbarhetstester

Kompatibilitetstester