===== Spring Boot ====== Spring boot - is a Java framework, which claims to retrieve the default configurations from the libraries loaded to the path. ==== Rest Controller ==== Logging the exposed endpoints. To log the exposed endpoints the change in the application.properties is required: application.properties logging.level.web=TRACE logging.level.org.springframework.web=TRACE Example output 12:14:48.398 [main] TRACE o.s.w.s.m.m.a.RequestMappingHandlerMapping i.d.l.d.g.RestGroupController: {GET [/rest/, /rest/groups]}: index(String,Optional) {POST /rest/groups, consumes [application/json]}: createGroup(Group) {POST /rest/groups/{groupId}/member}: addUserToGroup(String,String) {DELETE /rest/groups, consumes [application/json]}: deleteRole(String) {GET [/rest/, /rest/groups/member/{memberId}]}: groupsByMember(String) {GET [/rest/, /rest/groups/{id}]}: groupById(String) {DELETE /rest/groups/{groupId}/member}: removeUserFromGroup(String,String) 12:14:48.418 [main] TRACE o.s.w.s.m.m.a.RequestMappingHandlerMapping i.d.l.d.r.RestRoleController: {GET [/rest/, /rest/roles]}: index(String,Optional) {POST /rest/roles/{roleId}/member}: addMemberToRole(String,String,String) {DELETE /rest/roles, consumes [application/json]}: deleteRole(String) {POST /rest/roles, consumes [application/json]}: createRole(Role) {DELETE /rest/roles/{roleId}/member}: removeUserFromRole(String,String,String) ===== New project ===== Use [[https://start.spring.io/|Spring Initializr]] to generate a new project. Import it to the Idea IDE via: {{https://lh3.googleusercontent.com/-eDxwVOJ3dzs/Wpp5XRC7hkI/AAAAAAAAADw/L4JVWKY-81gPOnyjZekGnsZt44ccnP6UgCHMYCw/s0/2018-03-03_11-30-52.png}} ===== Gradle ===== Spring boot is normally either * packaged to an executable jar, together with dependencies, or * packaged as a deployable war, so that it may be deployed to a Tomcat etc. == Running the app == Running the app with gradle, choosing the port ./gradlew bootRun --args='--server.port=8888' == Building a JAR == To create a Jar with gradle - add the following to build.gradle to automagically resolve dependencies within the current spring boot version - you must apply a special plugin. \\ The dependencies will be resolved acording to the BOM - bill of materials. \\ Check https://docs.spring.io/spring-boot/docs/2.0.0.RELEASE/gradle-plugin/reference/html/#packaging-executable-jars apply plugin: 'io.spring.dependency-management' Build the jar by using **gradlew**. \\ This will produce a JAR e.g. under **build\libs\PROJECTNAME\complete.jar** ../../gradlew BootJar Start the jar java -jar complete.jar {{https://lh3.googleusercontent.com/-nSi9oHOqYxY/Wphe7hn3NKI/AAAAAAAAADY/Pc9ecqMiTpIkSgR9VfKIcDAft7SrIN8wQCHMYCw/s0/2018-03-01_21-13-31.png}} == Building a WAR == build.gradle apply plugin: 'io.spring.dependency-management' apply plugin: 'war' Build the jar by using **gradlew**. \\ This will produce a JAR e.g. under **build\libs\PROJECTNAME\complete.war** ../../gradlew BootWar ===== Spring Profiles ====== Spring profiles can be activated in multiple ways, e.g. by setting the environment variable export spring_profiles_active=dev by passing an argument to the java virtual machine -Dspring.profiles.active=dev When activated - you get the option to create a profile dependant properties files. * .properties files are located in /resources/application-{profile}.properties * ./resources/application-dev.properties * ./resources/application-stage.properties * ./resources/application-prod.properties * * ./resources/application.properties - is the default file, which is active * .properties files are additive To pick a default profile - you need to set in in applicaiton.properties application.properties # the default profile which is used. Can be overridden by specifying the Spring profile as -Dspring.profiles.active or in another way. # without that the "spring.profiles.active" will not fall back to the value "default" spring.profiles.active=dev ==== Continous build ==== Spring boot applications - can be configured to - react on file changes - rebuild the application e.g. to a jar - redeploy the jar, e.g. to the ThomCat == Step 1 == Add dev-tools to the dependencies, so that the rebuilt app is hot-swaped on the app server. In **build.gradle** dependencies { // makes Spring boot hot swap rebuilt jar to tomcat developmentOnly 'org.springframework.boot:spring-boot-devtools' } == Step 2 == In a separate terminal, start the continuous build of application. Do that in a separate terminal, because the command doesn't come back, but listens for file changes. It works in **Vagrant**, in a **Ubuntu guest-VM**, on **host-Windows**, on a "shared-folder".
But unfortunately, changes, originating form **vagrant-host-machine** - are NOT recognized.
To trigger rebuild, hot-swap - one needs to change some file in the **vagrant-guest-machine**. Starts continuos build skipping the tests ./gradlew build -xtest --continuous To propagate a change triggering a rebuild - you need to modify the file on the guest-system echo "" >> HelloController.java == Step3 Launch the app == The app will be built and propagated ./gradlew bootRun --args='--server.port=8888' ====== Native Image ====== # Prerequisites Install java # java open GraalVM from liberica "native image kit" sdk install java 22.3.r17-nik < /dev/null # switch sdk use java 22.3.r17-nik # set the Java_home source "~/.sdkman/bin/sdkman-init.sh" # Quickstart Build a native image ./gradlew nativeCompile [native-image-plugin] Native Image written to: /PROJECTDIR/throttling-enforcer/build/native/nativeCompile Run /PROJECTDIR/throttling-enforcer/build/native/nativeCompile/demo ===== Rest Controller ==== CRUD repositories ''CrudRepository'' can create queries by convention. Just name the methods according to the convention https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.query-creation and they will be mapped to queries. ===== API Versioning ==== URI Versioning - Twitter * http://localhost:8080/vl/person * http://localhost:8080/v2/person Request Parameter versioning - Amazon * http://localhost:8080/person?version=l * http://localhost:8080/pcrson?vcrsion=2 (Custom) headers versioning - Microsoft * SAME-URL headers=(X-API-VERSION=l] * SAME-URL headers=[X-API-VERSION=2] Media type versioning - GitHub * SAME-URL produces=application/vnd.company.app-vl+json * SAME-URL produces=application/vnd.company.app-v2+json ===== Libs ===== ==== Hystrix - Circuit Breaker ==== https://www.baeldung.com/spring-cloud-netflix-hystrix ==== Feign - declarative REST client ==== Reduces the glue-code to the minimum. Need only to express - what to call and receive the response DTO https://cloud.spring.io/spring-cloud-netflix/multi/multi_spring-cloud-feign.html package com.in28minutes.microservices.currencyconversionservice; import org.springframework.cloud.netflix.feign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @FeignClient(name = "currency-exchange-service", url = "localhost:8000") public interface CurrencyExchangeServiceProxy { @GetMapping("/currency-exchange/from/{from}/to/{to}") public CurrencyConversionBean retrieveExchangeValue (@PathVariable("from") String from, @PathVariable("to") String to); } ==== Ribbon - Client based load balancer ==== Exposes multiple deployments under one URL {{https://s3.eu-central-1.amazonaws.com/alf-digital-wiki-pics/sharex/K9ELIqz2Uf.png}} {{https://s3.eu-central-1.amazonaws.com/alf-digital-wiki-pics/sharex/Od4LgsV7Ij.png}} ==== Zuul API Gateway ==== API Gateway in SPring ==== EUreka Namingserver ==== Allows to register / discover services on a naming server. Has a GUI to list available services. {{https://s3.eu-central-1.amazonaws.com/alf-digital-wiki-pics/sharex/qVkyO04yvD.png}} ==== Cloud Sleuth - unique tracing id to requests ==== adds a unique tracing id to requests ==== Zipkin - Distributed Tracing Server ==== Central tracing server. * Like ELK. * and CloudWatch {{https://s3.eu-central-1.amazonaws.com/alf-digital-wiki-pics/sharex/ce868zFAte.png}} {{https://s3.eu-central-1.amazonaws.com/alf-digital-wiki-pics/sharex/EG0bVz0lrr.png}} ==== Spring Cloud Bus ==== Can use it to refresh the configs of all services, by sending a message via the bus. ===== Docker ===== == Build manually without gradle == docker build --build-arg JAR_FILE=build/libs/\*.jar -t springio/demo-consume-api -f src/main/docker/Dockerfile . == Build with Gradle == You can build a tagged docker image with Gradle in one command: sudo su ./gradlew bootBuildImage --imageName=springio/demo-consume-api sudo docker images == And run == sudo docker run -p 8080:8080 springio/demo-consume-api