diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..2f9f1cb Binary files /dev/null and b/.DS_Store differ diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml new file mode 100644 index 0000000..eac633f --- /dev/null +++ b/.github/workflows/docker-image.yml @@ -0,0 +1,18 @@ +name: Docker Image CI + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + +jobs: + + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Build the Docker image + run: docker build . --file Dockerfile --tag my-image-name:$(date +%s) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml new file mode 100644 index 0000000..afe4fe3 --- /dev/null +++ b/.github/workflows/maven.yml @@ -0,0 +1,35 @@ +# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven + +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. + +name: Java CI with Maven + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'temurin' + cache: maven + - name: Build with Maven + run: mvn -B package --file pom.xml + + # Optional: Uploads the full dependency graph to GitHub to improve the quality of Dependabot alerts this repository can receive + - name: Update dependency graph + uses: advanced-security/maven-dependency-submission-action@571e99aab1055c2e71a1e2309b9691de18d6b7d6 diff --git a/.gitignore b/.gitignore index 377dddf..461627c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ -/.idea/ +*.* /Status + diff --git a/README.md b/README.md index f1f3970..830ebda 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,52 @@ # spring-boot-based-microservices -Basic skeleton for Spring Boot Microservices. It includes spring spring security for basic Auth. Zuul is also implemented as an API gateway. Lots of the spring cloud component integrated. +Basic skeleton for Spring Boot Microservices. It includes spring security for basic Auth. Spring cloud gateway is also implemented as an Edge Service. Lots of the spring cloud component integrated. +# How to run + +- Navigate to root of the project +``` + cd spring-boot-based-microservices +``` +- Build the project +``` + mvn clean package -DskipTests +``` +![Maven Build](https://github.com/Nasruddin/spring-boot-based-microservices/blob/master/images/build.png?raw=true) + +- Locate the docker directory from the root directory and run docker compose to startup the containers +``` + cd docker && docker compose up --build +``` +![Docker Compose Build](https://github.com/Nasruddin/spring-boot-based-microservices/blob/master/images/docker-compose.png?raw=true) + +- Check if all our services are running and healthy +``` + docker ps +``` +![Docker PS](https://github.com/Nasruddin/spring-boot-based-microservices/blob/master/images/docker-ps.png?raw=true) + +- Let's check if all the services are up and running. We will reach to eureka server using gateway. +Open the browser and hit http://localhost:8443/eureka/web You will need to authenticate yourself before accessing the endpoint. +``` +username : user +password : password +``` +![Eureka](https://github.com/Nasruddin/spring-boot-based-microservices/blob/master/images/eureka.png?raw=true) + +- Now, we have a look at our gateway endpoints configurations as well. Hit http://localhost:8443/actuator/gateway/routes in the browser again and, you should be able to find all the routes configured. +![Gateway Routes](https://github.com/Nasruddin/spring-boot-based-microservices/blob/master/images/gateway-routes.png?raw=true) + + +- Coming to swagger/openapi specs, here is the address to access them - http://localhost:8443/openapi/swagger-ui.html +![Swagger OpenApi Specs](https://github.com/Nasruddin/spring-boot-based-microservices/blob/master/images/swagger-openapi.png?raw=true) + +- Please use the below curl to generate the access token with both read and write scope. +``` +curl -k http://writer:secret-writer@localhost:8443/oauth2/token -d grant_type=client_credentials -d scope="course:read course:write" +``` +![Swagger OpenApi Specs](https://github.com/Nasruddin/spring-boot-based-microservices/blob/master/images/oauth-endpoint.png?raw=true) +![Swagger OpenApi Specs](https://github.com/Nasruddin/spring-boot-based-microservices/blob/master/images/jwt-io.png?raw=true) + +## Note : Currently this project uses Spring Authorization server. Keep in mind, I'm planning to enhance the whole OAuth flow because it's in shaky state right now and, you may some face issues. We may also move to keycloak. +## These instructions are basic starting point and, the project does lot of other stuff like elastic and mongo configuration etc. Please feel free to play around. I really want to maintain this and keep up-to-date, however my current role doesn't give me enough spare time. Therefore, contributors and their contributions are welcome :) \ No newline at end of file diff --git a/api/pom.xml b/api/pom.xml index e5533f0..b3db193 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -5,12 +5,13 @@ org.springframework.boot spring-boot-starter-parent - 2.6.6 + 3.4.3 io.javatab.microservices.api api 1.0.0 + jar api Demo project for Spring Boot @@ -41,11 +42,18 @@ - org.springframework.boot - spring-boot-maven-plugin - - exec - + org.springframework.boot + spring-boot-maven-plugin + 3.4.3 + + + repackage + none + + repackage + + + diff --git a/api/src/test/java/io/javatab/microservices/api/ApiApplicationTests.java b/api/src/test/java/io/javatab/microservices/api/ApiApplicationTests.java index 406c4f7..5401095 100644 --- a/api/src/test/java/io/javatab/microservices/api/ApiApplicationTests.java +++ b/api/src/test/java/io/javatab/microservices/api/ApiApplicationTests.java @@ -3,7 +3,7 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -@SpringBootTest +@SpringBootTest() class ApiApplicationTests { @Test diff --git a/config-repo/auth-server.yml b/config-repo/auth-server.yml new file mode 100644 index 0000000..880529e --- /dev/null +++ b/config-repo/auth-server.yml @@ -0,0 +1,2 @@ +server.port: 9999 +server.forward-headers-strategy: framework \ No newline at end of file diff --git a/config-repo/course-composite.yml b/config-repo/course-composite.yml index 64b9ea6..0d6e585 100644 --- a/config-repo/course-composite.yml +++ b/config-repo/course-composite.yml @@ -9,14 +9,14 @@ springdoc: cache: disabled: true swagger-ui: - oauth2-redirect-url: https://localhost:8443/webjars/swagger-ui/oauth2-redirect.html + oauth2-redirect-url: http://localhost:8443/webjars/swagger-ui/oauth2-redirect.html oauth: clientId: writer clientSecret: secret useBasicAuthenticationWithAccessCodeGrant: true oAuthFlow: - authorizationUrl: https://localhost:8443/oauth2/authorize - tokenUrl: https://localhost:8443/oauth2/token + authorizationUrl: http://localhost:8443/oauth2/authorize + tokenUrl: http://localhost:8443/oauth2/token server.forward-headers-strategy: framework diff --git a/config-repo/eureka-server.yml b/config-repo/eureka-server.yml new file mode 100644 index 0000000..08ce63d --- /dev/null +++ b/config-repo/eureka-server.yml @@ -0,0 +1,17 @@ +server: + port: 8761 + +eureka: + instance: + hostname: localhost + client: + registerWithEureka: false + fetchRegistry: false + serviceUrl: + defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ + # from: https://github.com/spring-cloud-samples/eureka/blob/master/src/main/resources/application.yml + server: + waitTimeInMsWhenSyncEmpty: 0 + response-cache-update-interval-ms: 5000 + + diff --git a/config-repo/gateway.yml b/config-repo/gateway.yml new file mode 100644 index 0000000..cf2eb2b --- /dev/null +++ b/config-repo/gateway.yml @@ -0,0 +1,76 @@ +server.port: 8443 +test1.data: helloupdate +logging: + level: + root: INFO + org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator: INFO + org.springframework.cloud.gateway: TRACE + org.springframework.web.server.adapter.HttpWebHandlerAdapter: TRACE + +spring.cloud.gateway.routes: + - id: course-composite + uri: lb://course-composite + predicates: + - Path=/course-composite/** + + - id: oauth2-server + uri: lb://auth-server + predicates: + - Path=/oauth2/** + + - id: oauth2-login + uri: lb://auth-server + predicates: + - Path=/login/** + + - id: oauth2-error + uri: lb://auth-server + predicates: + - Path=/error/** + + - id: course-composite-swagger-ui + uri: lb://course-composite + predicates: + - Path=/openapi/** + + - id: course-composite-swagger-ui-webjars + uri: lb://course-composite + predicates: + - Path=/webjars/** + + - id: eureka-api + uri: http://${app.eureka-server}:8761 + predicates: + - Path=/eureka/api/{segment} + filters: + - SetPath=/eureka/{segment} + + - id: eureka-web-start + uri: http://${app.eureka-server}:8761 + predicates: + - Path=/eureka/web + filters: + - SetPath=/ + + - id: eureka-web-other + uri: http://${app.eureka-server}:8761 + predicates: + - Path=/eureka/** + - id: config-server + uri: ${spring.cloud.config.uri} + predicates: + - Path=/config/** + filters: + - RewritePath=/config/(?.*), /$\{segment} + +spring.security.oauth2.resourceserver.jwt.issuer-uri: http://${app.auth-server}:9999 + + +management.endpoint.gateway.enabled: true +management.endpoints.web.exposure.include: "*" + +#server.ssl: +# key-store-type: PKCS12 +# key-store: classpath:keystore/edge.p12 +# key-store-password: password +# key-alias: localhost \ No newline at end of file diff --git a/create-project.bash b/create-project.bash index 03a4dab..80b646e 100644 --- a/create-project.bash +++ b/create-project.bash @@ -1,10 +1,10 @@ #!/usr/bin/env bash -mkdir microservices -cd microservices +mkdir spring-boot-based-microservices +cd spring-boot-based-microservices spring init \ ---boot-version=2.5.2 \ +--boot-version=3.4.3 \ --build=maven \ --java-version=17 \ --packaging=jar \ @@ -16,7 +16,7 @@ spring init \ student-service spring init \ ---boot-version=2.5.2 \ +--boot-version=3.4.3 \ --build=maven \ --java-version=17 \ --packaging=jar \ @@ -28,7 +28,7 @@ spring init \ course-service spring init \ ---boot-version=2.5.2 \ +--boot-version=3.4.3 \ --build=maven \ --java-version=17 \ --packaging=jar \ @@ -40,7 +40,7 @@ spring init \ vote-service spring init \ ---boot-version=2.5.2 \ +--boot-version=3.4.3 \ --build=maven \ --java-version=17 \ --packaging=jar \ @@ -52,7 +52,7 @@ spring init \ search-service spring init \ ---boot-version=2.5.2 \ +--boot-version=3.4.3 \ --build=maven \ --java-version=17 \ --packaging=jar \ @@ -63,4 +63,4 @@ spring init \ --version=1.0.0 \ course-composite-service -cd .. \ No newline at end of file +cd .. diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index b842a31..3b13757 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -1,5 +1,3 @@ -version: '2.1' - services: course: build: ../microservices/course-service diff --git a/images/build.png b/images/build.png new file mode 100644 index 0000000..3614bc8 Binary files /dev/null and b/images/build.png differ diff --git a/images/docker-compose.png b/images/docker-compose.png new file mode 100644 index 0000000..f2f0206 Binary files /dev/null and b/images/docker-compose.png differ diff --git a/images/docker-ps.png b/images/docker-ps.png new file mode 100644 index 0000000..af62936 Binary files /dev/null and b/images/docker-ps.png differ diff --git a/images/eureka.png b/images/eureka.png new file mode 100644 index 0000000..3290f86 Binary files /dev/null and b/images/eureka.png differ diff --git a/images/gateway-routes.png b/images/gateway-routes.png new file mode 100644 index 0000000..a333b0c Binary files /dev/null and b/images/gateway-routes.png differ diff --git a/images/jwt-io.png b/images/jwt-io.png new file mode 100644 index 0000000..a51ea4f Binary files /dev/null and b/images/jwt-io.png differ diff --git a/images/oauth-endpoint.png b/images/oauth-endpoint.png new file mode 100644 index 0000000..79ea653 Binary files /dev/null and b/images/oauth-endpoint.png differ diff --git a/images/swagger-openapi.png b/images/swagger-openapi.png new file mode 100644 index 0000000..e9b9a31 Binary files /dev/null and b/images/swagger-openapi.png differ diff --git a/microservices/course-composite-service/Dockerfile b/microservices/course-composite-service/Dockerfile index d06ca3c..f5249bc 100644 --- a/microservices/course-composite-service/Dockerfile +++ b/microservices/course-composite-service/Dockerfile @@ -1,15 +1,15 @@ # stage 1 # Start with a base image containing Java runtime -# TODO :: Upgrade to slim jre version for 17 once available -FROM openjdk:17-alpine as builder +FROM eclipse-temurin:17-jre-alpine as builder WORKDIR application ARG JAR_FILE=target/*.jar COPY ${JAR_FILE} application.jar RUN java -Djarmode=layertools -jar application.jar extract # the second stage of our build will copy the extracted layers -FROM openjdk:17-alpine +FROM eclipse-temurin:17-jre-alpine WORKDIR application +# Copy extracted layers into the correct locations COPY --from=builder application/dependencies/ ./ COPY --from=builder application/spring-boot-loader/ ./ COPY --from=builder application/snapshot-dependencies/ ./ @@ -17,4 +17,4 @@ COPY --from=builder application/application/ ./ EXPOSE 8080 -ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"] \ No newline at end of file +ENTRYPOINT ["java", "org.springframework.boot.loader.launch.JarLauncher"] \ No newline at end of file diff --git a/microservices/course-composite-service/pom.xml b/microservices/course-composite-service/pom.xml index 8108fde..b87e1bf 100644 --- a/microservices/course-composite-service/pom.xml +++ b/microservices/course-composite-service/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 3.0.5 + 3.4.3 io.javatab.microservices.composite.course @@ -15,7 +15,7 @@ Demo project for Spring Boot 17 - 2022.0.1 + 2024.0.0 @@ -118,8 +118,16 @@ - org.springframework.boot - spring-boot-maven-plugin + org.springframework.boot + spring-boot-maven-plugin + 3.4.3 + + + + repackage + + + diff --git a/microservices/course-composite-service/src/main/java/io/javatab/microservices/composite/course/configuration/SecurityConfig.java b/microservices/course-composite-service/src/main/java/io/javatab/microservices/composite/course/configuration/SecurityConfig.java index 72fcd1a..9ffdf0f 100644 --- a/microservices/course-composite-service/src/main/java/io/javatab/microservices/composite/course/configuration/SecurityConfig.java +++ b/microservices/course-composite-service/src/main/java/io/javatab/microservices/composite/course/configuration/SecurityConfig.java @@ -1,12 +1,14 @@ package io.javatab.microservices.composite.course.configuration; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; import org.springframework.security.config.web.server.ServerHttpSecurity; import org.springframework.security.web.server.SecurityWebFilterChain; import static org.springframework.http.HttpMethod.*; +@Configuration @EnableWebFluxSecurity public class SecurityConfig { diff --git a/microservices/course-service/Dockerfile b/microservices/course-service/Dockerfile index d06ca3c..f2dbab8 100644 --- a/microservices/course-service/Dockerfile +++ b/microservices/course-service/Dockerfile @@ -1,20 +1,22 @@ # stage 1 # Start with a base image containing Java runtime # TODO :: Upgrade to slim jre version for 17 once available -FROM openjdk:17-alpine as builder +FROM eclipse-temurin:17-jre-alpine AS builder WORKDIR application ARG JAR_FILE=target/*.jar COPY ${JAR_FILE} application.jar RUN java -Djarmode=layertools -jar application.jar extract # the second stage of our build will copy the extracted layers -FROM openjdk:17-alpine +FROM eclipse-temurin:17-jre-alpine WORKDIR application +# Copy extracted layers into the correct locations COPY --from=builder application/dependencies/ ./ COPY --from=builder application/spring-boot-loader/ ./ COPY --from=builder application/snapshot-dependencies/ ./ COPY --from=builder application/application/ ./ + EXPOSE 8080 -ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"] \ No newline at end of file +ENTRYPOINT ["java", "org.springframework.boot.loader.launch.JarLauncher"] \ No newline at end of file diff --git a/microservices/course-service/pom.xml b/microservices/course-service/pom.xml index c4485f7..a7a2c82 100644 --- a/microservices/course-service/pom.xml +++ b/microservices/course-service/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 3.0.5 + 3.4.3 io.javatab.microservices.core.course @@ -16,7 +16,7 @@ 17 1.16.2 - 2022.0.1 + 2024.0.0 @@ -105,6 +105,11 @@ org.springframework.boot spring-boot-maven-plugin + + + true + + diff --git a/microservices/search-service/Dockerfile b/microservices/search-service/Dockerfile index d06ca3c..61299b0 100644 --- a/microservices/search-service/Dockerfile +++ b/microservices/search-service/Dockerfile @@ -1,20 +1,21 @@ # stage 1 # Start with a base image containing Java runtime -# TODO :: Upgrade to slim jre version for 17 once available -FROM openjdk:17-alpine as builder +FROM eclipse-temurin:17-jre-alpine as builder WORKDIR application ARG JAR_FILE=target/*.jar COPY ${JAR_FILE} application.jar RUN java -Djarmode=layertools -jar application.jar extract # the second stage of our build will copy the extracted layers -FROM openjdk:17-alpine +FROM eclipse-temurin:17-jre-alpine WORKDIR application +# Copy extracted layers into the correct locations COPY --from=builder application/dependencies/ ./ COPY --from=builder application/spring-boot-loader/ ./ COPY --from=builder application/snapshot-dependencies/ ./ COPY --from=builder application/application/ ./ + EXPOSE 8080 -ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"] \ No newline at end of file +ENTRYPOINT ["java", "org.springframework.boot.loader.launch.JarLauncher"] \ No newline at end of file diff --git a/microservices/search-service/pom.xml b/microservices/search-service/pom.xml index 1608701..be8c6b4 100644 --- a/microservices/search-service/pom.xml +++ b/microservices/search-service/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 3.0.5 + 3.4.3 io.javatab.microservices.core.search @@ -16,7 +16,7 @@ 17 1.16.2 - 2022.0.1 + 2024.0.0 @@ -97,15 +97,17 @@ - - org.springframework.boot spring-boot-maven-plugin + + + true + + - diff --git a/microservices/student-service/Dockerfile b/microservices/student-service/Dockerfile index d06ca3c..61299b0 100644 --- a/microservices/student-service/Dockerfile +++ b/microservices/student-service/Dockerfile @@ -1,20 +1,21 @@ # stage 1 # Start with a base image containing Java runtime -# TODO :: Upgrade to slim jre version for 17 once available -FROM openjdk:17-alpine as builder +FROM eclipse-temurin:17-jre-alpine as builder WORKDIR application ARG JAR_FILE=target/*.jar COPY ${JAR_FILE} application.jar RUN java -Djarmode=layertools -jar application.jar extract # the second stage of our build will copy the extracted layers -FROM openjdk:17-alpine +FROM eclipse-temurin:17-jre-alpine WORKDIR application +# Copy extracted layers into the correct locations COPY --from=builder application/dependencies/ ./ COPY --from=builder application/spring-boot-loader/ ./ COPY --from=builder application/snapshot-dependencies/ ./ COPY --from=builder application/application/ ./ + EXPOSE 8080 -ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"] \ No newline at end of file +ENTRYPOINT ["java", "org.springframework.boot.loader.launch.JarLauncher"] \ No newline at end of file diff --git a/microservices/student-service/pom.xml b/microservices/student-service/pom.xml index e4ab3a7..8af4da0 100644 --- a/microservices/student-service/pom.xml +++ b/microservices/student-service/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 3.0.5 + 3.4.3 io.javatab.microservices.core.student @@ -16,7 +16,7 @@ 17 1.16.2 - 2022.0.1 + 2024.0.0 @@ -102,8 +102,16 @@ - org.springframework.boot - spring-boot-maven-plugin + org.springframework.boot + spring-boot-maven-plugin + 3.4.3 + + + + repackage + + + diff --git a/microservices/vote-service/Dockerfile b/microservices/vote-service/Dockerfile index d06ca3c..61299b0 100644 --- a/microservices/vote-service/Dockerfile +++ b/microservices/vote-service/Dockerfile @@ -1,20 +1,21 @@ # stage 1 # Start with a base image containing Java runtime -# TODO :: Upgrade to slim jre version for 17 once available -FROM openjdk:17-alpine as builder +FROM eclipse-temurin:17-jre-alpine as builder WORKDIR application ARG JAR_FILE=target/*.jar COPY ${JAR_FILE} application.jar RUN java -Djarmode=layertools -jar application.jar extract # the second stage of our build will copy the extracted layers -FROM openjdk:17-alpine +FROM eclipse-temurin:17-jre-alpine WORKDIR application +# Copy extracted layers into the correct locations COPY --from=builder application/dependencies/ ./ COPY --from=builder application/spring-boot-loader/ ./ COPY --from=builder application/snapshot-dependencies/ ./ COPY --from=builder application/application/ ./ + EXPOSE 8080 -ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"] \ No newline at end of file +ENTRYPOINT ["java", "org.springframework.boot.loader.launch.JarLauncher"] \ No newline at end of file diff --git a/microservices/vote-service/pom.xml b/microservices/vote-service/pom.xml index 4484d1e..bab38d0 100644 --- a/microservices/vote-service/pom.xml +++ b/microservices/vote-service/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 3.0.5 + 3.4.3 io.javatab.microservices.core.vote @@ -16,7 +16,7 @@ 17 1.16.2 - 2022.0.1 + 2024.0.0 @@ -94,8 +94,16 @@ - org.springframework.boot - spring-boot-maven-plugin + org.springframework.boot + spring-boot-maven-plugin + 3.4.3 + + + + repackage + + + diff --git a/pom.xml b/pom.xml index 4b8df10..e99c8af 100644 --- a/pom.xml +++ b/pom.xml @@ -15,7 +15,7 @@ org.springframework.boot spring-boot-starter-parent - 3.0.5 + 3.4.3 diff --git a/spring-cloud/.DS_Store b/spring-cloud/.DS_Store new file mode 100644 index 0000000..b9ffbe5 Binary files /dev/null and b/spring-cloud/.DS_Store differ diff --git a/spring-cloud/authorization-server/.gitignore b/spring-cloud/authorization-server/.gitignore new file mode 100644 index 0000000..549e00a --- /dev/null +++ b/spring-cloud/authorization-server/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/spring-cloud/authorization-server/Dockerfile b/spring-cloud/authorization-server/Dockerfile index f73027b..5e372bc 100644 --- a/spring-cloud/authorization-server/Dockerfile +++ b/spring-cloud/authorization-server/Dockerfile @@ -1,22 +1,23 @@ # stage 1 # Start with a base image containing Java runtime -# TODO :: Upgrade to slim jre version for 17 once available -FROM openjdk:17-alpine as builder +FROM eclipse-temurin:17-jre-alpine as builder WORKDIR application ARG JAR_FILE=target/*.jar COPY ${JAR_FILE} application.jar RUN java -Djarmode=layertools -jar application.jar extract # the second stage of our build will copy the extracted layers -FROM openjdk:17-alpine +FROM eclipse-temurin:17-jre-alpine WORKDIR application # We install install curl for health check RUN apk --no-cache add curl +# Copy extracted layers into the correct locations COPY --from=builder application/dependencies/ ./ COPY --from=builder application/spring-boot-loader/ ./ COPY --from=builder application/snapshot-dependencies/ ./ COPY --from=builder application/application/ ./ + EXPOSE 9999 -ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"] \ No newline at end of file +ENTRYPOINT ["java", "org.springframework.boot.loader.launch.JarLauncher"] \ No newline at end of file diff --git a/spring-cloud/authorization-server/pom.xml b/spring-cloud/authorization-server/pom.xml new file mode 100644 index 0000000..97db72d --- /dev/null +++ b/spring-cloud/authorization-server/pom.xml @@ -0,0 +1,92 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.4.3 + + + io.javatab + authorization-server + 1.0.0 + authorization-server + Demo project for Spring Boot + + 17 + 2024.0.0 + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.security + spring-security-oauth2-authorization-server + 1.1.6 + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-client + + + org.springframework.cloud + spring-cloud-starter-config + + + org.springframework.retry + spring-retry + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.security + spring-security-test + test + + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + 3.4.3 + + + + repackage + + + + + + + + diff --git a/spring-cloud/authorization-server/src/main/java/io/javatab/springcloud/auth/AuthorizationServerApplication.java b/spring-cloud/authorization-server/src/main/java/io/javatab/springcloud/auth/AuthorizationServerApplication.java new file mode 100644 index 0000000..4382221 --- /dev/null +++ b/spring-cloud/authorization-server/src/main/java/io/javatab/springcloud/auth/AuthorizationServerApplication.java @@ -0,0 +1,13 @@ +package io.javatab.springcloud.auth; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class AuthorizationServerApplication { + + public static void main(String[] args) { + SpringApplication.run(AuthorizationServerApplication.class, args); + } + +} diff --git a/spring-cloud/authorization-server/src/main/java/io/javatab/springcloud/auth/configuration/AuthorizationServerConfig.java b/spring-cloud/authorization-server/src/main/java/io/javatab/springcloud/auth/configuration/AuthorizationServerConfig.java index 25d76a1..9b61801 100644 --- a/spring-cloud/authorization-server/src/main/java/io/javatab/springcloud/auth/configuration/AuthorizationServerConfig.java +++ b/spring-cloud/authorization-server/src/main/java/io/javatab/springcloud/auth/configuration/AuthorizationServerConfig.java @@ -115,8 +115,8 @@ public RegisteredClientRepository registeredClientRepository() { .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN) .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS) - .redirectUri("https://my.redirect.uri") - .redirectUri("https://localhost:8443/openapi/webjars/swagger-ui/oauth2-redirect.html") + .redirectUri("http://my.redirect.uri") + .redirectUri("http://localhost:8443/openapi/webjars/swagger-ui/oauth2-redirect.html") .scope(OidcScopes.OPENID) .scope("course:read") .scope("course:write") @@ -131,8 +131,8 @@ public RegisteredClientRepository registeredClientRepository() { .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN) .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS) - .redirectUri("https://my.redirect.uri") - .redirectUri("https://localhost:8443/openapi/webjars/swagger-ui/oauth2-redirect.html") + .redirectUri("http://my.redirect.uri") + .redirectUri("http://localhost:8443/openapi/webjars/swagger-ui/oauth2-redirect.html") .scope(OidcScopes.OPENID) .scope("course:read") .clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build()) @@ -157,7 +157,7 @@ public JwtDecoder jwtDecoder(JWKSource jwkSource) { @Bean public AuthorizationServerSettings authorizationServerSettings() { - return AuthorizationServerSettings.builder().issuer("http://auth-server").build(); + return AuthorizationServerSettings.builder().issuer("http://auth-server:9999").build(); } private Consumer> configureAuthenticationValidator() { diff --git a/spring-cloud/config-server/.gitignore b/spring-cloud/config-server/.gitignore new file mode 100644 index 0000000..549e00a --- /dev/null +++ b/spring-cloud/config-server/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/spring-cloud/config-server/Dockerfile b/spring-cloud/config-server/Dockerfile index 26387b7..516df3c 100644 --- a/spring-cloud/config-server/Dockerfile +++ b/spring-cloud/config-server/Dockerfile @@ -1,20 +1,21 @@ # stage 1 # Start with a base image containing Java runtime -# TODO :: Upgrade to slim jre version for 17 once available -FROM openjdk:17-alpine as builder +FROM eclipse-temurin:17-jre-alpine as builder WORKDIR application ARG JAR_FILE=target/*.jar COPY ${JAR_FILE} application.jar RUN java -Djarmode=layertools -jar application.jar extract # the second stage of our build will copy the extracted layers -FROM openjdk:17-alpine +FROM eclipse-temurin:17-jre-alpine WORKDIR application +# Copy extracted layers into the correct locations COPY --from=builder application/dependencies/ ./ COPY --from=builder application/spring-boot-loader/ ./ COPY --from=builder application/snapshot-dependencies/ ./ COPY --from=builder application/application/ ./ + EXPOSE 8888 -ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"] \ No newline at end of file +ENTRYPOINT ["java", "org.springframework.boot.loader.launch.JarLauncher"] \ No newline at end of file diff --git a/spring-cloud/config-server/pom.xml b/spring-cloud/config-server/pom.xml new file mode 100644 index 0000000..0327868 --- /dev/null +++ b/spring-cloud/config-server/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.4.3 + + + io.javatab + config-server + 0.0.1-SNAPSHOT + config-server + Demo project for Spring Boot + + 17 + 2024.0.0 + + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.cloud + spring-cloud-config-server + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.security + spring-security-test + test + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + 3.4.3 + + + + repackage + + + + + + + + diff --git a/spring-cloud/config-server/src/main/java/io/javatab/springcloud/configserver/ConfigServerApplication.java b/spring-cloud/config-server/src/main/java/io/javatab/springcloud/configserver/ConfigServerApplication.java new file mode 100644 index 0000000..cf64d47 --- /dev/null +++ b/spring-cloud/config-server/src/main/java/io/javatab/springcloud/configserver/ConfigServerApplication.java @@ -0,0 +1,23 @@ +package io.javatab.springcloud.configserver; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.config.server.EnableConfigServer; +import org.springframework.context.ConfigurableApplicationContext; + +@SpringBootApplication +@EnableConfigServer +public class ConfigServerApplication { + + private static final Logger LOG = LoggerFactory.getLogger(ConfigServerApplication.class); + + public static void main(String[] args) { + ConfigurableApplicationContext ctx = SpringApplication.run(ConfigServerApplication.class, args); + + String repoLocation = ctx.getEnvironment().getProperty("spring.cloud.config.server.native.search-locations"); + LOG.info("Serving configurations from folder: " + repoLocation); + } + +} diff --git a/spring-cloud/config-server/src/main/resources/application.yml b/spring-cloud/config-server/src/main/resources/application.yml new file mode 100644 index 0000000..94b5f18 --- /dev/null +++ b/spring-cloud/config-server/src/main/resources/application.yml @@ -0,0 +1,14 @@ +server.port: 8888 + +spring.cloud.config.server.native.search-locations: file:${PWD}/config-repo + +# WARNING: Exposing all management endpoints over http should only be used during development, must be locked down in production! +management.endpoint.health.show-details: "ALWAYS" +management.endpoints.web.exposure.include: "*" + +logging: + level: + root: info +--- +spring.config.activate.on-profile: docker,native +spring.cloud.config.server.native.search-locations: file:/config-repo \ No newline at end of file diff --git a/spring-cloud/config-server/src/test/java/io/javatab/springcloud/configserver/ConfigServerApplicationTests.java b/spring-cloud/config-server/src/test/java/io/javatab/springcloud/configserver/ConfigServerApplicationTests.java new file mode 100644 index 0000000..72b1961 --- /dev/null +++ b/spring-cloud/config-server/src/test/java/io/javatab/springcloud/configserver/ConfigServerApplicationTests.java @@ -0,0 +1,10 @@ +package io.javatab.springcloud.configserver; + +import org.springframework.boot.test.context.SpringBootTest; + +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; + +@SpringBootTest(webEnvironment = RANDOM_PORT, properties = {"spring.profiles.active=native"}) +class ConfigServerApplicationTests { + +} diff --git a/spring-cloud/eureka-server/.gitignore b/spring-cloud/eureka-server/.gitignore new file mode 100644 index 0000000..549e00a --- /dev/null +++ b/spring-cloud/eureka-server/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/spring-cloud/eureka-server/Dockerfile b/spring-cloud/eureka-server/Dockerfile index 4ddac48..cf957b4 100644 --- a/spring-cloud/eureka-server/Dockerfile +++ b/spring-cloud/eureka-server/Dockerfile @@ -1,20 +1,21 @@ # stage 1 # Start with a base image containing Java runtime -# TODO :: Upgrade to slim jre version for 17 once available -FROM openjdk:17-alpine as builder +FROM eclipse-temurin:17-jre-alpine as builder WORKDIR application ARG JAR_FILE=target/*.jar COPY ${JAR_FILE} application.jar RUN java -Djarmode=layertools -jar application.jar extract # the second stage of our build will copy the extracted layers -FROM openjdk:17-alpine +FROM eclipse-temurin:17-jre-alpine WORKDIR application +# Copy extracted layers into the correct locations COPY --from=builder application/dependencies/ ./ COPY --from=builder application/spring-boot-loader/ ./ COPY --from=builder application/snapshot-dependencies/ ./ COPY --from=builder application/application/ ./ + EXPOSE 8761 -ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"] \ No newline at end of file +ENTRYPOINT ["java", "org.springframework.boot.loader.launch.JarLauncher"] \ No newline at end of file diff --git a/spring-cloud/eureka-server/pom.xml b/spring-cloud/eureka-server/pom.xml new file mode 100644 index 0000000..3a5414e --- /dev/null +++ b/spring-cloud/eureka-server/pom.xml @@ -0,0 +1,72 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.4.3 + + + io.javatab + eureka-server + 0.0.1-SNAPSHOT + eureka-server + Demo project for Spring Boot + + 17 + 2024.0.0 + + + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-server + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.cloud + spring-cloud-starter-config + + + org.springframework.retry + spring-retry + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + 3.4.3 + + + + repackage + + + + + + + + diff --git a/spring-cloud/eureka-server/src/main/java/io/javatab/springcloud/eurekaserver/EurekaServerApplication.java b/spring-cloud/eureka-server/src/main/java/io/javatab/springcloud/eurekaserver/EurekaServerApplication.java new file mode 100644 index 0000000..23556f0 --- /dev/null +++ b/spring-cloud/eureka-server/src/main/java/io/javatab/springcloud/eurekaserver/EurekaServerApplication.java @@ -0,0 +1,15 @@ +package io.javatab.springcloud.eurekaserver; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; + +@SpringBootApplication +@EnableEurekaServer +public class EurekaServerApplication { + + public static void main(String[] args) { + SpringApplication.run(EurekaServerApplication.class, args); + } + +} diff --git a/spring-cloud/eureka-server/src/test/java/io/javatab/springcloud/eurekaserver/EurekaServerApplicationTests.java b/spring-cloud/eureka-server/src/test/java/io/javatab/springcloud/eurekaserver/EurekaServerApplicationTests.java new file mode 100644 index 0000000..40220da --- /dev/null +++ b/spring-cloud/eureka-server/src/test/java/io/javatab/springcloud/eurekaserver/EurekaServerApplicationTests.java @@ -0,0 +1,11 @@ +package io.javatab.springcloud.eurekaserver; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; + +@SpringBootTest(webEnvironment = RANDOM_PORT, properties = {"spring.cloud.config.enabled=false"}) +class EurekaServerApplicationTests { + +} diff --git a/spring-cloud/gateway/.gitignore b/spring-cloud/gateway/.gitignore new file mode 100644 index 0000000..549e00a --- /dev/null +++ b/spring-cloud/gateway/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/spring-cloud/gateway/Dockerfile b/spring-cloud/gateway/Dockerfile index d06ca3c..2bf8c0f 100644 --- a/spring-cloud/gateway/Dockerfile +++ b/spring-cloud/gateway/Dockerfile @@ -1,14 +1,13 @@ # stage 1 # Start with a base image containing Java runtime -# TODO :: Upgrade to slim jre version for 17 once available -FROM openjdk:17-alpine as builder +FROM eclipse-temurin:17-jre-alpine as builder WORKDIR application ARG JAR_FILE=target/*.jar COPY ${JAR_FILE} application.jar RUN java -Djarmode=layertools -jar application.jar extract # the second stage of our build will copy the extracted layers -FROM openjdk:17-alpine +FROM eclipse-temurin:17-jre-alpine WORKDIR application COPY --from=builder application/dependencies/ ./ COPY --from=builder application/spring-boot-loader/ ./ @@ -17,4 +16,4 @@ COPY --from=builder application/application/ ./ EXPOSE 8080 -ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"] \ No newline at end of file +ENTRYPOINT ["java", "org.springframework.boot.loader.launch.JarLauncher"] \ No newline at end of file diff --git a/spring-cloud/gateway/pom.xml b/spring-cloud/gateway/pom.xml new file mode 100644 index 0000000..ce5b46e --- /dev/null +++ b/spring-cloud/gateway/pom.xml @@ -0,0 +1,94 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.4.3 + + + io.javatab + gateway + 1.0.0 + gateway + Demo project for Spring Boot + + 17 + 2024.0.0 + + + + org.springframework.cloud + spring-cloud-starter-gateway + + + org.springframework.boot + spring-boot-starter-security + + + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-client + + + + org.springframework.security + spring-security-oauth2-resource-server + + + org.springframework.security + spring-security-oauth2-jose + + + + org.springframework.cloud + spring-cloud-starter-config + + + org.springframework.retry + spring-retry + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.boot + spring-boot-starter-actuator + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + 3.4.3 + + + + repackage + + + + + + + + diff --git a/spring-cloud/gateway/src/main/java/io/javatab/springcloud/gateway/GatewayApplication.java b/spring-cloud/gateway/src/main/java/io/javatab/springcloud/gateway/GatewayApplication.java new file mode 100644 index 0000000..c026ee0 --- /dev/null +++ b/spring-cloud/gateway/src/main/java/io/javatab/springcloud/gateway/GatewayApplication.java @@ -0,0 +1,29 @@ +package io.javatab.springcloud.gateway; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.loadbalancer.LoadBalanced; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.web.reactive.function.client.WebClient; + +@SpringBootApplication +public class GatewayApplication { + + private static final Logger LOG = LoggerFactory.getLogger(GatewayApplication.class); + + @Bean + @LoadBalanced + public WebClient.Builder loadBalancedWebClientBuilder() { + return WebClient.builder(); + } + + public static void main(String[] args) { + ConfigurableApplicationContext ctx = SpringApplication.run(GatewayApplication.class, args); + + String testdata = ctx.getEnvironment().getProperty("test1.data"); + LOG.info("testdata ====> " + testdata); + } +} diff --git a/spring-cloud/gateway/src/test/java/io/javatab/springcloud/gateway/GatewayApplicationTests.java b/spring-cloud/gateway/src/test/java/io/javatab/springcloud/gateway/GatewayApplicationTests.java new file mode 100644 index 0000000..2506a72 --- /dev/null +++ b/spring-cloud/gateway/src/test/java/io/javatab/springcloud/gateway/GatewayApplicationTests.java @@ -0,0 +1,18 @@ +package io.javatab.springcloud.gateway; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; + +@SpringBootTest( + webEnvironment = RANDOM_PORT, + properties = { + "spring.security.oauth2.resourceserver.jwt.issuer-uri=", + "spring.security.oauth2.resourceserver.jwt.jwk-set-uri=some-url", + "spring.main.allow-bean-definition-overriding=true", + "eureka.client.enabled=false", + "spring.cloud.config.enabled=false"}) +class GatewayApplicationTests { + +} diff --git a/util/pom.xml b/util/pom.xml index 82b8cf4..3f34614 100644 --- a/util/pom.xml +++ b/util/pom.xml @@ -5,12 +5,13 @@ org.springframework.boot spring-boot-starter-parent - 2.6.6 + 3.4.3 io.javatab.microservices.util util 1.0.0 + jar util Demo project for Spring Boot @@ -40,7 +41,7 @@ - + + + + + org.springframework.boot + spring-boot-maven-plugin + 3.4.3 + + + repackage + none + + repackage + + + + +