diff --git a/.idea/compiler.xml b/.idea/compiler.xml index e764ad6..c85c2fd 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -9,27 +9,43 @@ - - - + + + - + + + + + + + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml index fd9654e..215261b 100644 --- a/.idea/encodings.xml +++ b/.idea/encodings.xml @@ -1,17 +1,18 @@ - - - - - - - - + + + + + + + + + + - - + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 29bad36..7befe12 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -10,10 +10,12 @@ - + diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar new file mode 100644 index 0000000..c1dd12f Binary files /dev/null and b/.mvn/wrapper/maven-wrapper.jar differ diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..b7cb93e --- /dev/null +++ b/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,2 @@ +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.4/apache-maven-3.8.4-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar diff --git a/README.md b/README.md index 0e09f9c..f1f3970 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ # spring-boot-based-microservices -# WIP - Please refer revamp branch for latest code. - 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. + diff --git a/api-gateway-service/.mvn/wrapper/MavenWrapperDownloader.java b/api-gateway-service/.mvn/wrapper/MavenWrapperDownloader.java deleted file mode 100644 index e76d1f3..0000000 --- a/api-gateway-service/.mvn/wrapper/MavenWrapperDownloader.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2007-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import java.net.*; -import java.io.*; -import java.nio.channels.*; -import java.util.Properties; - -public class MavenWrapperDownloader { - - private static final String WRAPPER_VERSION = "0.5.6"; - /** - * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. - */ - private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" - + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; - - /** - * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to - * use instead of the default one. - */ - private static final String MAVEN_WRAPPER_PROPERTIES_PATH = - ".mvn/wrapper/maven-wrapper.properties"; - - /** - * Path where the maven-wrapper.jar will be saved to. - */ - private static final String MAVEN_WRAPPER_JAR_PATH = - ".mvn/wrapper/maven-wrapper.jar"; - - /** - * Name of the property which should be used to override the default download url for the wrapper. - */ - private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; - - public static void main(String args[]) { - System.out.println("- Downloader started"); - File baseDirectory = new File(args[0]); - System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); - - // If the maven-wrapper.properties exists, read it and check if it contains a custom - // wrapperUrl parameter. - File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); - String url = DEFAULT_DOWNLOAD_URL; - if(mavenWrapperPropertyFile.exists()) { - FileInputStream mavenWrapperPropertyFileInputStream = null; - try { - mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); - Properties mavenWrapperProperties = new Properties(); - mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); - url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); - } catch (IOException e) { - System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); - } finally { - try { - if(mavenWrapperPropertyFileInputStream != null) { - mavenWrapperPropertyFileInputStream.close(); - } - } catch (IOException e) { - // Ignore ... - } - } - } - System.out.println("- Downloading from: " + url); - - File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); - if(!outputFile.getParentFile().exists()) { - if(!outputFile.getParentFile().mkdirs()) { - System.out.println( - "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); - } - } - System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); - try { - downloadFileFromURL(url, outputFile); - System.out.println("Done"); - System.exit(0); - } catch (Throwable e) { - System.out.println("- Error downloading"); - e.printStackTrace(); - System.exit(1); - } - } - - private static void downloadFileFromURL(String urlString, File destination) throws Exception { - if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { - String username = System.getenv("MVNW_USERNAME"); - char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); - Authenticator.setDefault(new Authenticator() { - @Override - protected PasswordAuthentication getPasswordAuthentication() { - return new PasswordAuthentication(username, password); - } - }); - } - URL website = new URL(urlString); - ReadableByteChannel rbc; - rbc = Channels.newChannel(website.openStream()); - FileOutputStream fos = new FileOutputStream(destination); - fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); - fos.close(); - rbc.close(); - } - -} diff --git a/api-gateway-service/.mvn/wrapper/maven-wrapper.jar b/api-gateway-service/.mvn/wrapper/maven-wrapper.jar deleted file mode 100644 index 2cc7d4a..0000000 Binary files a/api-gateway-service/.mvn/wrapper/maven-wrapper.jar and /dev/null differ diff --git a/api-gateway-service/.mvn/wrapper/maven-wrapper.properties b/api-gateway-service/.mvn/wrapper/maven-wrapper.properties deleted file mode 100644 index abd303b..0000000 --- a/api-gateway-service/.mvn/wrapper/maven-wrapper.properties +++ /dev/null @@ -1,2 +0,0 @@ -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.2/apache-maven-3.8.2-bin.zip -wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar diff --git a/api-gateway-service/Dockerfile b/api-gateway-service/Dockerfile deleted file mode 100644 index b237fbd..0000000 --- a/api-gateway-service/Dockerfile +++ /dev/null @@ -1,31 +0,0 @@ -#stage 1 -#Start with a base image containing Java runtime -FROM openjdk:11-slim as build - -# Add Maintainer Info -LABEL maintainer="Nasruddin " - -# The application's jar file -ARG JAR_FILE - -# Add the application's jar to the container -COPY ${JAR_FILE} app.jar - -#unpackage jar file -RUN mkdir -p target/dependency && (cd target/dependency; jar -xf /app.jar) - -#stage 2 -#Same Java runtime -FROM openjdk:11-slim - -#Add volume pointing to /tmp -VOLUME /tmp - -#Copy unpackaged application to new container -ARG DEPENDENCY=/target/dependency -COPY --from=build ${DEPENDENCY}/BOOT-INF/lib /app/lib -COPY --from=build ${DEPENDENCY}/META-INF /app/META-INF -COPY --from=build ${DEPENDENCY}/BOOT-INF/classes /app - -#execute the application -ENTRYPOINT ["java","-cp","app:app/lib/*","com.javatab.gatewayservice.ApiGatewayServiceApplication"] \ No newline at end of file diff --git a/api-gateway-service/mvnw.cmd b/api-gateway-service/mvnw.cmd deleted file mode 100644 index c8d4337..0000000 --- a/api-gateway-service/mvnw.cmd +++ /dev/null @@ -1,182 +0,0 @@ -@REM ---------------------------------------------------------------------------- -@REM Licensed to the Apache Software Foundation (ASF) under one -@REM or more contributor license agreements. See the NOTICE file -@REM distributed with this work for additional information -@REM regarding copyright ownership. The ASF licenses this file -@REM to you under the Apache License, Version 2.0 (the -@REM "License"); you may not use this file except in compliance -@REM with the License. You may obtain a copy of the License at -@REM -@REM https://www.apache.org/licenses/LICENSE-2.0 -@REM -@REM Unless required by applicable law or agreed to in writing, -@REM software distributed under the License is distributed on an -@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -@REM KIND, either express or implied. See the License for the -@REM specific language governing permissions and limitations -@REM under the License. -@REM ---------------------------------------------------------------------------- - -@REM ---------------------------------------------------------------------------- -@REM Maven Start Up Batch script -@REM -@REM Required ENV vars: -@REM JAVA_HOME - location of a JDK home dir -@REM -@REM Optional ENV vars -@REM M2_HOME - location of maven2's installed home dir -@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands -@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending -@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven -@REM e.g. to debug Maven itself, use -@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files -@REM ---------------------------------------------------------------------------- - -@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' -@echo off -@REM set title of command window -title %0 -@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' -@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% - -@REM set %HOME% to equivalent of $HOME -if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") - -@REM Execute a user defined script before this one -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre -@REM check for pre script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" -if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" -:skipRcPre - -@setlocal - -set ERROR_CODE=0 - -@REM To isolate internal variables from possible post scripts, we use another setlocal -@setlocal - -@REM ==== START VALIDATION ==== -if not "%JAVA_HOME%" == "" goto OkJHome - -echo. -echo Error: JAVA_HOME not found in your environment. >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -:OkJHome -if exist "%JAVA_HOME%\bin\java.exe" goto init - -echo. -echo Error: JAVA_HOME is set to an invalid directory. >&2 -echo JAVA_HOME = "%JAVA_HOME%" >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -@REM ==== END VALIDATION ==== - -:init - -@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". -@REM Fallback to current working directory if not found. - -set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% -IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir - -set EXEC_DIR=%CD% -set WDIR=%EXEC_DIR% -:findBaseDir -IF EXIST "%WDIR%"\.mvn goto baseDirFound -cd .. -IF "%WDIR%"=="%CD%" goto baseDirNotFound -set WDIR=%CD% -goto findBaseDir - -:baseDirFound -set MAVEN_PROJECTBASEDIR=%WDIR% -cd "%EXEC_DIR%" -goto endDetectBaseDir - -:baseDirNotFound -set MAVEN_PROJECTBASEDIR=%EXEC_DIR% -cd "%EXEC_DIR%" - -:endDetectBaseDir - -IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig - -@setlocal EnableExtensions EnableDelayedExpansion -for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a -@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% - -:endReadAdditionalConfig - -SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" -set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" -set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - -FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( - IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B -) - -@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -@REM This allows using the maven wrapper in projects that prohibit checking in binary data. -if exist %WRAPPER_JAR% ( - if "%MVNW_VERBOSE%" == "true" ( - echo Found %WRAPPER_JAR% - ) -) else ( - if not "%MVNW_REPOURL%" == "" ( - SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - ) - if "%MVNW_VERBOSE%" == "true" ( - echo Couldn't find %WRAPPER_JAR%, downloading it ... - echo Downloading from: %DOWNLOAD_URL% - ) - - powershell -Command "&{"^ - "$webclient = new-object System.Net.WebClient;"^ - "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ - "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ - "}"^ - "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ - "}" - if "%MVNW_VERBOSE%" == "true" ( - echo Finished downloading %WRAPPER_JAR% - ) -) -@REM End of extension - -@REM Provide a "standardized" way to retrieve the CLI args that will -@REM work with both Windows and non-Windows executions. -set MAVEN_CMD_LINE_ARGS=%* - -%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* -if ERRORLEVEL 1 goto error -goto end - -:error -set ERROR_CODE=1 - -:end -@endlocal & set ERROR_CODE=%ERROR_CODE% - -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost -@REM check for post script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" -if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" -:skipRcPost - -@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' -if "%MAVEN_BATCH_PAUSE%" == "on" pause - -if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% - -exit /B %ERROR_CODE% diff --git a/api-gateway-service/pom.xml b/api-gateway-service/pom.xml deleted file mode 100644 index 4c33971..0000000 --- a/api-gateway-service/pom.xml +++ /dev/null @@ -1,134 +0,0 @@ - - - 4.0.0 - - org.springframework.boot - spring-boot-starter-parent - 2.5.4 - - - com.javatab - api-gateway-service - 1.0.0 - api-gateway-service - Gateway Service using spring cloud gateway - - 11 - javatab - 2020.0.3 - - - - org.springframework.boot - spring-boot-starter-actuator - - - org.springframework.cloud - spring-cloud-starter-config - - - org.springframework.cloud - spring-cloud-starter-gateway - - - org.springframework.cloud - spring-cloud-starter-netflix-eureka-client - - - org.springframework.cloud - spring-cloud-starter-ribbon - - - com.netflix.ribbon - ribbon-eureka - - - - - org.json - json - 20190722 - - - org.springframework.cloud - spring-cloud-starter-sleuth - - - org.springframework.cloud - spring-cloud-sleuth-zipkin - - - io.jsonwebtoken - jjwt-api - 0.11.1 - - - io.jsonwebtoken - jjwt-impl - 0.11.1 - runtime - - - io.jsonwebtoken - jjwt-jackson - 0.11.1 - runtime - - - - org.springframework.boot - spring-boot-starter-test - test - - - org.junit.vintage - junit-vintage-engine - - - - - - - - org.springframework.cloud - spring-cloud-dependencies - ${spring-cloud.version} - pom - import - - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - com.spotify - dockerfile-maven-plugin - 1.4.13 - - ${docker.image.prefix}/${project.artifactId} - ${project.version} - - target/${project.build.finalName}.jar - - - - - default - install - - build - - - - - - - - diff --git a/api-gateway-service/src/main/java/com/javatab/gatewayservice/ApiGatewayServiceApplication.java b/api-gateway-service/src/main/java/com/javatab/gatewayservice/ApiGatewayServiceApplication.java deleted file mode 100644 index 64d05fa..0000000 --- a/api-gateway-service/src/main/java/com/javatab/gatewayservice/ApiGatewayServiceApplication.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.javatab.gatewayservice; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.cloud.netflix.eureka.EnableEurekaClient; - -@SpringBootApplication -@EnableEurekaClient -public class ApiGatewayServiceApplication { - - public static void main(String[] args) { - SpringApplication.run(ApiGatewayServiceApplication.class, args); - } - -} diff --git a/api-gateway-service/src/main/java/com/javatab/gatewayservice/filters/AuthenticationFilter.java b/api-gateway-service/src/main/java/com/javatab/gatewayservice/filters/AuthenticationFilter.java deleted file mode 100644 index 076fc1f..0000000 --- a/api-gateway-service/src/main/java/com/javatab/gatewayservice/filters/AuthenticationFilter.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.javatab.gatewayservice.filters; - -import io.jsonwebtoken.Claims; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.cloud.context.config.annotation.RefreshScope; -import org.springframework.cloud.gateway.filter.GatewayFilter; -import org.springframework.cloud.gateway.filter.GatewayFilterChain; -import org.springframework.cloud.gateway.filter.GlobalFilter; -import org.springframework.core.annotation.Order; -import org.springframework.http.HttpStatus; -import org.springframework.http.server.reactive.ServerHttpRequest; -import org.springframework.http.server.reactive.ServerHttpResponse; -import org.springframework.stereotype.Component; -import org.springframework.web.server.ServerWebExchange; -import reactor.core.publisher.Mono; - -@RefreshScope -@Component -@Order(1) -public class AuthenticationFilter implements GlobalFilter { - - @Autowired - private RouterValidator routerValidator;//custom route validator - @Autowired - private JwtUtil jwtUtil; - - @Override - public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { - ServerHttpRequest request = exchange.getRequest(); - - if (routerValidator.isSecured.test(request)) { - if (this.isAuthMissing(request)) - return this.onError(exchange, "Authorization header is missing in request", HttpStatus.UNAUTHORIZED); - - final String token = this.getAuthHeader(request); - - if (jwtUtil.isInvalid(token)) - return this.onError(exchange, "Authorization header is invalid", HttpStatus.UNAUTHORIZED); - - this.populateRequestWithHeaders(exchange, token); - } - return chain.filter(exchange); - } - - - /*PRIVATE*/ - - private Mono onError(ServerWebExchange exchange, String err, HttpStatus httpStatus) { - ServerHttpResponse response = exchange.getResponse(); - response.setStatusCode(httpStatus); - return response.setComplete(); - } - - private String getAuthHeader(ServerHttpRequest request) { - return request.getHeaders().getOrEmpty("Authorization").get(0).replace("Bearer ", ""); - } - - private boolean isAuthMissing(ServerHttpRequest request) { - return !request.getHeaders().containsKey("Authorization"); - } - - private void populateRequestWithHeaders(ServerWebExchange exchange, String token) { - Claims claims = jwtUtil.getAllClaimsFromToken(token); - exchange.getRequest().mutate() - .header("id", String.valueOf(claims.get("id"))) - .header("role", String.valueOf(claims.get("role"))) - .build(); - } -} \ No newline at end of file diff --git a/api-gateway-service/src/main/java/com/javatab/gatewayservice/filters/JwtUtil.java b/api-gateway-service/src/main/java/com/javatab/gatewayservice/filters/JwtUtil.java deleted file mode 100644 index be4de47..0000000 --- a/api-gateway-service/src/main/java/com/javatab/gatewayservice/filters/JwtUtil.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.javatab.gatewayservice.filters; - -import io.jsonwebtoken.Claims; -import io.jsonwebtoken.Jwts; -import io.jsonwebtoken.security.Keys; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; - -import javax.annotation.PostConstruct; -import java.security.Key; -import java.util.Date; - - -@Component -public class JwtUtil { - - @Value("${jwt.secret}") - private String secret; - - private Key key; - - @PostConstruct - public void init(){ - this.key = Keys.hmacShaKeyFor(secret.getBytes()); - } - - public Claims getAllClaimsFromToken(String token) { - return Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token).getBody(); - } - - private boolean isTokenExpired(String token) { - return this.getAllClaimsFromToken(token).getExpiration().before(new Date()); - } - - public boolean isInvalid(String token) { - return this.isTokenExpired(token); - } - -} \ No newline at end of file diff --git a/api-gateway-service/src/main/java/com/javatab/gatewayservice/filters/RouterValidator.java b/api-gateway-service/src/main/java/com/javatab/gatewayservice/filters/RouterValidator.java deleted file mode 100644 index 641cb32..0000000 --- a/api-gateway-service/src/main/java/com/javatab/gatewayservice/filters/RouterValidator.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.javatab.gatewayservice.filters; - -import org.springframework.http.server.reactive.ServerHttpRequest; -import org.springframework.stereotype.Component; - -import java.util.List; -import java.util.function.Predicate; - -@Component -public class RouterValidator { - - public static final List openApiEndpoints= List.of( - "/register", - "/login" - ); - - public Predicate isSecured = - request -> openApiEndpoints - .stream() - .noneMatch(uri -> request.getURI().getPath().contains(uri)); - -} \ No newline at end of file diff --git a/api-gateway-service/src/main/resources/application.yml b/api-gateway-service/src/main/resources/application.yml deleted file mode 100644 index 289c7e3..0000000 --- a/api-gateway-service/src/main/resources/application.yml +++ /dev/null @@ -1,63 +0,0 @@ -server: - port: 8072 - -eureka: - instance: - prefer-ip-address: true - client: - service-url: - default-zone: http://discoveryservice:8761/eureka/ - fetch-registry: true - register-with-eureka: true - -spring: - config: - import: optional:configserver:config-server - cloud: - config: - discovery: - enabled: true - service-id: config-server - loadbalancer: - ribbon: - enabled: false - gateway: - discovery: - locator: - enabled: true - lower-case-service-id: true - routes: - - id: course-service - uri: lb://course-service - predicates: - - Path=/course/** - filters: - - RewritePath=/course/(?.*), /$\{path} - - RemoveRequestHeader= Cookie,Set-Cookie - - - id: auth-service - uri: lb://auth-service - predicates: - - Path=/auth/** - filters: - - RewritePath=/auth/(?.*), /$\{path} - - RemoveRequestHeader= Cookie,Set-Cookie - - application: - name: gateway-servlice - -logging: - level: - com.netflix: WARN - org.springframework.web: WARN - com.javatab: DEBUG - - -jwt: - secret: BvPHGM8C0ia4uOuxxqPD5DTbWC9F9TWvPStp3pb7ARo0oK2mJ3pd3YG4lxA9i8bj6OTbadwezxgeEByY - -management: - endpoints: - web: - exposure: - include: '*' \ No newline at end of file diff --git a/api-gateway-service/.gitignore b/api/.gitignore similarity index 100% rename from api-gateway-service/.gitignore rename to api/.gitignore diff --git a/api/pom.xml b/api/pom.xml new file mode 100644 index 0000000..e5533f0 --- /dev/null +++ b/api/pom.xml @@ -0,0 +1,53 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.6.6 + + + io.javatab.microservices.api + api + 1.0.0 + api + Demo project for Spring Boot + + 17 + + + + org.springframework.boot + spring-boot-starter-webflux + + + org.springdoc + springdoc-openapi-common + 1.5.10 + + + org.springframework.boot + spring-boot-starter-test + test + + + io.projectreactor + reactor-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + exec + + + + + + diff --git a/api/src/main/java/io/javatab/microservices/api/ApiApplication.java b/api/src/main/java/io/javatab/microservices/api/ApiApplication.java new file mode 100644 index 0000000..1c3ed2e --- /dev/null +++ b/api/src/main/java/io/javatab/microservices/api/ApiApplication.java @@ -0,0 +1,13 @@ +package io.javatab.microservices.api; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ApiApplication { + + public static void main(String[] args) { + SpringApplication.run(ApiApplication.class, args); + } + +} diff --git a/api/src/main/java/io/javatab/microservices/api/composite/course/CourseAggregate.java b/api/src/main/java/io/javatab/microservices/api/composite/course/CourseAggregate.java new file mode 100644 index 0000000..df32535 --- /dev/null +++ b/api/src/main/java/io/javatab/microservices/api/composite/course/CourseAggregate.java @@ -0,0 +1,8 @@ +package io.javatab.microservices.api.composite.course; + +import io.javatab.microservices.api.core.student.Student; + +import java.util.List; + +public record CourseAggregate(int courseId, int like, int dislike, int registeredUserNumber, List registerUserDetails) { +} diff --git a/api/src/main/java/io/javatab/microservices/api/composite/course/CourseCompositeService.java b/api/src/main/java/io/javatab/microservices/api/composite/course/CourseCompositeService.java new file mode 100644 index 0000000..c31329c --- /dev/null +++ b/api/src/main/java/io/javatab/microservices/api/composite/course/CourseCompositeService.java @@ -0,0 +1,74 @@ +package io.javatab.microservices.api.composite.course; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.*; +import reactor.core.publisher.Mono; + +@SecurityRequirement(name = "security_auth") +@Tag(name = "CourseComposite", description = "REST API for composite course information.") +public interface CourseCompositeService { + +// TODO:: Update API definitions + /** + * Sample usage: "curl $HOST:$PORT/course-composite/1". + * + * @param courseId of the course + * @return the composite course info, if found, else null + */ + @Operation( + summary = "${open-api.course-composite.get-composite-course.description}", + description = "${open-api.course-composite.get-composite-course.notes}") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "${open-api.responseCodes.ok.description}"), + @ApiResponse(responseCode = "400", description = "${open-api.responseCodes.badRequest.description}"), + @ApiResponse(responseCode = "404", description = "${open-api.responseCodes.notFound.description}"), + @ApiResponse(responseCode = "422", description = "${open-api.responseCodes.unprocessableEntity.description}") + }) + @ResponseStatus(HttpStatus.ACCEPTED) + @PostMapping("/course-composite") + Mono createProduct(@RequestBody CourseAggregate body); + + + /** + * Sample usage: "curl $HOST:$PORT/course-composite/1". + * + * @param courseId of the course + * @return the composite course info, if found, else null + */ + @Operation( + summary = "${open-api.course-composite.get-composite-course.description}", + description = "${open-api.course-composite.get-composite-course.notes}") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "${open-api.responseCodes.ok.description}"), + @ApiResponse(responseCode = "400", description = "${open-api.responseCodes.badRequest.description}"), + @ApiResponse(responseCode = "404", description = "${open-api.responseCodes.notFound.description}"), + @ApiResponse(responseCode = "422", description = "${open-api.responseCodes.unprocessableEntity.description}") + }) + @GetMapping("/course-composite/{courseId}") + Mono getCourse(@PathVariable("courseId") int courseId); + + /** + * Sample usage: "curl $HOST:$PORT/course-composite/1". + * + * @param courseId of the course + * @return the composite course info, if found, else null + */ + @Operation( + summary = "${open-api.course-composite.get-composite-course.description}", + description = "${open-api.course-composite.get-composite-course.notes}") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "${open-api.responseCodes.ok.description}"), + @ApiResponse(responseCode = "400", description = "${open-api.responseCodes.badRequest.description}"), + @ApiResponse(responseCode = "404", description = "${open-api.responseCodes.notFound.description}"), + @ApiResponse(responseCode = "422", description = "${open-api.responseCodes.unprocessableEntity.description}") + }) + @ResponseStatus(HttpStatus.ACCEPTED) + @DeleteMapping("/course-composite/{courseId}") + Mono deleteCourse(@PathVariable("courseId") int courseId); + +} diff --git a/api/src/main/java/io/javatab/microservices/api/core/course/Course.java b/api/src/main/java/io/javatab/microservices/api/core/course/Course.java new file mode 100644 index 0000000..6db2670 --- /dev/null +++ b/api/src/main/java/io/javatab/microservices/api/core/course/Course.java @@ -0,0 +1,4 @@ +package io.javatab.microservices.api.core.course; + +public record Course(int courseId, String courseName, String author, String content, int voteId) { +} diff --git a/api/src/main/java/io/javatab/microservices/api/core/course/CourseService.java b/api/src/main/java/io/javatab/microservices/api/core/course/CourseService.java new file mode 100644 index 0000000..4e9746b --- /dev/null +++ b/api/src/main/java/io/javatab/microservices/api/core/course/CourseService.java @@ -0,0 +1,12 @@ +package io.javatab.microservices.api.core.course; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import reactor.core.publisher.Mono; + +public interface CourseService { + + @GetMapping("/course/{courseId}") + Mono getCourse(@PathVariable(value = "courseId", required = true) int courseId); + +} diff --git a/api/src/main/java/io/javatab/microservices/api/core/search/SearchRecord.java b/api/src/main/java/io/javatab/microservices/api/core/search/SearchRecord.java new file mode 100644 index 0000000..7139b2b --- /dev/null +++ b/api/src/main/java/io/javatab/microservices/api/core/search/SearchRecord.java @@ -0,0 +1,4 @@ +package io.javatab.microservices.api.core.search; + +public record SearchRecord(int courseId, String courseName, int like, int dislike) { +} diff --git a/api/src/main/java/io/javatab/microservices/api/core/search/SearchService.java b/api/src/main/java/io/javatab/microservices/api/core/search/SearchService.java new file mode 100644 index 0000000..894d711 --- /dev/null +++ b/api/src/main/java/io/javatab/microservices/api/core/search/SearchService.java @@ -0,0 +1,11 @@ +package io.javatab.microservices.api.core.search; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import reactor.core.publisher.Mono; + +public interface SearchService { + + @GetMapping("/search") + Mono getCourse(@RequestParam("courseName") String courseName); +} diff --git a/api/src/main/java/io/javatab/microservices/api/core/student/Student.java b/api/src/main/java/io/javatab/microservices/api/core/student/Student.java new file mode 100644 index 0000000..679f831 --- /dev/null +++ b/api/src/main/java/io/javatab/microservices/api/core/student/Student.java @@ -0,0 +1,4 @@ +package io.javatab.microservices.api.core.student; + +public record Student(int studentId, String studentName, String email, String password) { +} diff --git a/api/src/main/java/io/javatab/microservices/api/core/student/StudentService.java b/api/src/main/java/io/javatab/microservices/api/core/student/StudentService.java new file mode 100644 index 0000000..ecaff0d --- /dev/null +++ b/api/src/main/java/io/javatab/microservices/api/core/student/StudentService.java @@ -0,0 +1,11 @@ +package io.javatab.microservices.api.core.student; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import reactor.core.publisher.Mono; + +public interface StudentService { + + @GetMapping("/student/{studentId}") + Mono getStudent(@PathVariable("studentId") String studentId); +} diff --git a/api/src/main/java/io/javatab/microservices/api/core/vote/Vote.java b/api/src/main/java/io/javatab/microservices/api/core/vote/Vote.java new file mode 100644 index 0000000..e14432a --- /dev/null +++ b/api/src/main/java/io/javatab/microservices/api/core/vote/Vote.java @@ -0,0 +1,4 @@ +package io.javatab.microservices.api.core.vote; + +public record Vote(int courseId, int studentId, int like, int dislike) { +} diff --git a/api/src/main/java/io/javatab/microservices/api/core/vote/VoteService.java b/api/src/main/java/io/javatab/microservices/api/core/vote/VoteService.java new file mode 100644 index 0000000..bad21b3 --- /dev/null +++ b/api/src/main/java/io/javatab/microservices/api/core/vote/VoteService.java @@ -0,0 +1,11 @@ +package io.javatab.microservices.api.core.vote; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import reactor.core.publisher.Mono; + +public interface VoteService { + + @GetMapping("/vote/{courseId}") + Mono getVote(@PathVariable("courseId") int courseId); +} diff --git a/api/src/main/java/io/javatab/microservices/api/exceptions/InvalidInputException.java b/api/src/main/java/io/javatab/microservices/api/exceptions/InvalidInputException.java new file mode 100644 index 0000000..a6ad110 --- /dev/null +++ b/api/src/main/java/io/javatab/microservices/api/exceptions/InvalidInputException.java @@ -0,0 +1,17 @@ +package io.javatab.microservices.api.exceptions; + +public class InvalidInputException extends RuntimeException { + public InvalidInputException() {} + + public InvalidInputException(String message) { + super(message); + } + + public InvalidInputException(String message, Throwable cause) { + super(message, cause); + } + + public InvalidInputException(Throwable cause) { + super(cause); + } +} diff --git a/api/src/main/java/io/javatab/microservices/api/exceptions/NotFoundException.java b/api/src/main/java/io/javatab/microservices/api/exceptions/NotFoundException.java new file mode 100644 index 0000000..f459c0b --- /dev/null +++ b/api/src/main/java/io/javatab/microservices/api/exceptions/NotFoundException.java @@ -0,0 +1,17 @@ +package io.javatab.microservices.api.exceptions; + +public class NotFoundException extends RuntimeException { + public NotFoundException() {} + + public NotFoundException(String message) { + super(message); + } + + public NotFoundException(String message, Throwable cause) { + super(message, cause); + } + + public NotFoundException(Throwable cause) { + super(cause); + } +} diff --git a/api/src/main/resources/application.properties b/api/src/main/resources/application.properties new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/api/src/main/resources/application.properties @@ -0,0 +1 @@ + diff --git a/student-service/src/test/java/com/javatab/student/StudentServiceApplicationTests.java b/api/src/test/java/io/javatab/microservices/api/ApiApplicationTests.java similarity index 68% rename from student-service/src/test/java/com/javatab/student/StudentServiceApplicationTests.java rename to api/src/test/java/io/javatab/microservices/api/ApiApplicationTests.java index 011c35a..406c4f7 100644 --- a/student-service/src/test/java/com/javatab/student/StudentServiceApplicationTests.java +++ b/api/src/test/java/io/javatab/microservices/api/ApiApplicationTests.java @@ -1,10 +1,10 @@ -package com.javatab.student; +package io.javatab.microservices.api; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest -class StudentServiceApplicationTests { +class ApiApplicationTests { @Test void contextLoads() { diff --git a/auth-service/.mvn/wrapper/MavenWrapperDownloader.java b/auth-service/.mvn/wrapper/MavenWrapperDownloader.java deleted file mode 100644 index 72308aa..0000000 --- a/auth-service/.mvn/wrapper/MavenWrapperDownloader.java +++ /dev/null @@ -1,114 +0,0 @@ -/* -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you under the Apache License, Version 2.0 (the -"License"); you may not use this file except in compliance -with the License. You may obtain a copy of the License at - - https://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, -software distributed under the License is distributed on an -"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, either express or implied. See the License for the -specific language governing permissions and limitations -under the License. -*/ - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.net.URL; -import java.nio.channels.Channels; -import java.nio.channels.ReadableByteChannel; -import java.util.Properties; - -public class MavenWrapperDownloader { - - /** - * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. - */ - private static final String DEFAULT_DOWNLOAD_URL = - "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"; - - /** - * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to - * use instead of the default one. - */ - private static final String MAVEN_WRAPPER_PROPERTIES_PATH = - ".mvn/wrapper/maven-wrapper.properties"; - - /** - * Path where the maven-wrapper.jar will be saved to. - */ - private static final String MAVEN_WRAPPER_JAR_PATH = - ".mvn/wrapper/maven-wrapper.jar"; - - /** - * Name of the property which should be used to override the default download url for the wrapper. - */ - private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; - - public static void main(String args[]) { - System.out.println("- Downloader started"); - File baseDirectory = new File(args[0]); - System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); - - // If the maven-wrapper.properties exists, read it and check if it contains a custom - // wrapperUrl parameter. - File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); - String url = DEFAULT_DOWNLOAD_URL; - if(mavenWrapperPropertyFile.exists()) { - FileInputStream mavenWrapperPropertyFileInputStream = null; - try { - mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); - Properties mavenWrapperProperties = new Properties(); - mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); - url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); - } catch (IOException e) { - System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); - } finally { - try { - if(mavenWrapperPropertyFileInputStream != null) { - mavenWrapperPropertyFileInputStream.close(); - } - } catch (IOException e) { - // Ignore ... - } - } - } - System.out.println("- Downloading from: : " + url); - - File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); - if(!outputFile.getParentFile().exists()) { - if(!outputFile.getParentFile().mkdirs()) { - System.out.println( - "- ERROR creating output direcrory '" + outputFile.getParentFile().getAbsolutePath() + "'"); - } - } - System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); - try { - downloadFileFromURL(url, outputFile); - System.out.println("Done"); - System.exit(0); - } catch (Throwable e) { - System.out.println("- Error downloading"); - e.printStackTrace(); - System.exit(1); - } - } - - private static void downloadFileFromURL(String urlString, File destination) throws Exception { - URL website = new URL(urlString); - ReadableByteChannel rbc; - rbc = Channels.newChannel(website.openStream()); - FileOutputStream fos = new FileOutputStream(destination); - fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); - fos.close(); - rbc.close(); - } - -} diff --git a/auth-service/.mvn/wrapper/maven-wrapper.jar b/auth-service/.mvn/wrapper/maven-wrapper.jar deleted file mode 100644 index 01e6799..0000000 Binary files a/auth-service/.mvn/wrapper/maven-wrapper.jar and /dev/null differ diff --git a/auth-service/.mvn/wrapper/maven-wrapper.properties b/auth-service/.mvn/wrapper/maven-wrapper.properties deleted file mode 100644 index cd0d451..0000000 --- a/auth-service/.mvn/wrapper/maven-wrapper.properties +++ /dev/null @@ -1 +0,0 @@ -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip diff --git a/auth-service/Dockerfile b/auth-service/Dockerfile deleted file mode 100644 index 9cf4aff..0000000 --- a/auth-service/Dockerfile +++ /dev/null @@ -1,31 +0,0 @@ -#stage 1 -#Start with a base image containing Java runtime -FROM openjdk:11-slim as build - -# Add Maintainer Info -LABEL maintainer="Nasruddin " - -# The application's jar file -ARG JAR_FILE - -# Add the application's jar to the container -COPY ${JAR_FILE} app.jar - -#unpackage jar file -RUN mkdir -p target/dependency && (cd target/dependency; jar -xf /app.jar) - -#stage 2 -#Same Java runtime -FROM openjdk:11-slim - -#Add volume pointing to /tmp -VOLUME /tmp - -#Copy unpackaged application to new container -ARG DEPENDENCY=/target/dependency -COPY --from=build ${DEPENDENCY}/BOOT-INF/lib /app/lib -COPY --from=build ${DEPENDENCY}/META-INF /app/META-INF -COPY --from=build ${DEPENDENCY}/BOOT-INF/classes /app - -#execute the application -ENTRYPOINT ["java","-cp","app:app/lib/*","com.javatab.authservice.AuthServiceApplication"] \ No newline at end of file diff --git a/auth-service/mvnw b/auth-service/mvnw deleted file mode 100755 index 8b9da3b..0000000 --- a/auth-service/mvnw +++ /dev/null @@ -1,286 +0,0 @@ -#!/bin/sh -# ---------------------------------------------------------------------------- -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# ---------------------------------------------------------------------------- - -# ---------------------------------------------------------------------------- -# Maven2 Start Up Batch script -# -# Required ENV vars: -# ------------------ -# JAVA_HOME - location of a JDK home dir -# -# Optional ENV vars -# ----------------- -# M2_HOME - location of maven2's installed home dir -# MAVEN_OPTS - parameters passed to the Java VM when running Maven -# e.g. to debug Maven itself, use -# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -# MAVEN_SKIP_RC - flag to disable loading of mavenrc files -# ---------------------------------------------------------------------------- - -if [ -z "$MAVEN_SKIP_RC" ] ; then - - if [ -f /etc/mavenrc ] ; then - . /etc/mavenrc - fi - - if [ -f "$HOME/.mavenrc" ] ; then - . "$HOME/.mavenrc" - fi - -fi - -# OS specific support. $var _must_ be set to either true or false. -cygwin=false; -darwin=false; -mingw=false -case "`uname`" in - CYGWIN*) cygwin=true ;; - MINGW*) mingw=true;; - Darwin*) darwin=true - # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home - # See https://developer.apple.com/library/mac/qa/qa1170/_index.html - if [ -z "$JAVA_HOME" ]; then - if [ -x "/usr/libexec/java_home" ]; then - export JAVA_HOME="`/usr/libexec/java_home`" - else - export JAVA_HOME="/Library/Java/Home" - fi - fi - ;; -esac - -if [ -z "$JAVA_HOME" ] ; then - if [ -r /etc/gentoo-release ] ; then - JAVA_HOME=`java-config --jre-home` - fi -fi - -if [ -z "$M2_HOME" ] ; then - ## resolve links - $0 may be a link to maven's home - PRG="$0" - - # need this for relative symlinks - while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG="`dirname "$PRG"`/$link" - fi - done - - saveddir=`pwd` - - M2_HOME=`dirname "$PRG"`/.. - - # make it fully qualified - M2_HOME=`cd "$M2_HOME" && pwd` - - cd "$saveddir" - # echo Using m2 at $M2_HOME -fi - -# For Cygwin, ensure paths are in UNIX format before anything is touched -if $cygwin ; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --unix "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --unix "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --unix "$CLASSPATH"` -fi - -# For Mingw, ensure paths are in UNIX format before anything is touched -if $mingw ; then - [ -n "$M2_HOME" ] && - M2_HOME="`(cd "$M2_HOME"; pwd)`" - [ -n "$JAVA_HOME" ] && - JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" - # TODO classpath? -fi - -if [ -z "$JAVA_HOME" ]; then - javaExecutable="`which javac`" - if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then - # readlink(1) is not available as standard on Solaris 10. - readLink=`which readlink` - if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then - if $darwin ; then - javaHome="`dirname \"$javaExecutable\"`" - javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" - else - javaExecutable="`readlink -f \"$javaExecutable\"`" - fi - javaHome="`dirname \"$javaExecutable\"`" - javaHome=`expr "$javaHome" : '\(.*\)/bin'` - JAVA_HOME="$javaHome" - export JAVA_HOME - fi - fi -fi - -if [ -z "$JAVACMD" ] ; then - if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - else - JAVACMD="`which java`" - fi -fi - -if [ ! -x "$JAVACMD" ] ; then - echo "Error: JAVA_HOME is not defined correctly." >&2 - echo " We cannot execute $JAVACMD" >&2 - exit 1 -fi - -if [ -z "$JAVA_HOME" ] ; then - echo "Warning: JAVA_HOME environment variable is not set." -fi - -CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher - -# traverses directory structure from process work directory to filesystem root -# first directory with .mvn subdirectory is considered project base directory -find_maven_basedir() { - - if [ -z "$1" ] - then - echo "Path not specified to find_maven_basedir" - return 1 - fi - - basedir="$1" - wdir="$1" - while [ "$wdir" != '/' ] ; do - if [ -d "$wdir"/.mvn ] ; then - basedir=$wdir - break - fi - # workaround for JBEAP-8937 (on Solaris 10/Sparc) - if [ -d "${wdir}" ]; then - wdir=`cd "$wdir/.."; pwd` - fi - # end of workaround - done - echo "${basedir}" -} - -# concatenates all lines of a file -concat_lines() { - if [ -f "$1" ]; then - echo "$(tr -s '\n' ' ' < "$1")" - fi -} - -BASE_DIR=`find_maven_basedir "$(pwd)"` -if [ -z "$BASE_DIR" ]; then - exit 1; -fi - -########################################################################################## -# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -# This allows using the maven wrapper in projects that prohibit checking in binary data. -########################################################################################## -if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found .mvn/wrapper/maven-wrapper.jar" - fi -else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." - fi - jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" - while IFS="=" read key value; do - case "$key" in (wrapperUrl) jarUrl="$value"; break ;; - esac - done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" - if [ "$MVNW_VERBOSE" = true ]; then - echo "Downloading from: $jarUrl" - fi - wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" - - if command -v wget > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found wget ... using wget" - fi - wget "$jarUrl" -O "$wrapperJarPath" - elif command -v curl > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found curl ... using curl" - fi - curl -o "$wrapperJarPath" "$jarUrl" - else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Falling back to using Java to download" - fi - javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" - if [ -e "$javaClass" ]; then - if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Compiling MavenWrapperDownloader.java ..." - fi - # Compiling the Java class - ("$JAVA_HOME/bin/javac" "$javaClass") - fi - if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - # Running the downloader - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Running MavenWrapperDownloader.java ..." - fi - ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") - fi - fi - fi -fi -########################################################################################## -# End of extension -########################################################################################## - -export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} -if [ "$MVNW_VERBOSE" = true ]; then - echo $MAVEN_PROJECTBASEDIR -fi -MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" - -# For Cygwin, switch paths to Windows format before running java -if $cygwin; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --path --windows "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --windows "$CLASSPATH"` - [ -n "$MAVEN_PROJECTBASEDIR" ] && - MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` -fi - -WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -exec "$JAVACMD" \ - $MAVEN_OPTS \ - -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ - "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ - ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/auth-service/mvnw.cmd b/auth-service/mvnw.cmd deleted file mode 100644 index fef5a8f..0000000 --- a/auth-service/mvnw.cmd +++ /dev/null @@ -1,161 +0,0 @@ -@REM ---------------------------------------------------------------------------- -@REM Licensed to the Apache Software Foundation (ASF) under one -@REM or more contributor license agreements. See the NOTICE file -@REM distributed with this work for additional information -@REM regarding copyright ownership. The ASF licenses this file -@REM to you under the Apache License, Version 2.0 (the -@REM "License"); you may not use this file except in compliance -@REM with the License. You may obtain a copy of the License at -@REM -@REM https://www.apache.org/licenses/LICENSE-2.0 -@REM -@REM Unless required by applicable law or agreed to in writing, -@REM software distributed under the License is distributed on an -@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -@REM KIND, either express or implied. See the License for the -@REM specific language governing permissions and limitations -@REM under the License. -@REM ---------------------------------------------------------------------------- - -@REM ---------------------------------------------------------------------------- -@REM Maven2 Start Up Batch script -@REM -@REM Required ENV vars: -@REM JAVA_HOME - location of a JDK home dir -@REM -@REM Optional ENV vars -@REM M2_HOME - location of maven2's installed home dir -@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands -@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending -@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven -@REM e.g. to debug Maven itself, use -@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files -@REM ---------------------------------------------------------------------------- - -@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' -@echo off -@REM set title of command window -title %0 -@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' -@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% - -@REM set %HOME% to equivalent of $HOME -if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") - -@REM Execute a user defined script before this one -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre -@REM check for pre script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" -if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" -:skipRcPre - -@setlocal - -set ERROR_CODE=0 - -@REM To isolate internal variables from possible post scripts, we use another setlocal -@setlocal - -@REM ==== START VALIDATION ==== -if not "%JAVA_HOME%" == "" goto OkJHome - -echo. -echo Error: JAVA_HOME not found in your environment. >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -:OkJHome -if exist "%JAVA_HOME%\bin\java.exe" goto init - -echo. -echo Error: JAVA_HOME is set to an invalid directory. >&2 -echo JAVA_HOME = "%JAVA_HOME%" >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -@REM ==== END VALIDATION ==== - -:init - -@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". -@REM Fallback to current working directory if not found. - -set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% -IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir - -set EXEC_DIR=%CD% -set WDIR=%EXEC_DIR% -:findBaseDir -IF EXIST "%WDIR%"\.mvn goto baseDirFound -cd .. -IF "%WDIR%"=="%CD%" goto baseDirNotFound -set WDIR=%CD% -goto findBaseDir - -:baseDirFound -set MAVEN_PROJECTBASEDIR=%WDIR% -cd "%EXEC_DIR%" -goto endDetectBaseDir - -:baseDirNotFound -set MAVEN_PROJECTBASEDIR=%EXEC_DIR% -cd "%EXEC_DIR%" - -:endDetectBaseDir - -IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig - -@setlocal EnableExtensions EnableDelayedExpansion -for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a -@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% - -:endReadAdditionalConfig - -SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" -set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" -set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" -FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO ( - IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B -) - -@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -@REM This allows using the maven wrapper in projects that prohibit checking in binary data. -if exist %WRAPPER_JAR% ( - echo Found %WRAPPER_JAR% -) else ( - echo Couldn't find %WRAPPER_JAR%, downloading it ... - echo Downloading from: %DOWNLOAD_URL% - powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')" - echo Finished downloading %WRAPPER_JAR% -) -@REM End of extension - -%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* -if ERRORLEVEL 1 goto error -goto end - -:error -set ERROR_CODE=1 - -:end -@endlocal & set ERROR_CODE=%ERROR_CODE% - -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost -@REM check for post script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" -if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" -:skipRcPost - -@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' -if "%MAVEN_BATCH_PAUSE%" == "on" pause - -if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% - -exit /B %ERROR_CODE% diff --git a/auth-service/pom.xml b/auth-service/pom.xml deleted file mode 100644 index f9ebaa5..0000000 --- a/auth-service/pom.xml +++ /dev/null @@ -1,165 +0,0 @@ - - - 4.0.0 - - - org.springframework.boot - spring-boot-starter-parent - 2.5.4 - - - - com.javatab - auth-service - 1.0.0 - auth-service - Demo project for Spring Boot - - - 11 - javatab - 2020.0.3 - 0.4 - - - - - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.cloud - spring-cloud-starter-netflix-eureka-client - - - io.jsonwebtoken - jjwt-api - 0.11.1 - - - io.jsonwebtoken - jjwt-impl - 0.11.1 - runtime - - - io.jsonwebtoken - jjwt-jackson - 0.11.1 - runtime - - - org.springframework.boot - spring-boot-starter-data-jpa - - - org.springframework.boot - spring-boot-starter-security - - - org.postgresql - postgresql - runtime - - - - org.mindrot - jbcrypt - ${jbcrypt.version} - - - com.google.code.gson - gson - 2.8.2 - - - org.springframework.boot - spring-boot-devtools - runtime - - - org.projectlombok - lombok - true - - - org.springframework.boot - spring-boot-starter-test - test - - - org.springframework.cloud - spring-cloud-starter-config - - - - - jakarta.xml.bind - jakarta.xml.bind-api - 2.3.2 - - - - - org.glassfish.jaxb - jaxb-runtime - 2.3.2 - - - - - org.springframework.cloud - spring-cloud-starter-stream-kafka - - - - - - - org.springframework.cloud - spring-cloud-dependencies - ${spring-cloud.version} - pom - import - - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - com.spotify - dockerfile-maven-plugin - 1.4.13 - - ${docker.image.prefix}/${project.artifactId} - ${project.version} - - target/${project.build.finalName}.jar - - - - - default - install - - build - - - - - - - - diff --git a/auth-service/src/main/java/com/javatab/authservice/AuthServiceApplication.java b/auth-service/src/main/java/com/javatab/authservice/AuthServiceApplication.java deleted file mode 100644 index 9a388fb..0000000 --- a/auth-service/src/main/java/com/javatab/authservice/AuthServiceApplication.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.javatab.authservice; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.cloud.client.discovery.EnableDiscoveryClient; -import org.springframework.cloud.client.loadbalancer.LoadBalanced; -import org.springframework.cloud.netflix.eureka.EnableEurekaClient; -import org.springframework.cloud.stream.annotation.EnableBinding; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.EnableMBeanExport; -import org.springframework.web.client.RestTemplate; - -import java.util.Random; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.function.Supplier; - -@SpringBootApplication -@EnableEurekaClient -public class AuthServiceApplication { - - public static void main(String[] args) { - SpringApplication.run(AuthServiceApplication.class, args); - } - - @Bean - @LoadBalanced - public RestTemplate restTemplate() { - return new RestTemplate(); - } -} \ No newline at end of file diff --git a/auth-service/src/main/java/com/javatab/authservice/controllers/AuthController.java b/auth-service/src/main/java/com/javatab/authservice/controllers/AuthController.java deleted file mode 100644 index 783f939..0000000 --- a/auth-service/src/main/java/com/javatab/authservice/controllers/AuthController.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.javatab.authservice.controllers; - -import com.javatab.authservice.domain.AuthRequest; -import com.javatab.authservice.domain.AuthResponse; -import com.javatab.authservice.domain.User; -import com.javatab.authservice.domain.UserEvent; -import com.javatab.authservice.security.JwtUserDetailService; -import com.javatab.authservice.services.UserService; -import lombok.RequiredArgsConstructor; -import org.springframework.cloud.stream.function.StreamBridge; -import org.springframework.web.bind.annotation.*; - -@RestController -@RequiredArgsConstructor -public class AuthController { - - private final JwtUserDetailService userDetailService; - private final UserService userService; - private final StreamBridge streamBridge; - - static final String USER_CREATED_OUTPUT = "userCreatedOutput"; - - @PostMapping("/login") - public AuthResponse login(@RequestBody AuthRequest request) throws Exception { - return userDetailService.createJwtToken(request); - } - - @PostMapping("/register") - public User registerNewUser(@RequestBody User user) { - User newUser = userService.createNewUser(user); - UserEvent userEvent = UserEvent.builder().username(newUser.getUsername()).email(newUser.getEmail()).build(); - boolean sent = streamBridge.send(USER_CREATED_OUTPUT, userEvent); - System.out.println("Message sent " + sent); - return newUser; - } -} diff --git a/auth-service/src/main/java/com/javatab/authservice/controllers/RoleController.java b/auth-service/src/main/java/com/javatab/authservice/controllers/RoleController.java deleted file mode 100644 index d461711..0000000 --- a/auth-service/src/main/java/com/javatab/authservice/controllers/RoleController.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.javatab.authservice.controllers; - -import com.javatab.authservice.domain.Role; -import com.javatab.authservice.repository.RoleRepository; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@RequestMapping("/roles") -public class RoleController { - - @Autowired - private RoleRepository roleRepository; - - @PostMapping - public Role createNewRole(@RequestBody Role role) { - return roleRepository.save(role); - } -} diff --git a/auth-service/src/main/java/com/javatab/authservice/domain/AuthRequest.java b/auth-service/src/main/java/com/javatab/authservice/domain/AuthRequest.java deleted file mode 100644 index 7cdfaac..0000000 --- a/auth-service/src/main/java/com/javatab/authservice/domain/AuthRequest.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.javatab.authservice.domain; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@AllArgsConstructor -@NoArgsConstructor -@Builder -public class AuthRequest { - - private String email; - private String password; - private String username; -} diff --git a/auth-service/src/main/java/com/javatab/authservice/domain/AuthResponse.java b/auth-service/src/main/java/com/javatab/authservice/domain/AuthResponse.java deleted file mode 100644 index a87d98a..0000000 --- a/auth-service/src/main/java/com/javatab/authservice/domain/AuthResponse.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.javatab.authservice.domain; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@AllArgsConstructor -@NoArgsConstructor -@Builder -public class AuthResponse { - - private String accessToken; - private String refreshToken; - -} diff --git a/auth-service/src/main/java/com/javatab/authservice/domain/Role.java b/auth-service/src/main/java/com/javatab/authservice/domain/Role.java deleted file mode 100644 index 5363902..0000000 --- a/auth-service/src/main/java/com/javatab/authservice/domain/Role.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.javatab.authservice.domain; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import javax.persistence.*; -import java.util.Set; - -@Entity -@Table(name = "roles") -@Data -@NoArgsConstructor -@AllArgsConstructor -public class Role { - - @Id - @Column(name = "role") - private String roleName; - - private String roleDescription; -} diff --git a/auth-service/src/main/java/com/javatab/authservice/domain/User.java b/auth-service/src/main/java/com/javatab/authservice/domain/User.java deleted file mode 100644 index 8bb2fb6..0000000 --- a/auth-service/src/main/java/com/javatab/authservice/domain/User.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.javatab.authservice.domain; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import javax.persistence.*; -import java.util.Set; - -@Entity -@Table(name = "Users") -@Data -@NoArgsConstructor -@AllArgsConstructor -public class User { - - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - private Long id; - - @Column(name = "username") - private String username; - - @Column(name = "password") - private String password; - - @Column(name = "email") - private String email; - - @ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.ALL}) - @JoinTable(name = "user_role", - joinColumns = @JoinColumn(name = "user_id"), - inverseJoinColumns = @JoinColumn(name = "role_id")) - private Set roles; -} - diff --git a/auth-service/src/main/java/com/javatab/authservice/domain/UserEvent.java b/auth-service/src/main/java/com/javatab/authservice/domain/UserEvent.java deleted file mode 100644 index 8a0dfae..0000000 --- a/auth-service/src/main/java/com/javatab/authservice/domain/UserEvent.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.javatab.authservice.domain; - -import lombok.Builder; -import lombok.Data; - -@Data -@Builder -public class UserEvent { - private String username; - private String email; -} diff --git a/auth-service/src/main/java/com/javatab/authservice/repository/RoleRepository.java b/auth-service/src/main/java/com/javatab/authservice/repository/RoleRepository.java deleted file mode 100644 index 698337a..0000000 --- a/auth-service/src/main/java/com/javatab/authservice/repository/RoleRepository.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.javatab.authservice.repository; - -import com.javatab.authservice.domain.Role; -import org.springframework.data.repository.CrudRepository; - -@Repository -public interface RoleRepository extends CrudRepository { -} diff --git a/auth-service/src/main/java/com/javatab/authservice/repository/UserRepository.java b/auth-service/src/main/java/com/javatab/authservice/repository/UserRepository.java deleted file mode 100644 index 5a576f3..0000000 --- a/auth-service/src/main/java/com/javatab/authservice/repository/UserRepository.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.javatab.authservice.repository; - -import com.javatab.authservice.domain.User; -import org.springframework.data.repository.CrudRepository; -import org.springframework.stereotype.Repository; - -import java.util.Optional; - -@Repository -public interface UserRepository extends CrudRepository { - - Optional findByUsername(String username); -} - diff --git a/auth-service/src/main/java/com/javatab/authservice/security/JwtAuthenticationEntryPoint.java b/auth-service/src/main/java/com/javatab/authservice/security/JwtAuthenticationEntryPoint.java deleted file mode 100644 index cc04ef1..0000000 --- a/auth-service/src/main/java/com/javatab/authservice/security/JwtAuthenticationEntryPoint.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.javatab.authservice.security; - -import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.web.AuthenticationEntryPoint; -import org.springframework.stereotype.Component; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; - -@Component -@EnableWebSecurity -@EnableGlobalMethodSecurity(prePostEnabled = true) -public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint { - - @Override - public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException { - httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED); - } -} diff --git a/auth-service/src/main/java/com/javatab/authservice/security/JwtRequestFilter.java b/auth-service/src/main/java/com/javatab/authservice/security/JwtRequestFilter.java deleted file mode 100644 index c4e258c..0000000 --- a/auth-service/src/main/java/com/javatab/authservice/security/JwtRequestFilter.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.javatab.authservice.security; - -import io.jsonwebtoken.ExpiredJwtException; -import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; -import org.springframework.stereotype.Component; -import org.springframework.web.filter.OncePerRequestFilter; - -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; - -@Component -public class JwtRequestFilter extends OncePerRequestFilter { - - private final JwtUtil jwtUtil; - private final JwtUserDetailService userDetailService; - - public JwtRequestFilter(JwtUserDetailService userDetailService, JwtUtil jwtUtil) { - this.userDetailService = userDetailService; - this.jwtUtil = jwtUtil; - } - - @Override - protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException { - final String header = httpServletRequest.getHeader("Authorization"); - String jwtToken = null; - String userName = null; - if (header != null && header.startsWith("Bearer ")) { - jwtToken = header.substring(7); - try { - userName = jwtUtil.getUserNameFromToken(jwtToken); - } catch (IllegalArgumentException e) { - System.out.println("Unable to get JWT token"); - } catch (ExpiredJwtException e) { - System.out.println("Jwt token is expired"); - } - } else { - System.out.println("Jwt token does not start with Bearer"); - } - - if (userName != null && SecurityContextHolder.getContext().getAuthentication() == null) { - UserDetails userDetails = userDetailService.loadUserByUsername(userName); - - if (jwtUtil.validateToken(jwtToken, userDetails)) { - UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); - usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpServletRequest)); - SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken); - } - } - filterChain.doFilter(httpServletRequest, httpServletResponse); - } - -} diff --git a/auth-service/src/main/java/com/javatab/authservice/security/JwtUserDetailService.java b/auth-service/src/main/java/com/javatab/authservice/security/JwtUserDetailService.java deleted file mode 100644 index 881d810..0000000 --- a/auth-service/src/main/java/com/javatab/authservice/security/JwtUserDetailService.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.javatab.authservice.security; - -import com.javatab.authservice.domain.AuthRequest; -import com.javatab.authservice.domain.AuthResponse; -import com.javatab.authservice.domain.User; -import com.javatab.authservice.repository.UserRepository; -import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Lazy; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.authentication.BadCredentialsException; -import org.springframework.security.authentication.DisabledException; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.stereotype.Component; - -import java.util.HashSet; -import java.util.Set; - -@Component -public class JwtUserDetailService implements UserDetailsService { - - private final UserRepository userRepository; - private final JwtUtil jwtUtil; - private final AuthenticationManager authenticationManager; - - public JwtUserDetailService(UserRepository userRepository, JwtUtil jwtUtil, @Lazy AuthenticationManager authenticationManager) { - this.userRepository = userRepository; - this.jwtUtil = jwtUtil; - this.authenticationManager = authenticationManager; - } - - public AuthResponse createJwtToken(AuthRequest jwtRequest) throws Exception{ - String userName = jwtRequest.getUsername(); - String userPassword = jwtRequest.getPassword(); - authenticate(userName, userPassword); - final UserDetails userDetails = loadUserByUsername(userName); - String accessToken = jwtUtil.generate(userDetails, "ACCESS"); - String refreshToken = jwtUtil.generate(userDetails, "REFRESH"); - - return new AuthResponse(accessToken, refreshToken); - } - - @Override - public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { - User user = userRepository.findByUsername(username).get(); - if (user != null) { - return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), getAuthorities(user)); - } else { - throw new UsernameNotFoundException("Username is not valid"); - } - } - - private Set getAuthorities(User user) { - Set authorities = new HashSet<>(); - user.getRoles().forEach(role -> { - authorities.add(new SimpleGrantedAuthority("ROLE_"+role.getRoleName())); - }); - return authorities; - } - - private void authenticate(String userName, String userPassword) throws Exception{ - try { - authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(userName, userPassword)); - } catch (DisabledException e) { - throw new Exception("User is disabled"); - } catch(BadCredentialsException e) { - throw new Exception("Bad credentials from user"); - } - } -} diff --git a/auth-service/src/main/java/com/javatab/authservice/security/JwtUtil.java b/auth-service/src/main/java/com/javatab/authservice/security/JwtUtil.java deleted file mode 100644 index b052954..0000000 --- a/auth-service/src/main/java/com/javatab/authservice/security/JwtUtil.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.javatab.authservice.security; - -import io.jsonwebtoken.Claims; -import io.jsonwebtoken.Jwts; -import io.jsonwebtoken.security.Keys; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.stereotype.Component; - -import javax.annotation.PostConstruct; -import java.security.Key; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; -import java.util.function.Function; - -@Component -public class JwtUtil { - - @Value("${jwt.secret}") - private String secret; - - @Value("${jwt.expiration}") - private String expirationTime; - - private Key key; - - @PostConstruct - public void init() { - this.key = Keys.hmacShaKeyFor(secret.getBytes()); - } - - public Claims getAllClaimsFromToken(String token) { - return Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token).getBody(); - } - - - public Date getExpirationDateFromToken(String token) { - return getAllClaimsFromToken(token).getExpiration(); - } - - private Boolean isTokenExpired(String token) { - final Date expiration = getExpirationDateFromToken(token); - return expiration.before(new Date()); - } - - public String generate(UserDetails user, String type) { - Map claims = new HashMap<>(); - claims.put("id", user.getUsername()); - claims.put("role", user.getAuthorities()); - return doGenerateToken(claims, user.getUsername(), type); - } - - private String doGenerateToken(Map claims, String username, String type) { - long expirationTimeLong; - if ("ACCESS".equals(type)) { - expirationTimeLong = Long.parseLong(expirationTime) * 1000; - } else { - expirationTimeLong = Long.parseLong(expirationTime) * 1000 * 5; - } - final Date createdDate = new Date(); - final Date expirationDate = new Date(createdDate.getTime() + expirationTimeLong); - - return Jwts.builder() - .setClaims(claims) - .setSubject(username) - .setIssuedAt(createdDate) - .setExpiration(expirationDate) - .signWith(key) - .compact(); - } - - public Boolean validateToken(String token, UserDetails userDetails) { - String userName = getUserNameFromToken(token); - return (userName.equals(userDetails.getUsername()) && !isTokenExpired(token)); - } - - public String getUserNameFromToken(String token) { - return getClaimFromToken(token, Claims::getSubject); - } - - private T getClaimFromToken(String token, Function claimResolver) { - final Claims claims = getAllClaimsFromToken(token); - return claimResolver.apply(claims); - } -} \ No newline at end of file diff --git a/auth-service/src/main/java/com/javatab/authservice/security/WebSecurityConfiguration.java b/auth-service/src/main/java/com/javatab/authservice/security/WebSecurityConfiguration.java deleted file mode 100644 index 14ea49c..0000000 --- a/auth-service/src/main/java/com/javatab/authservice/security/WebSecurityConfiguration.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.javatab.authservice.security; - -import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpHeaders; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import org.springframework.security.config.http.SessionCreationPolicy; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; - -@Configuration -@RequiredArgsConstructor -public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter { - - private final JwtAuthenticationEntryPoint jwtAuthenticationEntityPoint; - private final JwtRequestFilter jwtRequestFilter; - private final UserDetailsService jwtService; - - @Bean - @Override - public AuthenticationManager authenticationManagerBean() throws Exception { - return super.authenticationManagerBean(); - } - - @Override - protected void configure(HttpSecurity http) throws Exception { - http.cors(); - http.csrf().disable() - .authorizeRequests() - .antMatchers("/register", "/login").permitAll() - .antMatchers(HttpHeaders.ALLOW).permitAll() - .anyRequest().authenticated() - .and() - .exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntityPoint) - .and() - .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); - - http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class); - - } - - @Bean - public PasswordEncoder passwordEncoder() { - return new BCryptPasswordEncoder(); - } - - @Autowired - public void configureGlobal(AuthenticationManagerBuilder builder) throws Exception { - builder.userDetailsService(jwtService).passwordEncoder(passwordEncoder()); - } -} diff --git a/auth-service/src/main/java/com/javatab/authservice/services/UserService.java b/auth-service/src/main/java/com/javatab/authservice/services/UserService.java deleted file mode 100644 index 03f21de..0000000 --- a/auth-service/src/main/java/com/javatab/authservice/services/UserService.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.javatab.authservice.services; - -import com.javatab.authservice.domain.Role; -import com.javatab.authservice.domain.User; -import com.javatab.authservice.repository.RoleRepository; -import com.javatab.authservice.repository.UserRepository; -import lombok.RequiredArgsConstructor; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.stereotype.Service; - -import java.util.HashSet; -import java.util.Set; - -@Service -@RequiredArgsConstructor -public class UserService { - - private final UserRepository userRepository; - private final PasswordEncoder passwordEncoder; - private final RoleRepository roleRepository; - - public User createNewUser(User user) { - Role role = roleRepository.findById("USER").get(); - Set roles = new HashSet<>(); - roles.add(role); - user.setRoles(roles); - user.setPassword(getEncodedPassword(user.getPassword())); - return userRepository.save(user); - } - - private String getEncodedPassword(String password) { - return passwordEncoder.encode(password); - } -} diff --git a/auth-service/src/main/resources/application.yml b/auth-service/src/main/resources/application.yml deleted file mode 100644 index cfa110b..0000000 --- a/auth-service/src/main/resources/application.yml +++ /dev/null @@ -1,47 +0,0 @@ -spring: - application: - name: auth-service - config: - import: optional:configserver:config-server - cloud: - config: - discovery: - enabled: true - service-id: config-server - - #function: - # defination: userCreatedOutput - stream: - #kafka: - # binder: - # brokers: 192.168.1.8 - # defaultBrokerPort: 9092 - bindings: - userCreatedOutput-out-0: - destination: userCreatedOutput - #binder: kafka - #group: group - #consumer: - # concurrency: 10 - # max-attempts: 3 - - datasource: - url: jdbc:postgresql://postgres_container1:5432/testdb - username: postgres - password: 123 - driver-class-name: org.postgresql.Driver - jpa: - properties: - hibernate: - dialect: org.hibernate.dialect.PostgreSQLDialect - - hibernate: - ddl-auto: update -eureka: - client: - service-url: - default-zone: http://discoveryservice:8761/eureka/ - -jwt: - secret: BvPHGM8C0ia4uOuxxqPD5DTbWC9F9TWvPStp3pb7ARo0oK2mJ3pd3YG4lxA9i8bj6OTbadwezxgeEByY - expiration: 86400 \ No newline at end of file diff --git a/auth-service/src/test/java/com/javatab/authservice/AuthServiceApplicationTests.java b/auth-service/src/test/java/com/javatab/authservice/AuthServiceApplicationTests.java deleted file mode 100644 index 52cabf6..0000000 --- a/auth-service/src/test/java/com/javatab/authservice/AuthServiceApplicationTests.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.javatab.authservice; - -import org.junit.jupiter.api.Disabled; -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest -public class AuthServiceApplicationTests { - - @Disabled - public void contextLoads() { - } - -} diff --git a/config-repo/application.yml b/config-repo/application.yml new file mode 100644 index 0000000..f25c883 --- /dev/null +++ b/config-repo/application.yml @@ -0,0 +1,25 @@ +app: + eureka-username: user + eureka-password: password + eureka-server: localhost + auth-server: localhost + +eureka: + client: + serviceUrl: + defaultZone: "http://${app.eureka-username}:${app.eureka-password}@${app.eureka-server}:8761/eureka/" + initialInstanceInfoReplicationIntervalSeconds: 5 + registryFetchIntervalSeconds: 5 + instance: + leaseRenewalIntervalInSeconds: 5 + leaseExpirationDurationInSeconds: 5 + +# 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: "*" + +--- +spring.config.activate.on-profile: docker +app: + eureka-server: eureka + auth-server: auth-server diff --git a/config-repo/course-composite.yml b/config-repo/course-composite.yml new file mode 100644 index 0000000..64b9ea6 --- /dev/null +++ b/config-repo/course-composite.yml @@ -0,0 +1,102 @@ +server.port: 8016 +spring.application.name: course-composite + +springdoc: + swagger-ui.path: /openapi/swagger-ui.html + api-docs.path: /openapi/v3/api-docs + packagesToScan: io.javatab.microservices.composite.course + pathsToMatch: /** + cache: + disabled: true + swagger-ui: + oauth2-redirect-url: https://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 + +server.forward-headers-strategy: framework + +open-api: + version: 1.0.0 + title: Course Composite API + description: Composite API to fetch data from multiple microservices + termsOfService: + license: + licenseUrl: + externalDocDesc: + externalDocUrl: + contact: + name: Nasruddin + url: + email: webo.geeky@mail.com + + responseCodes: + ok.description: OK + badRequest.description: Bad Request, invalid format of the request. See response message for more information + notFound.description: Not found, the specified id does not exist + unprocessableEntity.description: Unprocessable entity, input parameters caused the processing to fail. See response message for more information + + course-composite: + get-composite-course: + description: Returns a composite view of the specified course id + notes: | + # Normal response + If the requested course id is found the method will return information regarding: + 1. Base course information + 1. Student subscribed + 1. Vote + 1. Service Addresses\n(technical information regarding the addresses of the microservices that created the response) + + # Expected partial and error responses + In the following cases, only a partial response be created (used to simplify testing of error conditions) + + ## Course id 113 + 200 - Ok, but no students will be returned + + ## Non numerical course id + 400 - A **Bad Request** error will be returned + + ## course id 13 + 404 - A **Not Found** error will be returned + + ## Negative course ids + 422 - An **Unprocessable Entity** error will be returned + +app: + eureka-username: user + eureka-password: password + eureka-server: localhost + auth-server: localhost + +eureka: + client: + serviceUrl: + defaultZone: "http://${app.eureka-username}:${app.eureka-password}@${app.eureka-server}:8761/eureka/" + + initialInstanceInfoReplicationIntervalSeconds: 5 + registryFetchIntervalSeconds: 5 + instance: + leaseRenewalIntervalInSeconds: 5 + leaseExpirationDurationInSeconds: 5 + +spring.security.oauth2.resourceserver.jwt.issuer-uri: http://${app.auth-server}:9999 + +logging: + level: + root: INFO + se.magnus: DEBUG + org.springframework.web.server.adapter.HttpWebHandlerAdapter: TRACE + +management.endpoint.health.show-details: "ALWAYS" +management.endpoints.web.exposure.include: "*" + +--- +spring.config.activate.on-profile: docker +server.port: 8080 +app: + eureka-server: eureka + auth-server: auth-server diff --git a/config-repo/course.yml b/config-repo/course.yml new file mode 100644 index 0000000..84070b8 --- /dev/null +++ b/config-repo/course.yml @@ -0,0 +1,27 @@ +server.port: 8012 +spring.application.name: course +logging: + level: + root: INFO + io.javatab.microservices: DEBUG + +app: + eureka-username: user + eureka-password: password + eureka-server: localhost + +eureka: + client: + serviceUrl: + defaultZone: "http://${app.eureka-username}:${app.eureka-password}@${app.eureka-server}:8761/eureka/" + initialInstanceInfoReplicationIntervalSeconds: 5 + registryFetchIntervalSeconds: 5 + instance: + leaseRenewalIntervalInSeconds: 5 + leaseExpirationDurationInSeconds: 5 + +--- +spring.config.activate.on-profile: docker +server.port: 8080 +app.eureka-server: eureka +spring.data.mongodb.host: mongodb \ No newline at end of file diff --git a/config-repo/search.yml b/config-repo/search.yml new file mode 100644 index 0000000..874c517 --- /dev/null +++ b/config-repo/search.yml @@ -0,0 +1,7 @@ +server.port: 8015 + +--- +spring.config.activate.on-profile: docker +server.port: 8080 +spring.elasticsearch: + uris: http://elasticsearch:9200 \ No newline at end of file diff --git a/config-repo/student.yml b/config-repo/student.yml new file mode 100644 index 0000000..45339d0 --- /dev/null +++ b/config-repo/student.yml @@ -0,0 +1,20 @@ +server.port: 8013 +spring: + application: + name: student + datasource: + driver-class-name: org.postgresql.Driver + username: user + password: pwd + url: jdbc:postgresql://localhost:5432/test + jpa: + database-platform: org.hibernate.dialect.PostgreSQLDialect + hibernate: + ddl-auto: update + + +--- +spring.config.activate.on-profile: docker +server.port: 8080 +app.eureka-server: eureka +spring.datasource.url: jdbc:postgresql://postgres:5432/test diff --git a/config-repo/vote.yml b/config-repo/vote.yml new file mode 100644 index 0000000..a0223fd --- /dev/null +++ b/config-repo/vote.yml @@ -0,0 +1,14 @@ +server.port: 8014 +spring.redis: + host: localhost + port: 6379 + client-type: lettuce + +--- +spring.config.activate.on-profile: docker +server.port: 8080 +spring.redis: + host: redis + port: 6379 + client-type: lettuce + diff --git a/config-server/.mvn/wrapper/MavenWrapperDownloader.java b/config-server/.mvn/wrapper/MavenWrapperDownloader.java deleted file mode 100644 index a45eb6b..0000000 --- a/config-server/.mvn/wrapper/MavenWrapperDownloader.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2007-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import java.net.*; -import java.io.*; -import java.nio.channels.*; -import java.util.Properties; - -public class MavenWrapperDownloader { - - private static final String WRAPPER_VERSION = "0.5.6"; - /** - * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. - */ - private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" - + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; - - /** - * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to - * use instead of the default one. - */ - private static final String MAVEN_WRAPPER_PROPERTIES_PATH = - ".mvn/wrapper/maven-wrapper.properties"; - - /** - * Path where the maven-wrapper.jar will be saved to. - */ - private static final String MAVEN_WRAPPER_JAR_PATH = - ".mvn/wrapper/maven-wrapper.jar"; - - /** - * Name of the property which should be used to override the default download url for the wrapper. - */ - private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; - - public static void main(String args[]) { - System.out.println("- Downloader started"); - File baseDirectory = new File(args[0]); - System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); - - // If the maven-wrapper.properties exists, read it and check if it contains a custom - // wrapperUrl parameter. - File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); - String url = DEFAULT_DOWNLOAD_URL; - if (mavenWrapperPropertyFile.exists()) { - FileInputStream mavenWrapperPropertyFileInputStream = null; - try { - mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); - Properties mavenWrapperProperties = new Properties(); - mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); - url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); - } catch (IOException e) { - System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); - } finally { - try { - if (mavenWrapperPropertyFileInputStream != null) { - mavenWrapperPropertyFileInputStream.close(); - } - } catch (IOException e) { - // Ignore ... - } - } - } - System.out.println("- Downloading from: " + url); - - File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); - if (!outputFile.getParentFile().exists()) { - if (!outputFile.getParentFile().mkdirs()) { - System.out.println( - "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); - } - } - System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); - try { - downloadFileFromURL(url, outputFile); - System.out.println("Done"); - System.exit(0); - } catch (Throwable e) { - System.out.println("- Error downloading"); - e.printStackTrace(); - System.exit(1); - } - } - - private static void downloadFileFromURL(String urlString, File destination) throws Exception { - if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { - String username = System.getenv("MVNW_USERNAME"); - char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); - Authenticator.setDefault(new Authenticator() { - @Override - protected PasswordAuthentication getPasswordAuthentication() { - return new PasswordAuthentication(username, password); - } - }); - } - URL website = new URL(urlString); - ReadableByteChannel rbc; - rbc = Channels.newChannel(website.openStream()); - FileOutputStream fos = new FileOutputStream(destination); - fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); - fos.close(); - rbc.close(); - } - -} diff --git a/config-server/.mvn/wrapper/maven-wrapper.jar b/config-server/.mvn/wrapper/maven-wrapper.jar deleted file mode 100644 index 2cc7d4a..0000000 Binary files a/config-server/.mvn/wrapper/maven-wrapper.jar and /dev/null differ diff --git a/config-server/.mvn/wrapper/maven-wrapper.properties b/config-server/.mvn/wrapper/maven-wrapper.properties deleted file mode 100644 index abd303b..0000000 --- a/config-server/.mvn/wrapper/maven-wrapper.properties +++ /dev/null @@ -1,2 +0,0 @@ -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.2/apache-maven-3.8.2-bin.zip -wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar diff --git a/config-server/Dockerfile b/config-server/Dockerfile deleted file mode 100644 index 0bb8a42..0000000 --- a/config-server/Dockerfile +++ /dev/null @@ -1,31 +0,0 @@ -#stage 1 -#Start with a base image containing Java runtime -FROM openjdk:11-slim as build - -# Add Maintainer Info -LABEL maintainer="Nasruddin " - -# The application's jar file -ARG JAR_FILE - -# Add the application's jar to the container -COPY ${JAR_FILE} app.jar - -#unpackage jar file -RUN mkdir -p target/dependency && (cd target/dependency; jar -xf /app.jar) - -#stage 2 -#Same Java runtime -FROM openjdk:11-slim - -#Add volume pointing to /tmp -VOLUME /tmp - -#Copy unpackaged application to new container -ARG DEPENDENCY=/target/dependency -COPY --from=build ${DEPENDENCY}/BOOT-INF/lib /app/lib -COPY --from=build ${DEPENDENCY}/META-INF /app/META-INF -COPY --from=build ${DEPENDENCY}/BOOT-INF/classes /app - -#execute the application -ENTRYPOINT ["java","-cp","app:app/lib/*","com.javatab.configserver.ConfigServerApplication"] \ No newline at end of file diff --git a/config-server/mvnw b/config-server/mvnw deleted file mode 100755 index a16b543..0000000 --- a/config-server/mvnw +++ /dev/null @@ -1,310 +0,0 @@ -#!/bin/sh -# ---------------------------------------------------------------------------- -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# ---------------------------------------------------------------------------- - -# ---------------------------------------------------------------------------- -# Maven Start Up Batch script -# -# Required ENV vars: -# ------------------ -# JAVA_HOME - location of a JDK home dir -# -# Optional ENV vars -# ----------------- -# M2_HOME - location of maven2's installed home dir -# MAVEN_OPTS - parameters passed to the Java VM when running Maven -# e.g. to debug Maven itself, use -# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -# MAVEN_SKIP_RC - flag to disable loading of mavenrc files -# ---------------------------------------------------------------------------- - -if [ -z "$MAVEN_SKIP_RC" ] ; then - - if [ -f /etc/mavenrc ] ; then - . /etc/mavenrc - fi - - if [ -f "$HOME/.mavenrc" ] ; then - . "$HOME/.mavenrc" - fi - -fi - -# OS specific support. $var _must_ be set to either true or false. -cygwin=false; -darwin=false; -mingw=false -case "`uname`" in - CYGWIN*) cygwin=true ;; - MINGW*) mingw=true;; - Darwin*) darwin=true - # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home - # See https://developer.apple.com/library/mac/qa/qa1170/_index.html - if [ -z "$JAVA_HOME" ]; then - if [ -x "/usr/libexec/java_home" ]; then - export JAVA_HOME="`/usr/libexec/java_home`" - else - export JAVA_HOME="/Library/Java/Home" - fi - fi - ;; -esac - -if [ -z "$JAVA_HOME" ] ; then - if [ -r /etc/gentoo-release ] ; then - JAVA_HOME=`java-config --jre-home` - fi -fi - -if [ -z "$M2_HOME" ] ; then - ## resolve links - $0 may be a link to maven's home - PRG="$0" - - # need this for relative symlinks - while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG="`dirname "$PRG"`/$link" - fi - done - - saveddir=`pwd` - - M2_HOME=`dirname "$PRG"`/.. - - # make it fully qualified - M2_HOME=`cd "$M2_HOME" && pwd` - - cd "$saveddir" - # echo Using m2 at $M2_HOME -fi - -# For Cygwin, ensure paths are in UNIX format before anything is touched -if $cygwin ; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --unix "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --unix "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --unix "$CLASSPATH"` -fi - -# For Mingw, ensure paths are in UNIX format before anything is touched -if $mingw ; then - [ -n "$M2_HOME" ] && - M2_HOME="`(cd "$M2_HOME"; pwd)`" - [ -n "$JAVA_HOME" ] && - JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" -fi - -if [ -z "$JAVA_HOME" ]; then - javaExecutable="`which javac`" - if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then - # readlink(1) is not available as standard on Solaris 10. - readLink=`which readlink` - if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then - if $darwin ; then - javaHome="`dirname \"$javaExecutable\"`" - javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" - else - javaExecutable="`readlink -f \"$javaExecutable\"`" - fi - javaHome="`dirname \"$javaExecutable\"`" - javaHome=`expr "$javaHome" : '\(.*\)/bin'` - JAVA_HOME="$javaHome" - export JAVA_HOME - fi - fi -fi - -if [ -z "$JAVACMD" ] ; then - if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - else - JAVACMD="`which java`" - fi -fi - -if [ ! -x "$JAVACMD" ] ; then - echo "Error: JAVA_HOME is not defined correctly." >&2 - echo " We cannot execute $JAVACMD" >&2 - exit 1 -fi - -if [ -z "$JAVA_HOME" ] ; then - echo "Warning: JAVA_HOME environment variable is not set." -fi - -CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher - -# traverses directory structure from process work directory to filesystem root -# first directory with .mvn subdirectory is considered project base directory -find_maven_basedir() { - - if [ -z "$1" ] - then - echo "Path not specified to find_maven_basedir" - return 1 - fi - - basedir="$1" - wdir="$1" - while [ "$wdir" != '/' ] ; do - if [ -d "$wdir"/.mvn ] ; then - basedir=$wdir - break - fi - # workaround for JBEAP-8937 (on Solaris 10/Sparc) - if [ -d "${wdir}" ]; then - wdir=`cd "$wdir/.."; pwd` - fi - # end of workaround - done - echo "${basedir}" -} - -# concatenates all lines of a file -concat_lines() { - if [ -f "$1" ]; then - echo "$(tr -s '\n' ' ' < "$1")" - fi -} - -BASE_DIR=`find_maven_basedir "$(pwd)"` -if [ -z "$BASE_DIR" ]; then - exit 1; -fi - -########################################################################################## -# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -# This allows using the maven wrapper in projects that prohibit checking in binary data. -########################################################################################## -if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found .mvn/wrapper/maven-wrapper.jar" - fi -else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." - fi - if [ -n "$MVNW_REPOURL" ]; then - jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - else - jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - fi - while IFS="=" read key value; do - case "$key" in (wrapperUrl) jarUrl="$value"; break ;; - esac - done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" - if [ "$MVNW_VERBOSE" = true ]; then - echo "Downloading from: $jarUrl" - fi - wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" - if $cygwin; then - wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` - fi - - if command -v wget > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found wget ... using wget" - fi - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - wget "$jarUrl" -O "$wrapperJarPath" - else - wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" - fi - elif command -v curl > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found curl ... using curl" - fi - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - curl -o "$wrapperJarPath" "$jarUrl" -f - else - curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f - fi - - else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Falling back to using Java to download" - fi - javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" - # For Cygwin, switch paths to Windows format before running javac - if $cygwin; then - javaClass=`cygpath --path --windows "$javaClass"` - fi - if [ -e "$javaClass" ]; then - if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Compiling MavenWrapperDownloader.java ..." - fi - # Compiling the Java class - ("$JAVA_HOME/bin/javac" "$javaClass") - fi - if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - # Running the downloader - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Running MavenWrapperDownloader.java ..." - fi - ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") - fi - fi - fi -fi -########################################################################################## -# End of extension -########################################################################################## - -export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} -if [ "$MVNW_VERBOSE" = true ]; then - echo $MAVEN_PROJECTBASEDIR -fi -MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" - -# For Cygwin, switch paths to Windows format before running java -if $cygwin; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --path --windows "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --windows "$CLASSPATH"` - [ -n "$MAVEN_PROJECTBASEDIR" ] && - MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` -fi - -# Provide a "standardized" way to retrieve the CLI args that will -# work with both Windows and non-Windows executions. -MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" -export MAVEN_CMD_LINE_ARGS - -WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -exec "$JAVACMD" \ - $MAVEN_OPTS \ - -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ - "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ - ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/config-server/mvnw.cmd b/config-server/mvnw.cmd deleted file mode 100644 index c8d4337..0000000 --- a/config-server/mvnw.cmd +++ /dev/null @@ -1,182 +0,0 @@ -@REM ---------------------------------------------------------------------------- -@REM Licensed to the Apache Software Foundation (ASF) under one -@REM or more contributor license agreements. See the NOTICE file -@REM distributed with this work for additional information -@REM regarding copyright ownership. The ASF licenses this file -@REM to you under the Apache License, Version 2.0 (the -@REM "License"); you may not use this file except in compliance -@REM with the License. You may obtain a copy of the License at -@REM -@REM https://www.apache.org/licenses/LICENSE-2.0 -@REM -@REM Unless required by applicable law or agreed to in writing, -@REM software distributed under the License is distributed on an -@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -@REM KIND, either express or implied. See the License for the -@REM specific language governing permissions and limitations -@REM under the License. -@REM ---------------------------------------------------------------------------- - -@REM ---------------------------------------------------------------------------- -@REM Maven Start Up Batch script -@REM -@REM Required ENV vars: -@REM JAVA_HOME - location of a JDK home dir -@REM -@REM Optional ENV vars -@REM M2_HOME - location of maven2's installed home dir -@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands -@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending -@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven -@REM e.g. to debug Maven itself, use -@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files -@REM ---------------------------------------------------------------------------- - -@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' -@echo off -@REM set title of command window -title %0 -@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' -@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% - -@REM set %HOME% to equivalent of $HOME -if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") - -@REM Execute a user defined script before this one -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre -@REM check for pre script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" -if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" -:skipRcPre - -@setlocal - -set ERROR_CODE=0 - -@REM To isolate internal variables from possible post scripts, we use another setlocal -@setlocal - -@REM ==== START VALIDATION ==== -if not "%JAVA_HOME%" == "" goto OkJHome - -echo. -echo Error: JAVA_HOME not found in your environment. >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -:OkJHome -if exist "%JAVA_HOME%\bin\java.exe" goto init - -echo. -echo Error: JAVA_HOME is set to an invalid directory. >&2 -echo JAVA_HOME = "%JAVA_HOME%" >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -@REM ==== END VALIDATION ==== - -:init - -@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". -@REM Fallback to current working directory if not found. - -set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% -IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir - -set EXEC_DIR=%CD% -set WDIR=%EXEC_DIR% -:findBaseDir -IF EXIST "%WDIR%"\.mvn goto baseDirFound -cd .. -IF "%WDIR%"=="%CD%" goto baseDirNotFound -set WDIR=%CD% -goto findBaseDir - -:baseDirFound -set MAVEN_PROJECTBASEDIR=%WDIR% -cd "%EXEC_DIR%" -goto endDetectBaseDir - -:baseDirNotFound -set MAVEN_PROJECTBASEDIR=%EXEC_DIR% -cd "%EXEC_DIR%" - -:endDetectBaseDir - -IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig - -@setlocal EnableExtensions EnableDelayedExpansion -for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a -@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% - -:endReadAdditionalConfig - -SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" -set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" -set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - -FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( - IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B -) - -@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -@REM This allows using the maven wrapper in projects that prohibit checking in binary data. -if exist %WRAPPER_JAR% ( - if "%MVNW_VERBOSE%" == "true" ( - echo Found %WRAPPER_JAR% - ) -) else ( - if not "%MVNW_REPOURL%" == "" ( - SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - ) - if "%MVNW_VERBOSE%" == "true" ( - echo Couldn't find %WRAPPER_JAR%, downloading it ... - echo Downloading from: %DOWNLOAD_URL% - ) - - powershell -Command "&{"^ - "$webclient = new-object System.Net.WebClient;"^ - "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ - "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ - "}"^ - "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ - "}" - if "%MVNW_VERBOSE%" == "true" ( - echo Finished downloading %WRAPPER_JAR% - ) -) -@REM End of extension - -@REM Provide a "standardized" way to retrieve the CLI args that will -@REM work with both Windows and non-Windows executions. -set MAVEN_CMD_LINE_ARGS=%* - -%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* -if ERRORLEVEL 1 goto error -goto end - -:error -set ERROR_CODE=1 - -:end -@endlocal & set ERROR_CODE=%ERROR_CODE% - -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost -@REM check for post script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" -if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" -:skipRcPost - -@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' -if "%MAVEN_BATCH_PAUSE%" == "on" pause - -if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% - -exit /B %ERROR_CODE% diff --git a/config-server/pom.xml b/config-server/pom.xml deleted file mode 100644 index 4b7a189..0000000 --- a/config-server/pom.xml +++ /dev/null @@ -1,83 +0,0 @@ - - - 4.0.0 - - org.springframework.boot - spring-boot-starter-parent - 2.5.4 - - - com.javatab - config-server - 1.0.0 - config-server - config-server - - 11 - javatab - 2020.0.3 - - - - org.springframework.boot - spring-boot-starter-actuator - - - org.springframework.cloud - spring-cloud-config-server - - - org.springframework.cloud - spring-cloud-starter-netflix-eureka-client - - - 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 - - - - com.spotify - dockerfile-maven-plugin - 1.4.13 - - ${docker.image.prefix}/${project.artifactId} - ${project.version} - - target/${project.build.finalName}.jar - - - - - default - install - - build - - - - - - - - diff --git a/config-server/src/main/java/com/javatab/configserver/ConfigServerApplication.java b/config-server/src/main/java/com/javatab/configserver/ConfigServerApplication.java deleted file mode 100644 index 8c88b19..0000000 --- a/config-server/src/main/java/com/javatab/configserver/ConfigServerApplication.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.javatab.configserver; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.cloud.config.server.EnableConfigServer; -import org.springframework.cloud.netflix.eureka.EnableEurekaClient; - -@SpringBootApplication -@EnableConfigServer -@EnableEurekaClient -public class ConfigServerApplication { - - public static void main(String[] args) { - SpringApplication.run(ConfigServerApplication.class, args); - } - -} diff --git a/config-server/src/main/resources/bootstrap.yml b/config-server/src/main/resources/bootstrap.yml deleted file mode 100644 index e915503..0000000 --- a/config-server/src/main/resources/bootstrap.yml +++ /dev/null @@ -1,33 +0,0 @@ -spring: - application: - name: config-server - profiles: - active: - - git - cloud: - config: - server: - git: - uri: https://github.com/nasruddin/config.git - discovery: - enabled: true - #service-id: config-server - -server: - port: 8071 - -#Enable all Spring Boot Actuator endpoints. -management: - endpoints: - web: - exposure: - include: "*" - -eureka: - instance: - prefer-ip-address: true - client: - service-url: - defaultZone: ${EUREKA_SERVER:http://localhost:8761/eureka} - fetch-registry: true - register-with-eureka: true \ No newline at end of file diff --git a/config-server/src/test/java/com/javatab/configserver/ConfigServerApplicationTests.java b/config-server/src/test/java/com/javatab/configserver/ConfigServerApplicationTests.java deleted file mode 100644 index ee4142b..0000000 --- a/config-server/src/test/java/com/javatab/configserver/ConfigServerApplicationTests.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.javatab.configserver; - -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest -class ConfigServerApplicationTests { - - @Disabled - void contextLoads() { - } - -} diff --git a/course-service/.mvn/wrapper/MavenWrapperDownloader.java b/course-service/.mvn/wrapper/MavenWrapperDownloader.java deleted file mode 100644 index 72308aa..0000000 --- a/course-service/.mvn/wrapper/MavenWrapperDownloader.java +++ /dev/null @@ -1,114 +0,0 @@ -/* -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you under the Apache License, Version 2.0 (the -"License"); you may not use this file except in compliance -with the License. You may obtain a copy of the License at - - https://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, -software distributed under the License is distributed on an -"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, either express or implied. See the License for the -specific language governing permissions and limitations -under the License. -*/ - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.net.URL; -import java.nio.channels.Channels; -import java.nio.channels.ReadableByteChannel; -import java.util.Properties; - -public class MavenWrapperDownloader { - - /** - * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. - */ - private static final String DEFAULT_DOWNLOAD_URL = - "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"; - - /** - * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to - * use instead of the default one. - */ - private static final String MAVEN_WRAPPER_PROPERTIES_PATH = - ".mvn/wrapper/maven-wrapper.properties"; - - /** - * Path where the maven-wrapper.jar will be saved to. - */ - private static final String MAVEN_WRAPPER_JAR_PATH = - ".mvn/wrapper/maven-wrapper.jar"; - - /** - * Name of the property which should be used to override the default download url for the wrapper. - */ - private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; - - public static void main(String args[]) { - System.out.println("- Downloader started"); - File baseDirectory = new File(args[0]); - System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); - - // If the maven-wrapper.properties exists, read it and check if it contains a custom - // wrapperUrl parameter. - File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); - String url = DEFAULT_DOWNLOAD_URL; - if(mavenWrapperPropertyFile.exists()) { - FileInputStream mavenWrapperPropertyFileInputStream = null; - try { - mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); - Properties mavenWrapperProperties = new Properties(); - mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); - url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); - } catch (IOException e) { - System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); - } finally { - try { - if(mavenWrapperPropertyFileInputStream != null) { - mavenWrapperPropertyFileInputStream.close(); - } - } catch (IOException e) { - // Ignore ... - } - } - } - System.out.println("- Downloading from: : " + url); - - File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); - if(!outputFile.getParentFile().exists()) { - if(!outputFile.getParentFile().mkdirs()) { - System.out.println( - "- ERROR creating output direcrory '" + outputFile.getParentFile().getAbsolutePath() + "'"); - } - } - System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); - try { - downloadFileFromURL(url, outputFile); - System.out.println("Done"); - System.exit(0); - } catch (Throwable e) { - System.out.println("- Error downloading"); - e.printStackTrace(); - System.exit(1); - } - } - - private static void downloadFileFromURL(String urlString, File destination) throws Exception { - URL website = new URL(urlString); - ReadableByteChannel rbc; - rbc = Channels.newChannel(website.openStream()); - FileOutputStream fos = new FileOutputStream(destination); - fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); - fos.close(); - rbc.close(); - } - -} diff --git a/course-service/.mvn/wrapper/maven-wrapper.jar b/course-service/.mvn/wrapper/maven-wrapper.jar deleted file mode 100644 index 01e6799..0000000 Binary files a/course-service/.mvn/wrapper/maven-wrapper.jar and /dev/null differ diff --git a/course-service/.mvn/wrapper/maven-wrapper.properties b/course-service/.mvn/wrapper/maven-wrapper.properties deleted file mode 100644 index cd0d451..0000000 --- a/course-service/.mvn/wrapper/maven-wrapper.properties +++ /dev/null @@ -1 +0,0 @@ -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip diff --git a/course-service/Dockerfile b/course-service/Dockerfile deleted file mode 100644 index 922ab38..0000000 --- a/course-service/Dockerfile +++ /dev/null @@ -1,31 +0,0 @@ -#stage 1 -#Start with a base image containing Java runtime -FROM openjdk:11-slim as build - -# Add Maintainer Info -LABEL maintainer="Nasruddin " - -# The application's jar file -ARG JAR_FILE - -# Add the application's jar to the container -COPY ${JAR_FILE} app.jar - -#unpackage jar file -RUN mkdir -p target/dependency && (cd target/dependency; jar -xf /app.jar) - -#stage 2 -#Same Java runtime -FROM openjdk:11-slim - -#Add volume pointing to /tmp -VOLUME /tmp - -#Copy unpackaged application to new container -ARG DEPENDENCY=/target/dependency -COPY --from=build ${DEPENDENCY}/BOOT-INF/lib /app/lib -COPY --from=build ${DEPENDENCY}/META-INF /app/META-INF -COPY --from=build ${DEPENDENCY}/BOOT-INF/classes /app - -#execute the application -ENTRYPOINT ["java","-cp","app:app/lib/*","com.javatab.courseservice.CourseServiceApplication"] \ No newline at end of file diff --git a/course-service/mvnw b/course-service/mvnw deleted file mode 100755 index 8b9da3b..0000000 --- a/course-service/mvnw +++ /dev/null @@ -1,286 +0,0 @@ -#!/bin/sh -# ---------------------------------------------------------------------------- -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# ---------------------------------------------------------------------------- - -# ---------------------------------------------------------------------------- -# Maven2 Start Up Batch script -# -# Required ENV vars: -# ------------------ -# JAVA_HOME - location of a JDK home dir -# -# Optional ENV vars -# ----------------- -# M2_HOME - location of maven2's installed home dir -# MAVEN_OPTS - parameters passed to the Java VM when running Maven -# e.g. to debug Maven itself, use -# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -# MAVEN_SKIP_RC - flag to disable loading of mavenrc files -# ---------------------------------------------------------------------------- - -if [ -z "$MAVEN_SKIP_RC" ] ; then - - if [ -f /etc/mavenrc ] ; then - . /etc/mavenrc - fi - - if [ -f "$HOME/.mavenrc" ] ; then - . "$HOME/.mavenrc" - fi - -fi - -# OS specific support. $var _must_ be set to either true or false. -cygwin=false; -darwin=false; -mingw=false -case "`uname`" in - CYGWIN*) cygwin=true ;; - MINGW*) mingw=true;; - Darwin*) darwin=true - # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home - # See https://developer.apple.com/library/mac/qa/qa1170/_index.html - if [ -z "$JAVA_HOME" ]; then - if [ -x "/usr/libexec/java_home" ]; then - export JAVA_HOME="`/usr/libexec/java_home`" - else - export JAVA_HOME="/Library/Java/Home" - fi - fi - ;; -esac - -if [ -z "$JAVA_HOME" ] ; then - if [ -r /etc/gentoo-release ] ; then - JAVA_HOME=`java-config --jre-home` - fi -fi - -if [ -z "$M2_HOME" ] ; then - ## resolve links - $0 may be a link to maven's home - PRG="$0" - - # need this for relative symlinks - while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG="`dirname "$PRG"`/$link" - fi - done - - saveddir=`pwd` - - M2_HOME=`dirname "$PRG"`/.. - - # make it fully qualified - M2_HOME=`cd "$M2_HOME" && pwd` - - cd "$saveddir" - # echo Using m2 at $M2_HOME -fi - -# For Cygwin, ensure paths are in UNIX format before anything is touched -if $cygwin ; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --unix "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --unix "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --unix "$CLASSPATH"` -fi - -# For Mingw, ensure paths are in UNIX format before anything is touched -if $mingw ; then - [ -n "$M2_HOME" ] && - M2_HOME="`(cd "$M2_HOME"; pwd)`" - [ -n "$JAVA_HOME" ] && - JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" - # TODO classpath? -fi - -if [ -z "$JAVA_HOME" ]; then - javaExecutable="`which javac`" - if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then - # readlink(1) is not available as standard on Solaris 10. - readLink=`which readlink` - if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then - if $darwin ; then - javaHome="`dirname \"$javaExecutable\"`" - javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" - else - javaExecutable="`readlink -f \"$javaExecutable\"`" - fi - javaHome="`dirname \"$javaExecutable\"`" - javaHome=`expr "$javaHome" : '\(.*\)/bin'` - JAVA_HOME="$javaHome" - export JAVA_HOME - fi - fi -fi - -if [ -z "$JAVACMD" ] ; then - if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - else - JAVACMD="`which java`" - fi -fi - -if [ ! -x "$JAVACMD" ] ; then - echo "Error: JAVA_HOME is not defined correctly." >&2 - echo " We cannot execute $JAVACMD" >&2 - exit 1 -fi - -if [ -z "$JAVA_HOME" ] ; then - echo "Warning: JAVA_HOME environment variable is not set." -fi - -CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher - -# traverses directory structure from process work directory to filesystem root -# first directory with .mvn subdirectory is considered project base directory -find_maven_basedir() { - - if [ -z "$1" ] - then - echo "Path not specified to find_maven_basedir" - return 1 - fi - - basedir="$1" - wdir="$1" - while [ "$wdir" != '/' ] ; do - if [ -d "$wdir"/.mvn ] ; then - basedir=$wdir - break - fi - # workaround for JBEAP-8937 (on Solaris 10/Sparc) - if [ -d "${wdir}" ]; then - wdir=`cd "$wdir/.."; pwd` - fi - # end of workaround - done - echo "${basedir}" -} - -# concatenates all lines of a file -concat_lines() { - if [ -f "$1" ]; then - echo "$(tr -s '\n' ' ' < "$1")" - fi -} - -BASE_DIR=`find_maven_basedir "$(pwd)"` -if [ -z "$BASE_DIR" ]; then - exit 1; -fi - -########################################################################################## -# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -# This allows using the maven wrapper in projects that prohibit checking in binary data. -########################################################################################## -if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found .mvn/wrapper/maven-wrapper.jar" - fi -else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." - fi - jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" - while IFS="=" read key value; do - case "$key" in (wrapperUrl) jarUrl="$value"; break ;; - esac - done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" - if [ "$MVNW_VERBOSE" = true ]; then - echo "Downloading from: $jarUrl" - fi - wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" - - if command -v wget > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found wget ... using wget" - fi - wget "$jarUrl" -O "$wrapperJarPath" - elif command -v curl > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found curl ... using curl" - fi - curl -o "$wrapperJarPath" "$jarUrl" - else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Falling back to using Java to download" - fi - javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" - if [ -e "$javaClass" ]; then - if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Compiling MavenWrapperDownloader.java ..." - fi - # Compiling the Java class - ("$JAVA_HOME/bin/javac" "$javaClass") - fi - if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - # Running the downloader - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Running MavenWrapperDownloader.java ..." - fi - ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") - fi - fi - fi -fi -########################################################################################## -# End of extension -########################################################################################## - -export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} -if [ "$MVNW_VERBOSE" = true ]; then - echo $MAVEN_PROJECTBASEDIR -fi -MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" - -# For Cygwin, switch paths to Windows format before running java -if $cygwin; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --path --windows "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --windows "$CLASSPATH"` - [ -n "$MAVEN_PROJECTBASEDIR" ] && - MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` -fi - -WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -exec "$JAVACMD" \ - $MAVEN_OPTS \ - -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ - "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ - ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/course-service/mvnw.cmd b/course-service/mvnw.cmd deleted file mode 100644 index fef5a8f..0000000 --- a/course-service/mvnw.cmd +++ /dev/null @@ -1,161 +0,0 @@ -@REM ---------------------------------------------------------------------------- -@REM Licensed to the Apache Software Foundation (ASF) under one -@REM or more contributor license agreements. See the NOTICE file -@REM distributed with this work for additional information -@REM regarding copyright ownership. The ASF licenses this file -@REM to you under the Apache License, Version 2.0 (the -@REM "License"); you may not use this file except in compliance -@REM with the License. You may obtain a copy of the License at -@REM -@REM https://www.apache.org/licenses/LICENSE-2.0 -@REM -@REM Unless required by applicable law or agreed to in writing, -@REM software distributed under the License is distributed on an -@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -@REM KIND, either express or implied. See the License for the -@REM specific language governing permissions and limitations -@REM under the License. -@REM ---------------------------------------------------------------------------- - -@REM ---------------------------------------------------------------------------- -@REM Maven2 Start Up Batch script -@REM -@REM Required ENV vars: -@REM JAVA_HOME - location of a JDK home dir -@REM -@REM Optional ENV vars -@REM M2_HOME - location of maven2's installed home dir -@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands -@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending -@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven -@REM e.g. to debug Maven itself, use -@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files -@REM ---------------------------------------------------------------------------- - -@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' -@echo off -@REM set title of command window -title %0 -@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' -@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% - -@REM set %HOME% to equivalent of $HOME -if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") - -@REM Execute a user defined script before this one -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre -@REM check for pre script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" -if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" -:skipRcPre - -@setlocal - -set ERROR_CODE=0 - -@REM To isolate internal variables from possible post scripts, we use another setlocal -@setlocal - -@REM ==== START VALIDATION ==== -if not "%JAVA_HOME%" == "" goto OkJHome - -echo. -echo Error: JAVA_HOME not found in your environment. >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -:OkJHome -if exist "%JAVA_HOME%\bin\java.exe" goto init - -echo. -echo Error: JAVA_HOME is set to an invalid directory. >&2 -echo JAVA_HOME = "%JAVA_HOME%" >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -@REM ==== END VALIDATION ==== - -:init - -@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". -@REM Fallback to current working directory if not found. - -set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% -IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir - -set EXEC_DIR=%CD% -set WDIR=%EXEC_DIR% -:findBaseDir -IF EXIST "%WDIR%"\.mvn goto baseDirFound -cd .. -IF "%WDIR%"=="%CD%" goto baseDirNotFound -set WDIR=%CD% -goto findBaseDir - -:baseDirFound -set MAVEN_PROJECTBASEDIR=%WDIR% -cd "%EXEC_DIR%" -goto endDetectBaseDir - -:baseDirNotFound -set MAVEN_PROJECTBASEDIR=%EXEC_DIR% -cd "%EXEC_DIR%" - -:endDetectBaseDir - -IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig - -@setlocal EnableExtensions EnableDelayedExpansion -for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a -@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% - -:endReadAdditionalConfig - -SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" -set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" -set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" -FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO ( - IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B -) - -@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -@REM This allows using the maven wrapper in projects that prohibit checking in binary data. -if exist %WRAPPER_JAR% ( - echo Found %WRAPPER_JAR% -) else ( - echo Couldn't find %WRAPPER_JAR%, downloading it ... - echo Downloading from: %DOWNLOAD_URL% - powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')" - echo Finished downloading %WRAPPER_JAR% -) -@REM End of extension - -%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* -if ERRORLEVEL 1 goto error -goto end - -:error -set ERROR_CODE=1 - -:end -@endlocal & set ERROR_CODE=%ERROR_CODE% - -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost -@REM check for post script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" -if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" -:skipRcPost - -@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' -if "%MAVEN_BATCH_PAUSE%" == "on" pause - -if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% - -exit /B %ERROR_CODE% diff --git a/course-service/src/main/java/com/javatab/courseservice/CourseServiceApplication.java b/course-service/src/main/java/com/javatab/courseservice/CourseServiceApplication.java deleted file mode 100644 index 93ba1e9..0000000 --- a/course-service/src/main/java/com/javatab/courseservice/CourseServiceApplication.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.javatab.courseservice; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.cloud.netflix.eureka.EnableEurekaClient; - -@SpringBootApplication -@EnableEurekaClient -public class CourseServiceApplication { - - public static void main(String[] args) { - SpringApplication.run(CourseServiceApplication.class, args); - } - -} diff --git a/course-service/src/main/java/com/javatab/courseservice/controller/web/v1/CourseControllerV1.java b/course-service/src/main/java/com/javatab/courseservice/controller/web/v1/CourseControllerV1.java deleted file mode 100644 index ff834cf..0000000 --- a/course-service/src/main/java/com/javatab/courseservice/controller/web/v1/CourseControllerV1.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.javatab.courseservice.controller.web.v1; - -import com.javatab.courseservice.exception.InvalidCourseOrSeatNotAvailableException; -import com.javatab.courseservice.exception.NoCourseAvailableException; -import com.javatab.courseservice.model.Course; -import com.javatab.courseservice.model.StudentCourse; -import com.javatab.courseservice.service.CourseService; -import com.javatab.courseservice.service.StudentService; -import lombok.AllArgsConstructor; -import org.springframework.web.bind.annotation.*; - -import java.util.List; -import java.util.Optional; - -@RestController -@RequestMapping("v1/courses") -@AllArgsConstructor -public class CourseControllerV1 { - - private final CourseService courseService; - private final StudentService studentService; - - @GetMapping("/{username}") - public List getAllCourse(@PathVariable("username") String username) { - if (courseService.findAllNotRegisteredCourses(username).isEmpty()) - throw new NoCourseAvailableException(); - else return courseService.findAllNotRegisteredCourses(username); - - } - - @PostMapping("/register") - public StudentCourse register(@RequestBody StudentCourse studentCourse) { - Optional studentCourseDetails = courseService - .findStudentCourse(studentCourse.getCourseId(), studentCourse.getUsername()); - return courseService.findCourse(studentCourse.getCourseId()) - .filter(course -> course.getAvailableSeats() > 0 && !course.getExpired() && !studentCourseDetails.isPresent()) - .map(course -> courseService.register(studentCourse.getCourseId(), studentCourse.getUsername())) - .orElseThrow(InvalidCourseOrSeatNotAvailableException::new); - } -} \ No newline at end of file diff --git a/course-service/src/main/java/com/javatab/courseservice/controller/web/v1/StudentControllerV1.java b/course-service/src/main/java/com/javatab/courseservice/controller/web/v1/StudentControllerV1.java deleted file mode 100644 index c425beb..0000000 --- a/course-service/src/main/java/com/javatab/courseservice/controller/web/v1/StudentControllerV1.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.javatab.courseservice.controller.web.v1; - - -import com.javatab.courseservice.dto.StudentCourseDto; -import com.javatab.courseservice.exception.InvalidCourseOrSeatNotAvailableException; -import com.javatab.courseservice.exception.NoCourseRegisteredForUserException; -import com.javatab.courseservice.model.Student; -import com.javatab.courseservice.service.StudentService; -import lombok.AllArgsConstructor; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import java.util.List; - -@RestController -@RequestMapping("v1/students") -@AllArgsConstructor -public class StudentControllerV1 { - - private final StudentService studentService; - - - @GetMapping() - List getAllStudents() { - return studentService.getAllStudents(); - } - - @GetMapping("/{username}/courses") - List getRegisteredCourses(@PathVariable("username") String username) { - if (studentService.getAllRegisteredCoursesForAStudent(username).isEmpty()) - throw new NoCourseRegisteredForUserException(); - else return studentService.getAllRegisteredCoursesForAStudent(username); - } - - @GetMapping("/{username}") - Student getStudentByUsername(@PathVariable("username") String username) { - return studentService.getUserByUsername(username) - .orElseThrow(InvalidCourseOrSeatNotAvailableException::new); - } - -} diff --git a/course-service/src/main/java/com/javatab/courseservice/dto/StudentCourseDto.java b/course-service/src/main/java/com/javatab/courseservice/dto/StudentCourseDto.java deleted file mode 100644 index d845f4b..0000000 --- a/course-service/src/main/java/com/javatab/courseservice/dto/StudentCourseDto.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.javatab.courseservice.dto; - -import com.javatab.courseservice.model.Status; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; - -@AllArgsConstructor -@Data -@Builder -public class StudentCourseDto { - private final String courseId; - private final String courseName; - private final String description; - private final Status status; -} diff --git a/course-service/src/main/java/com/javatab/courseservice/exception/InvalidCourseOrSeatNotAvailableAdvice.java b/course-service/src/main/java/com/javatab/courseservice/exception/InvalidCourseOrSeatNotAvailableAdvice.java deleted file mode 100644 index 9138489..0000000 --- a/course-service/src/main/java/com/javatab/courseservice/exception/InvalidCourseOrSeatNotAvailableAdvice.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.javatab.courseservice.exception; - -import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.ControllerAdvice; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.bind.annotation.ResponseBody; -import org.springframework.web.bind.annotation.ResponseStatus; - -@ControllerAdvice -public class InvalidCourseOrSeatNotAvailableAdvice { - - @ResponseBody - @ExceptionHandler(InvalidCourseOrSeatNotAvailableException.class) - @ResponseStatus(HttpStatus.NOT_FOUND) - String courseNotFoundHandler(InvalidCourseOrSeatNotAvailableException ex) { - return ex.getMessage(); - } -} diff --git a/course-service/src/main/java/com/javatab/courseservice/exception/InvalidCourseOrSeatNotAvailableException.java b/course-service/src/main/java/com/javatab/courseservice/exception/InvalidCourseOrSeatNotAvailableException.java deleted file mode 100644 index 9fed073..0000000 --- a/course-service/src/main/java/com/javatab/courseservice/exception/InvalidCourseOrSeatNotAvailableException.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.javatab.courseservice.exception; - -public class InvalidCourseOrSeatNotAvailableException extends RuntimeException { - - public InvalidCourseOrSeatNotAvailableException() { - super("Invalid course or, seat is not available for this course. May be you are trying to re-register the same course." + - " Please contact administrator"); - } -} diff --git a/course-service/src/main/java/com/javatab/courseservice/exception/NoCourseAvailableAdvice.java b/course-service/src/main/java/com/javatab/courseservice/exception/NoCourseAvailableAdvice.java deleted file mode 100644 index 8451706..0000000 --- a/course-service/src/main/java/com/javatab/courseservice/exception/NoCourseAvailableAdvice.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.javatab.courseservice.exception; - -import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.ControllerAdvice; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.bind.annotation.ResponseBody; -import org.springframework.web.bind.annotation.ResponseStatus; - -@ControllerAdvice -public class NoCourseAvailableAdvice { - @ResponseBody - @ExceptionHandler(NoCourseAvailableException.class) - @ResponseStatus(HttpStatus.NOT_FOUND) - String courseNotFoundHandler(NoCourseAvailableException ex) { - return ex.getMessage(); - } -} diff --git a/course-service/src/main/java/com/javatab/courseservice/exception/NoCourseAvailableException.java b/course-service/src/main/java/com/javatab/courseservice/exception/NoCourseAvailableException.java deleted file mode 100644 index 3112b8e..0000000 --- a/course-service/src/main/java/com/javatab/courseservice/exception/NoCourseAvailableException.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.javatab.courseservice.exception; - -public class NoCourseAvailableException extends RuntimeException { - - public NoCourseAvailableException() { - super("No courses available at the moment. Keep looking the awesome app for upcoming courses"); - } -} diff --git a/course-service/src/main/java/com/javatab/courseservice/exception/NoCourseRegisteredForUserAdvice.java b/course-service/src/main/java/com/javatab/courseservice/exception/NoCourseRegisteredForUserAdvice.java deleted file mode 100644 index e30e8b6..0000000 --- a/course-service/src/main/java/com/javatab/courseservice/exception/NoCourseRegisteredForUserAdvice.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.javatab.courseservice.exception; - -import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.ControllerAdvice; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.bind.annotation.ResponseBody; -import org.springframework.web.bind.annotation.ResponseStatus; - -@ControllerAdvice -public class NoCourseRegisteredForUserAdvice { - - @ResponseBody - @ExceptionHandler(NoCourseRegisteredForUserException.class) - @ResponseStatus(HttpStatus.NOT_FOUND) - String registeredCourseNotFoundHandler(NoCourseRegisteredForUserException ex) { - return ex.getMessage(); - } -} diff --git a/course-service/src/main/java/com/javatab/courseservice/exception/NoCourseRegisteredForUserException.java b/course-service/src/main/java/com/javatab/courseservice/exception/NoCourseRegisteredForUserException.java deleted file mode 100644 index 2a12b3d..0000000 --- a/course-service/src/main/java/com/javatab/courseservice/exception/NoCourseRegisteredForUserException.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.javatab.courseservice.exception; - -public class NoCourseRegisteredForUserException extends RuntimeException { - - public NoCourseRegisteredForUserException() { - super("No courses found for the user. May be invalid user id!!!"); - } -} diff --git a/course-service/src/main/java/com/javatab/courseservice/model/Course.java b/course-service/src/main/java/com/javatab/courseservice/model/Course.java deleted file mode 100644 index d6ec682..0000000 --- a/course-service/src/main/java/com/javatab/courseservice/model/Course.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.javatab.courseservice.model; - -import com.fasterxml.jackson.annotation.JsonIgnore; -import lombok.*; - -import javax.persistence.*; -import java.io.Serializable; -import java.util.HashSet; -import java.util.Set; - - -@Entity -@Table(name = "courses") -@Getter -@Setter -@AllArgsConstructor -@NoArgsConstructor -@Builder -public class Course implements Serializable { - - @Id - @Column(name = "course_id", nullable = false) - private String courseId; - - @Column(name = "course_name", nullable = false) - private String courseName; - - @Column(name = "course_desc", nullable = false) - private String description; - - @Column(name = "duration", nullable = false) - private Integer duration; - - @Column(name = "type", nullable = false) - @Enumerated(EnumType.STRING) - private Type type; - - @Column(name = "total_seats", nullable = false) - private Integer totalSeats; - - @Column(name = "available_seats", nullable = false) - private Integer availableSeats; - - @Column(name = "expired", nullable = false) - private Boolean expired; - - @Column(name = "featured", nullable = false) - private Boolean featured; - - @Column(name = "trending", nullable = false) - private Boolean trending; - - @JsonIgnore - @OneToMany(mappedBy="course") - private Set seats = new HashSet<>(); - - @JsonIgnore - @ManyToMany(fetch = FetchType.LAZY, - cascade = { - CascadeType.PERSIST, - CascadeType.MERGE - }, - mappedBy = "courses") - private Set students = new HashSet<>(); -} diff --git a/course-service/src/main/java/com/javatab/courseservice/model/Seat.java b/course-service/src/main/java/com/javatab/courseservice/model/Seat.java deleted file mode 100644 index 7c7b451..0000000 --- a/course-service/src/main/java/com/javatab/courseservice/model/Seat.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.javatab.courseservice.model; - -import lombok.*; - -import javax.persistence.*; -import java.io.Serializable; - -@Entity -@Table(name = "seats") -@Getter -@Setter -@AllArgsConstructor -@NoArgsConstructor -@Builder -public class Seat implements Serializable { - - @Id - @Column(name = "seat_id", nullable = false) - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column(name = "available", nullable = false) - private Boolean isSeatAvailable; - - @Column(name = "type", nullable = false) - @Enumerated(EnumType.STRING) - private SeatType type; - - @ManyToOne - @JoinColumn(name="course_id", nullable=false) - private Course course; -} diff --git a/course-service/src/main/java/com/javatab/courseservice/model/SeatType.java b/course-service/src/main/java/com/javatab/courseservice/model/SeatType.java deleted file mode 100644 index 66b4af4..0000000 --- a/course-service/src/main/java/com/javatab/courseservice/model/SeatType.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.javatab.courseservice.model; - -public enum SeatType { - FRONT, BACK, MIDDLE -} diff --git a/course-service/src/main/java/com/javatab/courseservice/model/Status.java b/course-service/src/main/java/com/javatab/courseservice/model/Status.java deleted file mode 100644 index 2e6e91f..0000000 --- a/course-service/src/main/java/com/javatab/courseservice/model/Status.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.javatab.courseservice.model; - -public enum Status { - PENDING, APPROVED, CANCELLED -} diff --git a/course-service/src/main/java/com/javatab/courseservice/model/Student.java b/course-service/src/main/java/com/javatab/courseservice/model/Student.java deleted file mode 100644 index 74644e8..0000000 --- a/course-service/src/main/java/com/javatab/courseservice/model/Student.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.javatab.courseservice.model; - - -import lombok.*; - -import javax.persistence.*; -import java.io.Serializable; -import java.util.HashSet; -import java.util.Set; - -@Entity -@Table(name = "students") -@Getter -@Setter -@AllArgsConstructor -@NoArgsConstructor -@Builder -public class Student implements Serializable { - - @Id - @Column(name = "student_id", nullable = false) - private String studentId; - - @Column(name = "student_name", nullable = false) - private String studentName; - - @Column(name = "username", nullable = false) - private String username; - - @Column(name = "department", nullable = false) - private String department; - - @Column(name = "semster", nullable = false) - private String semster; - - @Column(name = "join_in", nullable = false) - private String yearOfJoin; - - @ManyToMany(fetch = FetchType.LAZY, - cascade = { - CascadeType.PERSIST, - CascadeType.MERGE - }) - @JoinTable(name = "student_course", - joinColumns = { @JoinColumn(name = "username") }, - inverseJoinColumns = { @JoinColumn(name = "course_id") }) - private Set courses = new HashSet<>(); - - -} diff --git a/course-service/src/main/java/com/javatab/courseservice/model/StudentCourse.java b/course-service/src/main/java/com/javatab/courseservice/model/StudentCourse.java deleted file mode 100644 index edf273e..0000000 --- a/course-service/src/main/java/com/javatab/courseservice/model/StudentCourse.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.javatab.courseservice.model; - -import lombok.*; - -import javax.persistence.*; -import java.io.Serializable; - -@Entity -@Table(name = "student_course") -@Getter -@Setter -@AllArgsConstructor -@NoArgsConstructor -@Builder -public class StudentCourse implements Serializable { - - @Id - @Column(name = "id", nullable = false) - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column(name = "username", nullable = false) - private String username; - - @Column(name = "course_id", nullable = false) - private String courseId; - - @Column(name = "status", nullable = false) - @Enumerated(EnumType.STRING) - private Status status; -} \ No newline at end of file diff --git a/course-service/src/main/java/com/javatab/courseservice/model/Type.java b/course-service/src/main/java/com/javatab/courseservice/model/Type.java deleted file mode 100644 index 6725d9e..0000000 --- a/course-service/src/main/java/com/javatab/courseservice/model/Type.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.javatab.courseservice.model; - -public enum Type { - INTERNAL, EXTERNAL -} diff --git a/course-service/src/main/java/com/javatab/courseservice/repository/CourseRepository.java b/course-service/src/main/java/com/javatab/courseservice/repository/CourseRepository.java deleted file mode 100644 index 3ee5e0c..0000000 --- a/course-service/src/main/java/com/javatab/courseservice/repository/CourseRepository.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.javatab.courseservice.repository; - -import com.javatab.courseservice.model.Course; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; -import org.springframework.stereotype.Repository; - -import java.util.List; - -@Repository -public interface CourseRepository extends JpaRepository { - - @Query( "SELECT c FROM Course c WHERE " - + "c.courseId NOT IN (SELECT sc.courseId FROM " - + "StudentCourse sc where sc.username = :username)" - ) - List findAllCourseNotRegistered(@Param("username") String username); -} diff --git a/course-service/src/main/java/com/javatab/courseservice/repository/SeatRepository.java b/course-service/src/main/java/com/javatab/courseservice/repository/SeatRepository.java deleted file mode 100644 index 0b35a57..0000000 --- a/course-service/src/main/java/com/javatab/courseservice/repository/SeatRepository.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.javatab.courseservice.repository; - -import com.javatab.courseservice.model.Seat; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -@Repository -public interface SeatRepository extends JpaRepository { -} diff --git a/course-service/src/main/java/com/javatab/courseservice/repository/StudentCourseRepository.java b/course-service/src/main/java/com/javatab/courseservice/repository/StudentCourseRepository.java deleted file mode 100644 index 952982e..0000000 --- a/course-service/src/main/java/com/javatab/courseservice/repository/StudentCourseRepository.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.javatab.courseservice.repository; - -import com.javatab.courseservice.dto.StudentCourseDto; -import com.javatab.courseservice.model.StudentCourse; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; -import org.springframework.stereotype.Repository; - -import java.util.List; -import java.util.Optional; - -@Repository -public interface StudentCourseRepository extends JpaRepository { - @Query("SELECT new com.javatab.courseservice.dto.StudentCourseDto(c.courseId, c.courseName, c.description, sc.status) " - + "FROM Course c INNER JOIN StudentCourse sc " - + "ON c.courseId = sc.courseId " - + "WHERE sc.username = :username") - List findAllCoursesRegistered(@Param("username") String username); - - @Query("SELECT sc " - + "FROM StudentCourse sc where sc.courseId = :courseId " - + "AND sc.username = :username") - Optional findByCourseIdAndStudentId(@Param("courseId") String courseId, - @Param("username") String username); -} diff --git a/course-service/src/main/java/com/javatab/courseservice/repository/StudentRepository.java b/course-service/src/main/java/com/javatab/courseservice/repository/StudentRepository.java deleted file mode 100644 index 7479a63..0000000 --- a/course-service/src/main/java/com/javatab/courseservice/repository/StudentRepository.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.javatab.courseservice.repository; - - -import com.javatab.courseservice.model.Student; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.repository.query.Param; -import org.springframework.stereotype.Repository; - -import java.util.Optional; - -@Repository -public interface StudentRepository extends JpaRepository { - Optional findByUsername(@Param("username") String username); -} diff --git a/course-service/src/main/java/com/javatab/courseservice/service/CourseService.java b/course-service/src/main/java/com/javatab/courseservice/service/CourseService.java deleted file mode 100644 index 65175b8..0000000 --- a/course-service/src/main/java/com/javatab/courseservice/service/CourseService.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.javatab.courseservice.service; - -import com.javatab.courseservice.model.Course; -import com.javatab.courseservice.model.Status; -import com.javatab.courseservice.model.StudentCourse; -import com.javatab.courseservice.repository.CourseRepository; -import com.javatab.courseservice.repository.StudentCourseRepository; -import lombok.AllArgsConstructor; -import org.springframework.stereotype.Service; - -import java.util.List; -import java.util.Optional; - -@Service -@AllArgsConstructor -public class CourseService { - - private final CourseRepository courseRepository; - private final StudentCourseRepository studentCourseRepository; - - public List getAllCourse(){ - return this.courseRepository.findAll(); - } - - public StudentCourse register(String courseId, String username) { - StudentCourse studentCourse = StudentCourse.builder() - .courseId(courseId) - .username(username) - .status(Status.PENDING) - .build(); - courseRepository.findById(courseId).ifPresent(course -> { - course.setAvailableSeats(course.getAvailableSeats() - 1); - courseRepository.save(course); - }); - return studentCourseRepository.save(studentCourse); - } - - public List findAllNotRegisteredCourses(String username) { - return courseRepository.findAllCourseNotRegistered(username); - } - - public Optional findCourse(String courseId) { - return courseRepository.findById(courseId); - } - - public Optional findStudentCourse(String courseId, String studentUsername) { - return studentCourseRepository.findByCourseIdAndStudentId(courseId, studentUsername); - } -} diff --git a/course-service/src/main/java/com/javatab/courseservice/service/SeatService.java b/course-service/src/main/java/com/javatab/courseservice/service/SeatService.java deleted file mode 100644 index cb2dc6a..0000000 --- a/course-service/src/main/java/com/javatab/courseservice/service/SeatService.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.javatab.courseservice.service; - -import com.javatab.courseservice.repository.SeatRepository; -import lombok.AllArgsConstructor; -import org.springframework.stereotype.Service; - -@Service -@AllArgsConstructor -public class SeatService { - - private SeatRepository seatRepository; - -} diff --git a/course-service/src/main/java/com/javatab/courseservice/service/StudentService.java b/course-service/src/main/java/com/javatab/courseservice/service/StudentService.java deleted file mode 100644 index 07e8428..0000000 --- a/course-service/src/main/java/com/javatab/courseservice/service/StudentService.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.javatab.courseservice.service; - -import com.javatab.courseservice.dto.StudentCourseDto; -import com.javatab.courseservice.model.Student; -import com.javatab.courseservice.repository.StudentCourseRepository; -import com.javatab.courseservice.repository.StudentRepository; -import lombok.AllArgsConstructor; -import org.springframework.stereotype.Service; - -import java.util.List; -import java.util.Optional; - -@Service -@AllArgsConstructor -public class StudentService { - - private final StudentRepository studentRepository; - private final StudentCourseRepository studentCourseRepository; - - public List getAllStudents() { - return studentRepository.findAll(); - } - - public Student addStudent(Student student) { - return studentRepository.save(student); - } - - public List getAllRegisteredCoursesForAStudent(String username) { - return studentCourseRepository.findAllCoursesRegistered(username); - } - - public Optional getUserByUsername(String username) { - return studentRepository.findByUsername(username); - } - -} diff --git a/course-service/src/main/resources/application.yml b/course-service/src/main/resources/application.yml deleted file mode 100644 index 8b1fd38..0000000 --- a/course-service/src/main/resources/application.yml +++ /dev/null @@ -1,15 +0,0 @@ -spring: - application: - name: course-service - config: - import: optional:configserver:config-server - cloud: - config: - discovery: - enabled: true - service-id: config-server - -eureka: - client: - service-url: - default-zone: http://discoveryservice:8761/eureka/ \ No newline at end of file diff --git a/course-service/src/main/resources/data.sql b/course-service/src/main/resources/data.sql deleted file mode 100644 index 9e0b953..0000000 --- a/course-service/src/main/resources/data.sql +++ /dev/null @@ -1,90 +0,0 @@ -INSERT INTO courses (course_id, course_name, course_desc, duration, type, total_seats, available_seats, expired, trending, featured) -VALUES ('f3831f8c-c338-4ebe-a82a-e2fc1d1ff78a', - 'Complete Python Bootcamp: Go from zero to hero in Python 3', - 'Learn Python like a Professional! Start from the basics and go all the way to creating your own applications and games!', - 60, 'EXTERNAL', 30, 5, false, true, false - ); - -INSERT INTO courses (course_id, course_name, course_desc, duration, type, total_seats, available_seats, expired, trending, featured) -VALUES ('f3831f8c-c338-4ebe-a82a-e2fc1d1ff78b', - 'Java Programming Masterclass for Software Developers', - 'Learn Java In This Course And Become a Computer Programmer. Obtain valuable Core Java Skills And Java Certification', - 30, 'EXTERNAL', 50, 4, false, true, false - ); - -INSERT INTO courses (course_id, course_name, course_desc, duration, type, total_seats, available_seats, expired, trending, featured) -VALUES ('f3831f8c-c338-4ebe-a82a-e2fc1d1ff78c', - 'Docker Mastery: The Complete Toolset From a Docker Captain', - 'Build, compose, deploy, and manage Docker containers from development to DevOps based Swarm clusters', - 15, 'EXTERNAL', 40, 3, false, true, false - ); - - -INSERT INTO courses (course_id, course_name, course_desc, duration, type, total_seats, available_seats, expired, trending, featured) -VALUES ('f3831f8c-c338-4ebe-a82a-e2fc1d1ff78d', - 'The Complete Digital Marketing Course - 12 Courses', - 'Master Digital Marketing: Strategy, Social Media Marketing, SEO, YouTube, Email, Facebook Marketing, Analytics & More!', - 5, 'INTERNAL', 100, 80, false, false, true - ); - - -INSERT INTO courses (course_id, course_name, course_desc, duration, type, total_seats, available_seats, expired, trending, featured) -VALUES ('f3831f8c-c338-4ebe-a82a-e2fc1d1ff78e', - 'Complete Guide to TensorFlow for Deep Learning with Python ', - 'Learn how to use Googles Deep Learning Framework - TensorFlow with Python! Solve problems with cutting edge techniques!', - 30, 'INTERNAL', 50, 22, false, false, false - ); - - -INSERT INTO courses (course_id, course_name, course_desc, duration, type, total_seats, available_seats, expired, trending, featured) -VALUES ('f3831f8c-c338-4ebe-a82a-e2fc1d1ff78f', - 'Angular & NodeJS - The MEAN Stack Guide', - 'Learn how to connect your Angular Frontend to a NodeJS & Express & MongoDB Backend by building a real Application', - 30, 'EXTERNAL', 50, 12, false, false, false - ); - - - -INSERT INTO courses (course_id, course_name, course_desc, duration, type, total_seats, available_seats, expired, trending, featured) -VALUES ('f3831f8c-c338-4ebe-a82a-e2fc1d1ff78g', - 'Understanding TypeScript', - 'Donot limit the Usage of TypeScript to Angular 2! Learn the Basics, its Features, Workflows and how to use it!', - 30, 'EXTERNAL', 30, 12, false, false, false - ); - - - - -INSERT INTO courses (course_id, course_name, course_desc, duration, type, total_seats, available_seats, expired, trending, featured) -VALUES ('f3831f8c-c338-4ebe-a82a-e2fc1d1ff78h', - 'Learn How To Code: Googles Go (golang) Programming Language', - 'The Ultimate Comprehensive Course Perfect for Both Beginners and Experienced Developers', - 20, 'EXTERNAL', 50, 21, false, false, false - ); - - - -INSERT INTO seats (available, type, course_id) -VALUES (true, 'FRONT', 'f3831f8c-c338-4ebe-a82a-e2fc1d1ff78a'); -INSERT INTO seats (available, type, course_id) -VALUES (true, 'FRONT', 'f3831f8c-c338-4ebe-a82a-e2fc1d1ff78a'); -INSERT INTO seats (available, type, course_id) -VALUES (true, 'MIDDLE', 'f3831f8c-c338-4ebe-a82a-e2fc1d1ff78a'); -INSERT INTO seats (available, type, course_id) -VALUES (true, 'BACK', 'f3831f8c-c338-4ebe-a82a-e2fc1d1ff78a'); -INSERT INTO seats (available, type, course_id) -VALUES (true, 'BACK', 'f3831f8c-c338-4ebe-a82a-e2fc1d1ff78a'); - - -INSERT INTO students (student_id, student_name, username, department, semster, join_in) -VALUES ('5001', 'Nasruddin', 'nasruddin', 'Computer Science and Engineering', '4', '2015'); -INSERT INTO students (student_id, student_name, username, department, semster, join_in) -VALUES ('5002', 'User 1', 'user', 'Electronics And Communication', '5', '2012'); -INSERT INTO students (student_id, student_name, username, department, semster, join_in) -VALUES ('5003', 'admin', 'admin', 'Mechanical', '6', '2012'); - - -INSERT INTO student_course (id, username, course_id, status) -VALUES ('1', 'nasruddin', 'f3831f8c-c338-4ebe-a82a-e2fc1d1ff78a', 'APPROVED'); -INSERT INTO student_course (id, username, course_id, status) -VALUES ('2', 'nasruddin', 'f3831f8c-c338-4ebe-a82a-e2fc1d1ff78b', 'PENDING'); diff --git a/course-service/src/main/resources/schema.sql b/course-service/src/main/resources/schema.sql deleted file mode 100644 index 3d92128..0000000 --- a/course-service/src/main/resources/schema.sql +++ /dev/null @@ -1,45 +0,0 @@ -DROP TABLE IF EXISTS courses; -DROP TABLE IF EXISTS students; -DROP TABLE IF EXISTS student_course; -DROP TABLE IF EXISTS seats; - -CREATE TABLE courses ( - course_id VARCHAR(100) NOT NULL, - course_name TEXT NOT NULL, - course_desc TEXT NOT NULL, - duration BIGINT NOT NULL, - type TEXT NOT NULL, - total_seats BIGINT NOT NULL, - available_seats BIGINT NOT NULL, - expired BOOLEAN NOT NULL, - featured BOOLEAN NOT NULL, - trending BOOLEAN NOT NULL, - primary key(course_id) - -); - -CREATE TABLE students ( - student_id VARCHAR(100) NOT NULL, - student_name TEXT NOT NULL, - username TEXT NOT NULL, - department TEXT NOT NULL, - semster TEXT NOT NULL, - join_in TEXT NOT NULL, - primary key(student_id) -); - -CREATE TABLE student_course ( - id BIGINT auto_increment NOT NULL, - username VARCHAR(100) NOT NULL, - course_id VARCHAR(100) NOT NULL, - status TEXT DEFAULT 'PENDING' NOT NULL, - primary key(username, course_id) -); - -CREATE TABLE seats ( - seat_id BIGINT auto_increment NOT NULL, - available BOOLEAN NOT NULL, - type TEXT NOT NULL, - course_id VARCHAR(100) NOT NULL, - primary key(seat_id) -) \ No newline at end of file diff --git a/course-service/src/test/java/com/javatab/courseservice/CourseServiceApplicationTests.java b/course-service/src/test/java/com/javatab/courseservice/CourseServiceApplicationTests.java deleted file mode 100644 index 5c9ad15..0000000 --- a/course-service/src/test/java/com/javatab/courseservice/CourseServiceApplicationTests.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.javatab.courseservice; - -import org.junit.jupiter.api.Disabled; -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest -public class CourseServiceApplicationTests { - - @Disabled - public void contextLoads() { - } - -} diff --git a/create-project.bash b/create-project.bash new file mode 100644 index 0000000..03a4dab --- /dev/null +++ b/create-project.bash @@ -0,0 +1,66 @@ +#!/usr/bin/env bash + +mkdir microservices +cd microservices + +spring init \ +--boot-version=2.5.2 \ +--build=maven \ +--java-version=17 \ +--packaging=jar \ +--name=student-service \ +--package-name=io.javatab.microservices.core.student \ +--groupId=io.javatab.microservices.core.student \ +--dependencies=actuator,webflux \ +--version=1.0.0 \ +student-service + +spring init \ +--boot-version=2.5.2 \ +--build=maven \ +--java-version=17 \ +--packaging=jar \ +--name=course-service \ +--package-name=io.javatab.microservices.core.course \ +--groupId=io.javatab.microservices.core.course \ +--dependencies=actuator,webflux \ +--version=1.0.0 \ +course-service + +spring init \ +--boot-version=2.5.2 \ +--build=maven \ +--java-version=17 \ +--packaging=jar \ +--name=vote-service \ +--package-name=io.javatab.microservices.core.vote \ +--groupId=io.javatab.microservices.core.vote \ +--dependencies=actuator,webflux \ +--version=1.0.0 \ +vote-service + +spring init \ +--boot-version=2.5.2 \ +--build=maven \ +--java-version=17 \ +--packaging=jar \ +--name=search-service \ +--package-name=io.javatab.microservices.core.search \ +--groupId=io.javatab.microservices.core.search \ +--dependencies=actuator,webflux \ +--version=1.0.0 \ +search-service + +spring init \ +--boot-version=2.5.2 \ +--build=maven \ +--java-version=17 \ +--packaging=jar \ +--name=course-composite-service \ +--package-name=io.javatab.microservices.composite.course \ +--groupId=io.javatab.microservices.composite.course \ +--dependencies=actuator,webflux \ +--version=1.0.0 \ +course-composite-service + +cd .. \ No newline at end of file diff --git a/discovery-service/.mvn/wrapper/MavenWrapperDownloader.java b/discovery-service/.mvn/wrapper/MavenWrapperDownloader.java deleted file mode 100644 index 72308aa..0000000 --- a/discovery-service/.mvn/wrapper/MavenWrapperDownloader.java +++ /dev/null @@ -1,114 +0,0 @@ -/* -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you under the Apache License, Version 2.0 (the -"License"); you may not use this file except in compliance -with the License. You may obtain a copy of the License at - - https://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, -software distributed under the License is distributed on an -"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, either express or implied. See the License for the -specific language governing permissions and limitations -under the License. -*/ - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.net.URL; -import java.nio.channels.Channels; -import java.nio.channels.ReadableByteChannel; -import java.util.Properties; - -public class MavenWrapperDownloader { - - /** - * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. - */ - private static final String DEFAULT_DOWNLOAD_URL = - "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"; - - /** - * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to - * use instead of the default one. - */ - private static final String MAVEN_WRAPPER_PROPERTIES_PATH = - ".mvn/wrapper/maven-wrapper.properties"; - - /** - * Path where the maven-wrapper.jar will be saved to. - */ - private static final String MAVEN_WRAPPER_JAR_PATH = - ".mvn/wrapper/maven-wrapper.jar"; - - /** - * Name of the property which should be used to override the default download url for the wrapper. - */ - private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; - - public static void main(String args[]) { - System.out.println("- Downloader started"); - File baseDirectory = new File(args[0]); - System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); - - // If the maven-wrapper.properties exists, read it and check if it contains a custom - // wrapperUrl parameter. - File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); - String url = DEFAULT_DOWNLOAD_URL; - if(mavenWrapperPropertyFile.exists()) { - FileInputStream mavenWrapperPropertyFileInputStream = null; - try { - mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); - Properties mavenWrapperProperties = new Properties(); - mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); - url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); - } catch (IOException e) { - System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); - } finally { - try { - if(mavenWrapperPropertyFileInputStream != null) { - mavenWrapperPropertyFileInputStream.close(); - } - } catch (IOException e) { - // Ignore ... - } - } - } - System.out.println("- Downloading from: : " + url); - - File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); - if(!outputFile.getParentFile().exists()) { - if(!outputFile.getParentFile().mkdirs()) { - System.out.println( - "- ERROR creating output direcrory '" + outputFile.getParentFile().getAbsolutePath() + "'"); - } - } - System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); - try { - downloadFileFromURL(url, outputFile); - System.out.println("Done"); - System.exit(0); - } catch (Throwable e) { - System.out.println("- Error downloading"); - e.printStackTrace(); - System.exit(1); - } - } - - private static void downloadFileFromURL(String urlString, File destination) throws Exception { - URL website = new URL(urlString); - ReadableByteChannel rbc; - rbc = Channels.newChannel(website.openStream()); - FileOutputStream fos = new FileOutputStream(destination); - fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); - fos.close(); - rbc.close(); - } - -} diff --git a/discovery-service/.mvn/wrapper/maven-wrapper.jar b/discovery-service/.mvn/wrapper/maven-wrapper.jar deleted file mode 100644 index 01e6799..0000000 Binary files a/discovery-service/.mvn/wrapper/maven-wrapper.jar and /dev/null differ diff --git a/discovery-service/.mvn/wrapper/maven-wrapper.properties b/discovery-service/.mvn/wrapper/maven-wrapper.properties deleted file mode 100644 index cd0d451..0000000 --- a/discovery-service/.mvn/wrapper/maven-wrapper.properties +++ /dev/null @@ -1 +0,0 @@ -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip diff --git a/discovery-service/Dockerfile b/discovery-service/Dockerfile deleted file mode 100644 index 1bccac9..0000000 --- a/discovery-service/Dockerfile +++ /dev/null @@ -1,31 +0,0 @@ -#stage 1 -#Start with a base image containing Java runtime -FROM openjdk:11-slim as build - -# Add Maintainer Info -LABEL maintainer="Nasruddin " - -# The application's jar file -ARG JAR_FILE - -# Add the application's jar to the container -COPY ${JAR_FILE} app.jar - -#unpackage jar file -RUN mkdir -p target/dependency && (cd target/dependency; jar -xf /app.jar) - -#stage 2 -#Same Java runtime -FROM openjdk:11-slim - -#Add volume pointing to /tmp -VOLUME /tmp - -#Copy unpackaged application to new container -ARG DEPENDENCY=/target/dependency -COPY --from=build ${DEPENDENCY}/BOOT-INF/lib /app/lib -COPY --from=build ${DEPENDENCY}/META-INF /app/META-INF -COPY --from=build ${DEPENDENCY}/BOOT-INF/classes /app - -#execute the application -ENTRYPOINT ["java","-cp","app:app/lib/*","com.javatab.discoveryservice.DiscoveryServiceApplication"] \ No newline at end of file diff --git a/discovery-service/mvnw b/discovery-service/mvnw deleted file mode 100755 index 8b9da3b..0000000 --- a/discovery-service/mvnw +++ /dev/null @@ -1,286 +0,0 @@ -#!/bin/sh -# ---------------------------------------------------------------------------- -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# ---------------------------------------------------------------------------- - -# ---------------------------------------------------------------------------- -# Maven2 Start Up Batch script -# -# Required ENV vars: -# ------------------ -# JAVA_HOME - location of a JDK home dir -# -# Optional ENV vars -# ----------------- -# M2_HOME - location of maven2's installed home dir -# MAVEN_OPTS - parameters passed to the Java VM when running Maven -# e.g. to debug Maven itself, use -# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -# MAVEN_SKIP_RC - flag to disable loading of mavenrc files -# ---------------------------------------------------------------------------- - -if [ -z "$MAVEN_SKIP_RC" ] ; then - - if [ -f /etc/mavenrc ] ; then - . /etc/mavenrc - fi - - if [ -f "$HOME/.mavenrc" ] ; then - . "$HOME/.mavenrc" - fi - -fi - -# OS specific support. $var _must_ be set to either true or false. -cygwin=false; -darwin=false; -mingw=false -case "`uname`" in - CYGWIN*) cygwin=true ;; - MINGW*) mingw=true;; - Darwin*) darwin=true - # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home - # See https://developer.apple.com/library/mac/qa/qa1170/_index.html - if [ -z "$JAVA_HOME" ]; then - if [ -x "/usr/libexec/java_home" ]; then - export JAVA_HOME="`/usr/libexec/java_home`" - else - export JAVA_HOME="/Library/Java/Home" - fi - fi - ;; -esac - -if [ -z "$JAVA_HOME" ] ; then - if [ -r /etc/gentoo-release ] ; then - JAVA_HOME=`java-config --jre-home` - fi -fi - -if [ -z "$M2_HOME" ] ; then - ## resolve links - $0 may be a link to maven's home - PRG="$0" - - # need this for relative symlinks - while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG="`dirname "$PRG"`/$link" - fi - done - - saveddir=`pwd` - - M2_HOME=`dirname "$PRG"`/.. - - # make it fully qualified - M2_HOME=`cd "$M2_HOME" && pwd` - - cd "$saveddir" - # echo Using m2 at $M2_HOME -fi - -# For Cygwin, ensure paths are in UNIX format before anything is touched -if $cygwin ; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --unix "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --unix "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --unix "$CLASSPATH"` -fi - -# For Mingw, ensure paths are in UNIX format before anything is touched -if $mingw ; then - [ -n "$M2_HOME" ] && - M2_HOME="`(cd "$M2_HOME"; pwd)`" - [ -n "$JAVA_HOME" ] && - JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" - # TODO classpath? -fi - -if [ -z "$JAVA_HOME" ]; then - javaExecutable="`which javac`" - if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then - # readlink(1) is not available as standard on Solaris 10. - readLink=`which readlink` - if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then - if $darwin ; then - javaHome="`dirname \"$javaExecutable\"`" - javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" - else - javaExecutable="`readlink -f \"$javaExecutable\"`" - fi - javaHome="`dirname \"$javaExecutable\"`" - javaHome=`expr "$javaHome" : '\(.*\)/bin'` - JAVA_HOME="$javaHome" - export JAVA_HOME - fi - fi -fi - -if [ -z "$JAVACMD" ] ; then - if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - else - JAVACMD="`which java`" - fi -fi - -if [ ! -x "$JAVACMD" ] ; then - echo "Error: JAVA_HOME is not defined correctly." >&2 - echo " We cannot execute $JAVACMD" >&2 - exit 1 -fi - -if [ -z "$JAVA_HOME" ] ; then - echo "Warning: JAVA_HOME environment variable is not set." -fi - -CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher - -# traverses directory structure from process work directory to filesystem root -# first directory with .mvn subdirectory is considered project base directory -find_maven_basedir() { - - if [ -z "$1" ] - then - echo "Path not specified to find_maven_basedir" - return 1 - fi - - basedir="$1" - wdir="$1" - while [ "$wdir" != '/' ] ; do - if [ -d "$wdir"/.mvn ] ; then - basedir=$wdir - break - fi - # workaround for JBEAP-8937 (on Solaris 10/Sparc) - if [ -d "${wdir}" ]; then - wdir=`cd "$wdir/.."; pwd` - fi - # end of workaround - done - echo "${basedir}" -} - -# concatenates all lines of a file -concat_lines() { - if [ -f "$1" ]; then - echo "$(tr -s '\n' ' ' < "$1")" - fi -} - -BASE_DIR=`find_maven_basedir "$(pwd)"` -if [ -z "$BASE_DIR" ]; then - exit 1; -fi - -########################################################################################## -# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -# This allows using the maven wrapper in projects that prohibit checking in binary data. -########################################################################################## -if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found .mvn/wrapper/maven-wrapper.jar" - fi -else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." - fi - jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" - while IFS="=" read key value; do - case "$key" in (wrapperUrl) jarUrl="$value"; break ;; - esac - done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" - if [ "$MVNW_VERBOSE" = true ]; then - echo "Downloading from: $jarUrl" - fi - wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" - - if command -v wget > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found wget ... using wget" - fi - wget "$jarUrl" -O "$wrapperJarPath" - elif command -v curl > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found curl ... using curl" - fi - curl -o "$wrapperJarPath" "$jarUrl" - else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Falling back to using Java to download" - fi - javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" - if [ -e "$javaClass" ]; then - if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Compiling MavenWrapperDownloader.java ..." - fi - # Compiling the Java class - ("$JAVA_HOME/bin/javac" "$javaClass") - fi - if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - # Running the downloader - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Running MavenWrapperDownloader.java ..." - fi - ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") - fi - fi - fi -fi -########################################################################################## -# End of extension -########################################################################################## - -export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} -if [ "$MVNW_VERBOSE" = true ]; then - echo $MAVEN_PROJECTBASEDIR -fi -MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" - -# For Cygwin, switch paths to Windows format before running java -if $cygwin; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --path --windows "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --windows "$CLASSPATH"` - [ -n "$MAVEN_PROJECTBASEDIR" ] && - MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` -fi - -WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -exec "$JAVACMD" \ - $MAVEN_OPTS \ - -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ - "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ - ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/discovery-service/mvnw.cmd b/discovery-service/mvnw.cmd deleted file mode 100644 index fef5a8f..0000000 --- a/discovery-service/mvnw.cmd +++ /dev/null @@ -1,161 +0,0 @@ -@REM ---------------------------------------------------------------------------- -@REM Licensed to the Apache Software Foundation (ASF) under one -@REM or more contributor license agreements. See the NOTICE file -@REM distributed with this work for additional information -@REM regarding copyright ownership. The ASF licenses this file -@REM to you under the Apache License, Version 2.0 (the -@REM "License"); you may not use this file except in compliance -@REM with the License. You may obtain a copy of the License at -@REM -@REM https://www.apache.org/licenses/LICENSE-2.0 -@REM -@REM Unless required by applicable law or agreed to in writing, -@REM software distributed under the License is distributed on an -@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -@REM KIND, either express or implied. See the License for the -@REM specific language governing permissions and limitations -@REM under the License. -@REM ---------------------------------------------------------------------------- - -@REM ---------------------------------------------------------------------------- -@REM Maven2 Start Up Batch script -@REM -@REM Required ENV vars: -@REM JAVA_HOME - location of a JDK home dir -@REM -@REM Optional ENV vars -@REM M2_HOME - location of maven2's installed home dir -@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands -@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending -@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven -@REM e.g. to debug Maven itself, use -@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files -@REM ---------------------------------------------------------------------------- - -@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' -@echo off -@REM set title of command window -title %0 -@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' -@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% - -@REM set %HOME% to equivalent of $HOME -if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") - -@REM Execute a user defined script before this one -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre -@REM check for pre script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" -if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" -:skipRcPre - -@setlocal - -set ERROR_CODE=0 - -@REM To isolate internal variables from possible post scripts, we use another setlocal -@setlocal - -@REM ==== START VALIDATION ==== -if not "%JAVA_HOME%" == "" goto OkJHome - -echo. -echo Error: JAVA_HOME not found in your environment. >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -:OkJHome -if exist "%JAVA_HOME%\bin\java.exe" goto init - -echo. -echo Error: JAVA_HOME is set to an invalid directory. >&2 -echo JAVA_HOME = "%JAVA_HOME%" >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -@REM ==== END VALIDATION ==== - -:init - -@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". -@REM Fallback to current working directory if not found. - -set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% -IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir - -set EXEC_DIR=%CD% -set WDIR=%EXEC_DIR% -:findBaseDir -IF EXIST "%WDIR%"\.mvn goto baseDirFound -cd .. -IF "%WDIR%"=="%CD%" goto baseDirNotFound -set WDIR=%CD% -goto findBaseDir - -:baseDirFound -set MAVEN_PROJECTBASEDIR=%WDIR% -cd "%EXEC_DIR%" -goto endDetectBaseDir - -:baseDirNotFound -set MAVEN_PROJECTBASEDIR=%EXEC_DIR% -cd "%EXEC_DIR%" - -:endDetectBaseDir - -IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig - -@setlocal EnableExtensions EnableDelayedExpansion -for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a -@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% - -:endReadAdditionalConfig - -SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" -set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" -set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" -FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO ( - IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B -) - -@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -@REM This allows using the maven wrapper in projects that prohibit checking in binary data. -if exist %WRAPPER_JAR% ( - echo Found %WRAPPER_JAR% -) else ( - echo Couldn't find %WRAPPER_JAR%, downloading it ... - echo Downloading from: %DOWNLOAD_URL% - powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')" - echo Finished downloading %WRAPPER_JAR% -) -@REM End of extension - -%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* -if ERRORLEVEL 1 goto error -goto end - -:error -set ERROR_CODE=1 - -:end -@endlocal & set ERROR_CODE=%ERROR_CODE% - -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost -@REM check for post script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" -if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" -:skipRcPost - -@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' -if "%MAVEN_BATCH_PAUSE%" == "on" pause - -if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% - -exit /B %ERROR_CODE% diff --git a/discovery-service/pom.xml b/discovery-service/pom.xml deleted file mode 100644 index 573bba0..0000000 --- a/discovery-service/pom.xml +++ /dev/null @@ -1,105 +0,0 @@ - - - 4.0.0 - - - org.springframework.boot - spring-boot-starter-parent - 2.5.4 - - - - com.javatab - discovery-service - 1.0.0 - discovery-service - Demo project for Spring Boot - - - 11 - javatab - 2020.0.3 - - - - - - org.springframework.boot - spring-boot-starter-actuator - - - org.springframework.cloud - spring-cloud-starter-netflix-eureka-server - - - org.springframework.cloud - spring-cloud-starter-ribbon - - - com.netflix.ribbon - ribbon-eureka - - - - - org.springframework.cloud - spring-cloud-starter-loadbalancer - - - org.springframework.boot - spring-boot-starter-test - test - - - org.junit.vintage - junit-vintage-engine - - - - - - - - - org.springframework.cloud - spring-cloud-dependencies - ${spring-cloud.version} - pom - import - - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - com.spotify - dockerfile-maven-plugin - 1.4.13 - - ${docker.image.prefix}/${project.artifactId} - ${project.version} - - target/${project.build.finalName}.jar - - - - - default - install - - build - - - - - - - - diff --git a/discovery-service/src/main/java/com/javatab/discoveryservice/DiscoveryServiceApplication.java b/discovery-service/src/main/java/com/javatab/discoveryservice/DiscoveryServiceApplication.java deleted file mode 100644 index db4e3ed..0000000 --- a/discovery-service/src/main/java/com/javatab/discoveryservice/DiscoveryServiceApplication.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.javatab.discoveryservice; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; - -@SpringBootApplication -@EnableEurekaServer -public class DiscoveryServiceApplication { - - public static void main(String[] args) { - SpringApplication.run(DiscoveryServiceApplication.class, args); - } - -} diff --git a/discovery-service/src/main/resources/application.yml b/discovery-service/src/main/resources/application.yml deleted file mode 100644 index 26fe9d5..0000000 --- a/discovery-service/src/main/resources/application.yml +++ /dev/null @@ -1,23 +0,0 @@ -spring: - application: - name: discovery-service -server: - port: 8761 - -eureka: - instance: - hostname: discoveryservice - prefer-ip-address: true - client: - registerWithEureka: false - fetchRegistry: false - serviceUrl: - defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ - server: - waitTimeInMsWhenSyncEmpty: 5 - -management: - endpoints: - web: - exposure: - include: "*" diff --git a/discovery-service/src/test/java/com/javatab/discoveryservice/DiscoveryServiceApplicationTests.java b/discovery-service/src/test/java/com/javatab/discoveryservice/DiscoveryServiceApplicationTests.java deleted file mode 100644 index 589daca..0000000 --- a/discovery-service/src/test/java/com/javatab/discoveryservice/DiscoveryServiceApplicationTests.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.javatab.discoveryservice; - - -import org.junit.jupiter.api.Disabled; -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest -public class DiscoveryServiceApplicationTests { - - @Disabled - void contextLoads() { - } - -} diff --git a/docker/.env b/docker/.env new file mode 100644 index 0000000..293fc79 --- /dev/null +++ b/docker/.env @@ -0,0 +1,3 @@ +CONFIG_SERVER_ENCRYPT_KEY=my-very-secure-encrypt-key +CONFIG_SERVER_USR=dev-user +CONFIG_SERVER_PWD=dev-password \ No newline at end of file diff --git a/docker/database.env b/docker/database.env deleted file mode 100644 index 8dcbf1a..0000000 --- a/docker/database.env +++ /dev/null @@ -1,4 +0,0 @@ -# database.env -POSTGRES_USER=postgres -POSTGRES_PASSWORD=123 -POSTGRES_DB=testdb \ No newline at end of file diff --git a/docker/docker-compose-elasticsearch.yml b/docker/docker-compose-elasticsearch.yml deleted file mode 100644 index 4c16693..0000000 --- a/docker/docker-compose-elasticsearch.yml +++ /dev/null @@ -1,30 +0,0 @@ -version: "3.8" -services: - elasticsearch: - image: docker.elastic.co/elasticsearch/elasticsearch:7.7.0 - container_name: elasticsearch - environment: - - node.name=elasticsearch - - discovery.type=single-node - - cluster.name=docker-cluster - - bootstrap.memory_lock=true - - "ES_JAVA_OPTS=-Xms512m -Xmx512m" - ulimits: - memlock: - soft: -1 - hard: -1 - # volumes: - # - esdata1:/usr/share/elasticsearch/data - ports: - - "9300:9300" - - "9200:9200" - networks: - - backend - -networks: - backend: - driver: bridge - -#volumes: - # esdata1: - # driver: local \ No newline at end of file diff --git a/docker/docker-compose-kafka.yml b/docker/docker-compose-kafka.yml deleted file mode 100644 index 817ea6e..0000000 --- a/docker/docker-compose-kafka.yml +++ /dev/null @@ -1,26 +0,0 @@ -version: '3.8' -services: - zookeeper: - image: wurstmeister/zookeeper:latest - ports: - - "2181:2181" - networks: - - backend - kafkaserver: - image: wurstmeister/kafka:latest - ports: - - "9092:9092" - environment: - - KAFKA_ADVERTISED_HOST_NAME=kafka - - KAFKA_ADVERTISED_PORT=9092 - - KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181 - volumes: - - "/var/run/docker.sock:/var/run/docker.sock" - depends_on: - - zookeeper - networks: - - backend - -networks: - backend: - driver: bridge \ No newline at end of file diff --git a/docker/docker-compose-keycloak.yml b/docker/docker-compose-keycloak.yml deleted file mode 100644 index d7e8f3d..0000000 --- a/docker/docker-compose-keycloak.yml +++ /dev/null @@ -1,18 +0,0 @@ -version: '3.8' # Migrate to version 3 -services: - keycloak: - image: jboss/keycloak - restart: always - environment: - KEYCLOAK_USER: admin - KEYCLOAK_PASSWORD: admin - ports: - - "8080:8080" - networks: - backend: - aliases: - - "keycloak" - -networks: - backend: - driver: bridge \ No newline at end of file diff --git a/docker/docker-compose-mongo.yml b/docker/docker-compose-mongo.yml deleted file mode 100644 index aed2805..0000000 --- a/docker/docker-compose-mongo.yml +++ /dev/null @@ -1,15 +0,0 @@ -version: '3.8' -services: - mongodb_container: - image: mongo:latest - restart: always - #environment: - # MONGO_INITDB_ROOT_USERNAME: root - # MONGO_INITDB_ROOT_PASSWORD: rootpassword - ports: - - 27017:27017 - volumes: - - mongodb_data_container:/data/db - -volumes: - mongodb_data_container: \ No newline at end of file diff --git a/docker/docker-compose-postgres.yml b/docker/docker-compose-postgres.yml deleted file mode 100644 index 7ba4472..0000000 --- a/docker/docker-compose-postgres.yml +++ /dev/null @@ -1,19 +0,0 @@ -version: '3.8' -services: - postgres_container1: - restart: always - image: "postgres:latest" # use latest official postgres version - env_file: - - database.env # configure postgres - ports: - - "5432:5432" - volumes: - - database-data:/var/lib/postgresql/data/ # persist data even if container shuts down - networks: - - backend -volumes: - database-data: # named volumes can be managed easier using docker-compose - -networks: - backend: - driver: bridge \ No newline at end of file diff --git a/docker/docker-compose-redis.yml b/docker/docker-compose-redis.yml deleted file mode 100644 index bf83edb..0000000 --- a/docker/docker-compose-redis.yml +++ /dev/null @@ -1,12 +0,0 @@ -version: "3.8" -services: - redisserver: - image: redis:alpine - ports: - - "6379:6379" - networks: - - backend - -networks: - backend: - driver: bridge \ No newline at end of file diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index f029487..28f1e7e 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -1,57 +1,163 @@ -version: '3.8' +version: '2.1' + services: - discoveryservice: - image: javatab/discovery-service:1.0.0 - container_name: discoveryService - ports: - - "8761:8761" - networks: - - backend - #healthcheck: - # test: [ "CMD", "curl", "-f", "http://discoveryservice:8761/eureka/" ] - # interval: 30s - # timeout: 10s - # retries: 5 - configserver: + course: + build: ../microservices/course-service + image: javatab/course_service:v1 + mem_limit: 512m + environment: + - SPRING_PROFILES_ACTIVE=docker + - CONFIG_SERVER_USR=${CONFIG_SERVER_USR} + - CONFIG_SERVER_PWD=${CONFIG_SERVER_PWD} depends_on: - - discoveryservice - image: javatab/config-server:1.0.0 - container_name: configServer - ports: - - "8071:8071" - networks: - - backend + mongodb: + condition: service_healthy + + search: + build: ../microservices/search-service + image: javatab/search_service:v1 + mem_limit: 512m environment: - - JAVA_OPTS= - -DEUREKA_SERVER=http://discoveryservice:8761/eureka - auth-service: + - SPRING_PROFILES_ACTIVE=docker + - CONFIG_SERVER_USR=${CONFIG_SERVER_USR} + - CONFIG_SERVER_PWD=${CONFIG_SERVER_PWD} depends_on: - - discoveryservice - - configserver - image: javatab/auth-service:1.0.0 - container_name: authService - ports: - - "9100:9100" - networks: - - backend - apigatewayservice: + elasticsearch: + condition: service_healthy + + student: + build: ../microservices/student-service + image: javatab/student_service:v1 + mem_limit: 512m + environment: + - SPRING_PROFILES_ACTIVE=docker + - CONFIG_SERVER_USR=${CONFIG_SERVER_USR} + - CONFIG_SERVER_PWD=${CONFIG_SERVER_PWD} depends_on: - - discoveryservice - - configserver - image: javatab/api-gateway-service:1.0.0 - container_name: apiGatewayService - ports: - - "8762:8762" - courseservice: + postgres: + condition: service_healthy + + vote: + build: ../microservices/vote-service + image: javatab/vote_service:v1 + mem_limit: 512m + environment: + - SPRING_PROFILES_ACTIVE=docker + - CONFIG_SERVER_USR=${CONFIG_SERVER_USR} + - CONFIG_SERVER_PWD=${CONFIG_SERVER_PWD} depends_on: - - discoveryservice - - configserver - image: javatab/course-service:1.0.0 - container_name: courseService + redis: + condition: service_healthy + + course-composite: + build: ../microservices/course-composite-service + image: javatab/course_composite_service:v1 + mem_limit: 512m + environment: + - SPRING_PROFILES_ACTIVE=docker + - CONFIG_SERVER_USR=${CONFIG_SERVER_USR} + - CONFIG_SERVER_PWD=${CONFIG_SERVER_PWD} + + mongodb: + image: mongo:4.4.2 + mem_limit: 512m + ports: + - "27017:27017" + command: mongod + healthcheck: + test: "mongo --eval 'db.stats().ok'" + interval: 5s + timeout: 2s + retries: 60 + + postgres: + image: postgres:alpine3.15 + mem_limit: 512m ports: - - "8200:8200" - networks: - - backend -networks: - backend: - driver: bridge \ No newline at end of file + - "5432:5432" + environment: + - POSTGRES_DATABASE=test + - POSTGRES_USER=user + - POSTGRES_PASSWORD=pwd + healthcheck: + test: [ "CMD-SHELL", "pg_isready -U user" ] + interval: 10s + timeout: 5s + retries: 5 + + redis: + image: redis:6.2.6-alpine + restart: always + ports: + - "6379:6379" + healthcheck: + test: [ "CMD-SHELL", "redis-cli ping | grep PONG" ] + interval: 5s + timeout: 2s + retries: 60 + + elasticsearch: + image: elasticsearch:7.12.1 + ports: + - "9300:9300" + - "9200:9200" + environment: + - node.name=elasticsearch + - discovery.type=single-node + - cluster.name=docker-cluster + - bootstrap.memory_lock=true + - "ES_JAVA_OPTS=-Xms512m -Xmx512m" + ulimits: + memlock: + soft: -1 + hard: -1 + healthcheck: + test: ["CMD-SHELL", "curl --silent --fail localhost:9200/_cluster/health || exit 1"] + interval: 5s + timeout: 2s + retries: 60 + + eureka: + build: ../spring-cloud/eureka-server + mem_limit: 512m + environment: + - SPRING_PROFILES_ACTIVE=docker + - CONFIG_SERVER_USR=${CONFIG_SERVER_USR} + - CONFIG_SERVER_PWD=${CONFIG_SERVER_PWD} + + gateway: + build: ../spring-cloud/gateway + mem_limit: 512m + ports: + - "8443:8443" + environment: + - SPRING_PROFILES_ACTIVE=docker + - CONFIG_SERVER_USR=${CONFIG_SERVER_USR} + - CONFIG_SERVER_PWD=${CONFIG_SERVER_PWD} + #depends_on: + # auth-server: + # condition: service_healthy + + auth-server: + environment: + - SPRING_PROFILES_ACTIVE=docker + - CONFIG_SERVER_USR=${CONFIG_SERVER_USR} + - CONFIG_SERVER_PWD=${CONFIG_SERVER_PWD} + build: ../spring-cloud/authorization-server + mem_limit: 512m + #healthcheck: + # test: "curl --fail --silent http://localhost:9999/actuator/health | grep UP || exit 1" + # interval: 5s + # timeout: 2s + # retries: 60 + + config-server: + build: ../spring-cloud/config-server + mem_limit: 512m + environment: + - SPRING_PROFILES_ACTIVE=docker,native + #- ENCRYPT_KEY=${CONFIG_SERVER_ENCRYPT_KEY} + - SPRING_SECURITY_USER_NAME=${CONFIG_SERVER_USR} + - SPRING_SECURITY_USER_PASSWORD=${CONFIG_SERVER_PWD} + volumes: + - $PWD/../config-repo:/config-repo \ No newline at end of file diff --git a/config-server/.gitignore b/microservices/course-composite-service/.gitignore similarity index 100% rename from config-server/.gitignore rename to microservices/course-composite-service/.gitignore diff --git a/microservices/course-composite-service/Dockerfile b/microservices/course-composite-service/Dockerfile new file mode 100644 index 0000000..d06ca3c --- /dev/null +++ b/microservices/course-composite-service/Dockerfile @@ -0,0 +1,20 @@ +# 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 +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 +WORKDIR application +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 diff --git a/microservices/course-composite-service/pom.xml b/microservices/course-composite-service/pom.xml new file mode 100644 index 0000000..b784d8f --- /dev/null +++ b/microservices/course-composite-service/pom.xml @@ -0,0 +1,122 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.6.6 + + + io.javatab.microservices.composite.course + course-composite-service + 1.0.0 + course-composite-service + Demo project for Spring Boot + + 17 + 2021.0.1 + + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-webflux + + + org.springdoc + springdoc-openapi-common + 1.5.10 + + + org.springdoc + springdoc-openapi-webflux-ui + 1.5.10 + + + org.springframework.boot + spring-boot-starter-security + + + + org.springframework.boot + spring-boot-configuration-processor + true + + + org.projectlombok + lombok + true + + + 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 + + + + + + io.javatab.microservices.api + api + 1.0.0 + compile + + + io.javatab.microservices.util + util + 1.0.0 + compile + + + org.springframework.boot + spring-boot-starter-test + test + + + io.projectreactor + reactor-test + test + + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/microservices/course-composite-service/src/main/java/io/javatab/microservices/composite/course/CourseCompositeServiceApplication.java b/microservices/course-composite-service/src/main/java/io/javatab/microservices/composite/course/CourseCompositeServiceApplication.java new file mode 100644 index 0000000..4e0654d --- /dev/null +++ b/microservices/course-composite-service/src/main/java/io/javatab/microservices/composite/course/CourseCompositeServiceApplication.java @@ -0,0 +1,26 @@ +package io.javatab.microservices.composite.course; + +import io.javatab.microservices.composite.course.configuration.OpenApiConfigProperties; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.cloud.client.loadbalancer.LoadBalanced; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.reactive.function.client.ExchangeFilterFunction; +import org.springframework.web.reactive.function.client.WebClient; +import reactor.core.publisher.Mono; + +@SpringBootApplication +@ComponentScan("io.javatab") +@EnableConfigurationProperties(OpenApiConfigProperties.class) +public class CourseCompositeServiceApplication { + + public static void main(String[] args) { + SpringApplication.run(CourseCompositeServiceApplication.class, args); + } + +} diff --git a/microservices/course-composite-service/src/main/java/io/javatab/microservices/composite/course/configuration/OpenApi.java b/microservices/course-composite-service/src/main/java/io/javatab/microservices/composite/course/configuration/OpenApi.java new file mode 100644 index 0000000..44a8d35 --- /dev/null +++ b/microservices/course-composite-service/src/main/java/io/javatab/microservices/composite/course/configuration/OpenApi.java @@ -0,0 +1,57 @@ +package io.javatab.microservices.composite.course.configuration; + +import io.swagger.v3.oas.annotations.enums.SecuritySchemeType; +import io.swagger.v3.oas.annotations.security.OAuthFlow; +import io.swagger.v3.oas.annotations.security.OAuthFlows; +import io.swagger.v3.oas.annotations.security.OAuthScope; +import io.swagger.v3.oas.annotations.security.SecurityScheme; +import io.swagger.v3.oas.models.ExternalDocumentation; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Contact; +import io.swagger.v3.oas.models.info.Info; +import io.swagger.v3.oas.models.info.License; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@SecurityScheme( + name = "security_auth", type = SecuritySchemeType.OAUTH2, + flows = @OAuthFlows( + authorizationCode = @OAuthFlow( + authorizationUrl = "${springdoc.oAuthFlow.authorizationUrl}", + tokenUrl = "${springdoc.oAuthFlow.tokenUrl}", + scopes = { + @OAuthScope(name = "course:read", description = + "read scope"), + @OAuthScope(name = "write:write", description = + "write scope") + } + ))) +@Configuration +public class OpenApi { + + private final OpenApiConfigProperties configuration; + + public OpenApi(OpenApiConfigProperties configuration) { + this.configuration = configuration; + } + + @Bean + public OpenAPI getOpenApiDocumentation() { + return new OpenAPI() + .info(new Info().title(configuration.title()) + .description(configuration.description()) + .version(configuration.version()) + .contact(new Contact() + .name(configuration.contactName()) + .url(configuration.contactUrl()) + .email(configuration.contactEmail())) + .termsOfService(configuration.termsOfService()) + .license(new License() + .name(configuration.license()) + .url(configuration.licenseUrl()))) + .externalDocs(new ExternalDocumentation() + .description(configuration.externalDocDesc()) + .url(configuration.externalDocUrl())); + } + +} diff --git a/microservices/course-composite-service/src/main/java/io/javatab/microservices/composite/course/configuration/OpenApiConfigProperties.java b/microservices/course-composite-service/src/main/java/io/javatab/microservices/composite/course/configuration/OpenApiConfigProperties.java new file mode 100644 index 0000000..0a78d52 --- /dev/null +++ b/microservices/course-composite-service/src/main/java/io/javatab/microservices/composite/course/configuration/OpenApiConfigProperties.java @@ -0,0 +1,17 @@ +package io.javatab.microservices.composite.course.configuration; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +@ConfigurationProperties(prefix = "open-api") +public record OpenApiConfigProperties(String version, + String title, + String description, + String termsOfService, + String license, + String licenseUrl, + String externalDocDesc, + String externalDocUrl, + String contactName, + String contactUrl, + String contactEmail) { +} 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 new file mode 100644 index 0000000..2549ef9 --- /dev/null +++ b/microservices/course-composite-service/src/main/java/io/javatab/microservices/composite/course/configuration/SecurityConfig.java @@ -0,0 +1,29 @@ +package io.javatab.microservices.composite.course.configuration; + +import org.springframework.context.annotation.Bean; +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.*; + +@EnableWebFluxSecurity +public class SecurityConfig { + + @Bean + SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) { + http + .authorizeExchange() + .pathMatchers("/openapi/**").permitAll() + .pathMatchers("/webjars/**").permitAll() + .pathMatchers("/actuator/**").permitAll() + .pathMatchers(POST, "/course-composite/**").hasAuthority("SCOPE_product:write") + .pathMatchers(DELETE, "/course-composite/**").hasAuthority("SCOPE_product:write") + .pathMatchers(GET, "/course-composite/**").hasAuthority("SCOPE_product:read") + .anyExchange().authenticated() + .and() + .oauth2ResourceServer() + .jwt(); + return http.build(); + } +} diff --git a/microservices/course-composite-service/src/main/java/io/javatab/microservices/composite/course/configuration/WebClients.java b/microservices/course-composite-service/src/main/java/io/javatab/microservices/composite/course/configuration/WebClients.java new file mode 100644 index 0000000..ef0b6d5 --- /dev/null +++ b/microservices/course-composite-service/src/main/java/io/javatab/microservices/composite/course/configuration/WebClients.java @@ -0,0 +1,39 @@ +package io.javatab.microservices.composite.course.configuration; + +import io.netty.resolver.DefaultAddressResolverGroup; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.client.loadbalancer.LoadBalanced; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.client.reactive.ReactorClientHttpConnector; +import org.springframework.web.reactive.function.client.ExchangeFilterFunction; +import org.springframework.web.reactive.function.client.WebClient; +import reactor.core.publisher.Mono; +import reactor.netty.http.client.HttpClient; + +@Configuration +public class WebClients { + + private static final Logger logger = LoggerFactory.getLogger(WebClients.class); + + @Bean + @LoadBalanced + public WebClient.Builder loadBalancedWebClientBuilder() { + //HttpClient httpClient = HttpClient.create().resolver(DefaultAddressResolverGroup.INSTANCE); + return WebClient.builder(); + //.filter(logRequest()) + //.clientConnector(new ReactorClientHttpConnector(httpClient)) + //.build(); + } + + + private static ExchangeFilterFunction logRequest() { + return ExchangeFilterFunction.ofRequestProcessor(clientRequest -> { + logger.info("Request: {} {} {}", clientRequest.method(), clientRequest.url(), clientRequest.body()); + clientRequest.headers().forEach((name, values) -> values.forEach(value -> logger.info("{}={}", name, value))); + return Mono.just(clientRequest); + }); + } + +} diff --git a/microservices/course-composite-service/src/main/java/io/javatab/microservices/composite/course/service/CourseCompositeIntegration.java b/microservices/course-composite-service/src/main/java/io/javatab/microservices/composite/course/service/CourseCompositeIntegration.java new file mode 100644 index 0000000..bf0da74 --- /dev/null +++ b/microservices/course-composite-service/src/main/java/io/javatab/microservices/composite/course/service/CourseCompositeIntegration.java @@ -0,0 +1,97 @@ +package io.javatab.microservices.composite.course.service; + +import com.fasterxml.jackson.databind.ObjectMapper; +import io.javatab.microservices.api.core.course.Course; +import io.javatab.microservices.api.core.course.CourseService; +import io.javatab.microservices.api.core.student.Student; +import io.javatab.microservices.api.core.student.StudentService; +import io.javatab.microservices.api.core.vote.Vote; +import io.javatab.microservices.api.core.vote.VoteService; +import io.javatab.microservices.api.exceptions.InvalidInputException; +import io.javatab.microservices.api.exceptions.NotFoundException; +import io.javatab.microservices.util.http.HttpErrorInfo; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.client.WebClient; +import org.springframework.web.reactive.function.client.WebClientResponseException; +import reactor.core.publisher.Mono; + +import java.io.IOException; + +import static java.util.logging.Level.FINE; + +@Component +public class CourseCompositeIntegration implements CourseService, StudentService, VoteService { + + private static final Logger LOG = LoggerFactory.getLogger(CourseCompositeIntegration.class); + + private WebClient webClient; + private final ObjectMapper objectMapper; + + private static final String COURSE_SERVICE_URL = "http://course"; + private static final String STUDENT_SERVICE_URL = "http://student"; + private static final String VOTE_SERVICE_URL = "http://vote"; + + public CourseCompositeIntegration( + WebClient.Builder webClient, + ObjectMapper objectMapper) { + this.webClient = webClient.build(); + this.objectMapper = objectMapper; + } + + private String getErrorMessage(WebClientResponseException ex) { + try { + return objectMapper.readValue(ex.getResponseBodyAsString(), HttpErrorInfo.class).getMessage(); + } catch (IOException ioex) { + return ex.getMessage(); + } + } + + private Throwable handleException(Throwable ex) { + + if (!(ex instanceof WebClientResponseException)) { + LOG.warn("Got a unexpected error: {}, will rethrow it", ex.toString()); + return ex; + } + + WebClientResponseException wcre = (WebClientResponseException)ex; + + switch (wcre.getStatusCode()) { + + case NOT_FOUND: + return new NotFoundException(getErrorMessage(wcre)); + + case UNPROCESSABLE_ENTITY : + return new InvalidInputException(getErrorMessage(wcre)); + + default: + LOG.warn("Got an unexpected HTTP error: {}, will rethrow it", wcre.getStatusCode()); + LOG.warn("Error body: {}", wcre.getResponseBodyAsString()); + return ex; + } + } + @Override + public Mono getCourse(int courseId) { + LOG.info("Fetching courses in Integration layer"); + var url = COURSE_SERVICE_URL + "/course/" + courseId; + return webClient.get().uri(url).retrieve().bodyToMono(Course.class).map(course -> { + System.out.println("Course" + course); + return new Course(1, "d", "f", "r", 2); + }).log(LOG.getName(), FINE).onErrorMap(WebClientResponseException.class, this::handleException); + } + + @Override + public Mono getStudent(String studentId) { + LOG.info("Fetching students in Integration layer"); + var url = STUDENT_SERVICE_URL + "/student/" + studentId; + return webClient.get().uri(url).retrieve().bodyToMono(Student.class).log(LOG.getName(), FINE).onErrorMap(WebClientResponseException.class, this::handleException); + } + + @Override + public Mono getVote(int courseId) { + LOG.info("Fetching votes in Integration layer"); + var url = VOTE_SERVICE_URL + "/vote/" + courseId; + return webClient.get().uri(url).retrieve().bodyToMono(Vote.class).log(LOG.getName(), FINE).onErrorMap(WebClientResponseException.class, this::handleException); + } +} diff --git a/microservices/course-composite-service/src/main/java/io/javatab/microservices/composite/course/service/CourseCompositeServiceImpl.java b/microservices/course-composite-service/src/main/java/io/javatab/microservices/composite/course/service/CourseCompositeServiceImpl.java new file mode 100644 index 0000000..db5ed62 --- /dev/null +++ b/microservices/course-composite-service/src/main/java/io/javatab/microservices/composite/course/service/CourseCompositeServiceImpl.java @@ -0,0 +1,42 @@ +package io.javatab.microservices.composite.course.service; + +import io.javatab.microservices.api.composite.course.CourseAggregate; +import io.javatab.microservices.api.composite.course.CourseCompositeService; +import io.javatab.microservices.api.core.student.Student; +import io.javatab.microservices.util.http.ServiceUtil; +import org.springframework.web.bind.annotation.RestController; +import reactor.core.publisher.Mono; + +import java.util.List; + +@RestController +public class CourseCompositeServiceImpl implements CourseCompositeService { + + private final CourseCompositeIntegration integration; + private final ServiceUtil serviceUtil; + + public CourseCompositeServiceImpl(final CourseCompositeIntegration integration, ServiceUtil serviceUtil) { + this.integration = integration; + this.serviceUtil = serviceUtil; + } + + @Override + public Mono createProduct(CourseAggregate body) { + return Mono.just("CREATED"); + } + + @Override + public Mono getCourse(int courseId) { + // Call integration apis + integration.getCourse(1).subscribe(course -> System.out.println("Course " + course)); + integration.getStudent("name").subscribe(course -> System.out.println("student " + course)); + integration.getVote(1).subscribe(course -> System.out.println("vote " + course)); + return Mono.just(new CourseAggregate(1, 1, 3, 3, + List.of(new Student(1, "Student Name", "email", "password")))); + } + + @Override + public Mono deleteCourse(int courseId) { + return Mono.just("DELETED"); + } +} diff --git a/microservices/course-composite-service/src/main/resources/application.yml b/microservices/course-composite-service/src/main/resources/application.yml new file mode 100644 index 0000000..e82e6c9 --- /dev/null +++ b/microservices/course-composite-service/src/main/resources/application.yml @@ -0,0 +1,19 @@ +spring.config.import: "configserver:" + +spring: + application.name: course-composite + cloud.config: + failFast: true + retry: + initialInterval: 3000 + multiplier: 1.3 + maxInterval: 10000 + maxAttempts: 20 + uri: http://localhost:8888 + username: ${CONFIG_SERVER_USR} + password: ${CONFIG_SERVER_PWD} + +--- +spring.config.activate.on-profile: docker + +spring.cloud.config.uri: http://config-server:8888 \ No newline at end of file diff --git a/microservices/course-composite-service/src/test/java/io/javatab/microservices/composite/course/CourseCompositeServiceApplicationTests.java b/microservices/course-composite-service/src/test/java/io/javatab/microservices/composite/course/CourseCompositeServiceApplicationTests.java new file mode 100644 index 0000000..67f9319 --- /dev/null +++ b/microservices/course-composite-service/src/test/java/io/javatab/microservices/composite/course/CourseCompositeServiceApplicationTests.java @@ -0,0 +1,17 @@ +package io.javatab.microservices.composite.course; + +import org.springframework.boot.test.context.SpringBootTest; + +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; + +@SpringBootTest( + webEnvironment = RANDOM_PORT, + classes = {TestSecurityConfig.class}, + properties = { + "spring.security.oauth2.resourceserver.jwt.issuer-uri=", + "spring.main.allow-bean-definition-overriding=true", + "eureka.client.enabled=false", + "spring.cloud.config.enabled=false"}) +class CourseCompositeServiceApplicationTests { + +} diff --git a/microservices/course-composite-service/src/test/java/io/javatab/microservices/composite/course/TestSecurityConfig.java b/microservices/course-composite-service/src/test/java/io/javatab/microservices/composite/course/TestSecurityConfig.java new file mode 100644 index 0000000..6b2fe44 --- /dev/null +++ b/microservices/course-composite-service/src/test/java/io/javatab/microservices/composite/course/TestSecurityConfig.java @@ -0,0 +1,16 @@ +package io.javatab.microservices.composite.course; + +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.security.config.web.server.ServerHttpSecurity; +import org.springframework.security.web.server.SecurityWebFilterChain; + +@TestConfiguration +public class TestSecurityConfig { + + @Bean + public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) { + http.csrf().disable().authorizeExchange().anyExchange().permitAll(); + return http.build(); + } +} diff --git a/student-service/.gitignore b/microservices/course-service/.gitignore similarity index 100% rename from student-service/.gitignore rename to microservices/course-service/.gitignore diff --git a/microservices/course-service/Dockerfile b/microservices/course-service/Dockerfile new file mode 100644 index 0000000..d06ca3c --- /dev/null +++ b/microservices/course-service/Dockerfile @@ -0,0 +1,20 @@ +# 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 +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 +WORKDIR application +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 diff --git a/course-service/pom.xml b/microservices/course-service/pom.xml similarity index 53% rename from course-service/pom.xml rename to microservices/course-service/pom.xml index 92f4b4b..b09a3e6 100644 --- a/course-service/pom.xml +++ b/microservices/course-service/pom.xml @@ -1,78 +1,95 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.springframework.boot spring-boot-starter-parent - 2.5.4 + 2.6.6 - - com.javatab + io.javatab.microservices.core.course course-service 1.0.0 course-service Demo project for Spring Boot - - 11 - javatab - 2020.0.3 + 17 + 1.16.2 + 2021.0.1 - org.springframework.boot - spring-boot-starter-data-jpa + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-webflux org.springframework.boot - spring-boot-starter-web + spring-boot-starter-data-mongodb org.springframework.cloud spring-cloud-starter-netflix-eureka-client - org.springframework.cloud - spring-cloud-starter-sleuth + org.mapstruct + mapstruct + 1.3.1.Final - org.projectlombok - lombok - true + org.springframework.cloud + spring-cloud-starter-config - org.springframework.boot - spring-boot-devtools - runtime + org.springframework.retry + spring-retry + - org.springframework.cloud - spring-cloud-starter-config + io.javatab.microservices.api + api + 1.0.0 - com.h2database - h2 - runtime + io.javatab.microservices.util + util + 1.0.0 org.springframework.boot spring-boot-starter-test test - - - org.junit.vintage - junit-vintage-engine - - + + + io.projectreactor + reactor-test + test + + + org.testcontainers + mongodb + test + + + org.testcontainers + junit-jupiter + test + + org.testcontainers + testcontainers-bom + ${testcontainers.version} + pom + import + org.springframework.cloud spring-cloud-dependencies @@ -89,28 +106,6 @@ org.springframework.boot spring-boot-maven-plugin - - - com.spotify - dockerfile-maven-plugin - 1.4.13 - - ${docker.image.prefix}/${project.artifactId} - ${project.version} - - target/${project.build.finalName}.jar - - - - - default - install - - build - - - - diff --git a/microservices/course-service/src/main/java/io/javatab/microservices/core/course/CourseServiceApplication.java b/microservices/course-service/src/main/java/io/javatab/microservices/core/course/CourseServiceApplication.java new file mode 100644 index 0000000..3421539 --- /dev/null +++ b/microservices/course-service/src/main/java/io/javatab/microservices/core/course/CourseServiceApplication.java @@ -0,0 +1,18 @@ +package io.javatab.microservices.core.course; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.ComponentScan; + +@SpringBootApplication +@ComponentScan("io.javatab") // To enable Spring Boot's autoconfiguration feature to detect Spring Beans in the api and util projects, we also need to add a @ComponentScan annotation to the main application class, which includes the packages of the api and util projects: +public class CourseServiceApplication { + + public static void main(String[] args) { + ConfigurableApplicationContext ctx = SpringApplication.run(CourseServiceApplication.class, args); + String mongoUri = ctx.getEnvironment().getProperty("spring.data.mongodb.host"); + System.out.println("Connected to Mongo: " + mongoUri); + } + +} diff --git a/microservices/course-service/src/main/java/io/javatab/microservices/core/course/persistence/CourseEntity.java b/microservices/course-service/src/main/java/io/javatab/microservices/core/course/persistence/CourseEntity.java new file mode 100644 index 0000000..3a2c5d0 --- /dev/null +++ b/microservices/course-service/src/main/java/io/javatab/microservices/core/course/persistence/CourseEntity.java @@ -0,0 +1,112 @@ +package io.javatab.microservices.core.course.persistence; + +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; +import org.springframework.data.mongodb.core.index.Indexed; +import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.annotation.Id; +import org.springframework.data.annotation.Version; + +@Document(collection = "courses") +public class CourseEntity { + + @Id + private String id; + + @Version + private Integer version; + + @Indexed(unique = true) + private int courseId; + + private String courseName; + + private String author; + + private int voteId; + + private String content; + + public CourseEntity() { + } + + public CourseEntity(int courseId, String courseName, String author, int voteId, String content) { + this.courseId = courseId; + this.courseName = courseName; + this.author = author; + this.voteId = voteId; + this.content = content; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public Integer getVersion() { + return version; + } + + public void setVersion(Integer version) { + this.version = version; + } + + public int getCourseId() { + return courseId; + } + + public void setCourseId(int courseId) { + this.courseId = courseId; + } + + public String getCourseName() { + return courseName; + } + + public void setCourseName(String courseName) { + this.courseName = courseName; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public int getVoteId() { + return voteId; + } + + public void setVoteId(int voteId) { + this.voteId = voteId; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + + if (o == null || getClass() != o.getClass()) return false; + + CourseEntity entity = (CourseEntity) o; + + return new EqualsBuilder().append(courseId, entity.courseId).append(voteId, entity.voteId).append(id, entity.id).append(version, entity.version).append(courseName, entity.courseName).append(author, entity.author).append(content, entity.content).isEquals(); + } + + @Override + public int hashCode() { + return new HashCodeBuilder(17, 37).append(id).append(version).append(courseId).append(courseName).append(author).append(voteId).append(content).toHashCode(); + } +} diff --git a/microservices/course-service/src/main/java/io/javatab/microservices/core/course/persistence/CourseRepository.java b/microservices/course-service/src/main/java/io/javatab/microservices/core/course/persistence/CourseRepository.java new file mode 100644 index 0000000..3194201 --- /dev/null +++ b/microservices/course-service/src/main/java/io/javatab/microservices/core/course/persistence/CourseRepository.java @@ -0,0 +1,6 @@ +package io.javatab.microservices.core.course.persistence; + +import org.springframework.data.repository.CrudRepository; + +public interface CourseRepository extends CrudRepository { +} diff --git a/microservices/course-service/src/main/java/io/javatab/microservices/core/course/service/CourseServiceImpl.java b/microservices/course-service/src/main/java/io/javatab/microservices/core/course/service/CourseServiceImpl.java new file mode 100644 index 0000000..3fb4424 --- /dev/null +++ b/microservices/course-service/src/main/java/io/javatab/microservices/core/course/service/CourseServiceImpl.java @@ -0,0 +1,27 @@ +package io.javatab.microservices.core.course.service; + +import io.javatab.microservices.api.core.course.Course; +import io.javatab.microservices.api.core.course.CourseService; +import io.javatab.microservices.util.http.ServiceUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.annotation.RestController; +import reactor.core.publisher.Mono; + +@RestController +public class CourseServiceImpl implements CourseService { + + private static final Logger LOG = LoggerFactory.getLogger(CourseServiceImpl.class); + + private final ServiceUtil serviceUtil; + + public CourseServiceImpl(final ServiceUtil serviceUtil) { + this.serviceUtil = serviceUtil; + } + + @Override + public Mono getCourse(int courseId) { + LOG.info("In course service"); + return Mono.just(new Course(123, "Test", "Test", "Test content", 1)); + } +} diff --git a/microservices/course-service/src/main/resources/application.yml b/microservices/course-service/src/main/resources/application.yml new file mode 100644 index 0000000..968bed7 --- /dev/null +++ b/microservices/course-service/src/main/resources/application.yml @@ -0,0 +1,19 @@ +spring.config.import: "configserver:" + +spring: + application.name: course + cloud.config: + failFast: true + retry: + initialInterval: 3000 + multiplier: 1.3 + maxInterval: 10000 + maxAttempts: 20 + uri: http://localhost:8888 + username: ${CONFIG_SERVER_USR} + password: ${CONFIG_SERVER_PWD} + +--- +spring.config.activate.on-profile: docker + +spring.cloud.config.uri: http://config-server:8888 \ No newline at end of file diff --git a/microservices/course-service/src/test/java/io/javatab/microservices/core/course/CourseServiceImplApplicationTests.java b/microservices/course-service/src/test/java/io/javatab/microservices/core/course/CourseServiceImplApplicationTests.java new file mode 100644 index 0000000..0c36fd2 --- /dev/null +++ b/microservices/course-service/src/test/java/io/javatab/microservices/core/course/CourseServiceImplApplicationTests.java @@ -0,0 +1,11 @@ +package io.javatab.microservices.core.course; + +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 CourseServiceImplApplicationTests extends MongoDbTestBase { + +} diff --git a/microservices/course-service/src/test/java/io/javatab/microservices/core/course/MongoDbTestBase.java b/microservices/course-service/src/test/java/io/javatab/microservices/core/course/MongoDbTestBase.java new file mode 100644 index 0000000..b8bcbaa --- /dev/null +++ b/microservices/course-service/src/test/java/io/javatab/microservices/core/course/MongoDbTestBase.java @@ -0,0 +1,20 @@ +package io.javatab.microservices.core.course; + +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; +import org.testcontainers.containers.MongoDBContainer; + +public abstract class MongoDbTestBase { + private static MongoDBContainer database = new MongoDBContainer("mongo:4.4.2"); + + static { + database.start(); + } + + @DynamicPropertySource + static void setProperties(DynamicPropertyRegistry registry) { + registry.add("spring.data.mongodb.host", database::getContainerIpAddress); + registry.add("spring.data.mongodb.port", () -> database.getMappedPort(27017)); + registry.add("spring.data.mongodb.database", () -> "test"); + } +} diff --git a/microservices/course-service/src/test/java/io/javatab/microservices/core/course/PersistenceTests.java b/microservices/course-service/src/test/java/io/javatab/microservices/core/course/PersistenceTests.java new file mode 100644 index 0000000..bbc18aa --- /dev/null +++ b/microservices/course-service/src/test/java/io/javatab/microservices/core/course/PersistenceTests.java @@ -0,0 +1,41 @@ +package io.javatab.microservices.core.course; + + +import io.javatab.microservices.core.course.persistence.CourseEntity; +import io.javatab.microservices.core.course.persistence.CourseRepository; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration; +import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@DataMongoTest( + excludeAutoConfiguration = EmbeddedMongoAutoConfiguration.class, + properties = {"spring.cloud.config.enabled=false"} +) +public class PersistenceTests extends MongoDbTestBase { + + @Autowired + private CourseRepository repository; + private CourseEntity savedEntity; + + @BeforeEach + void setUp() { + repository.deleteAll(); + CourseEntity entity = new CourseEntity(1, "Course Name", "Author", 4, "Content"); + savedEntity = repository.save(entity); + assertEquals(entity, savedEntity); + } + + @Test + void create() { + CourseEntity newEntity = new CourseEntity(1, "Course Name", "Author", 4, "Content"); + repository.save(newEntity); + + CourseEntity foundEntity = repository.findById(newEntity.getId()).get(); + assertEquals(newEntity.getId(), foundEntity.getId()); + assertEquals(2, repository.count()); + } +} diff --git a/microservices/course-service/src/test/resources/application.yml b/microservices/course-service/src/test/resources/application.yml new file mode 100644 index 0000000..e69de29 diff --git a/microservices/course-service/src/test/resources/logback-test.xml b/microservices/course-service/src/test/resources/logback-test.xml new file mode 100644 index 0000000..b6c7deb --- /dev/null +++ b/microservices/course-service/src/test/resources/logback-test.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/course-service/.gitignore b/microservices/search-service/.gitignore similarity index 72% rename from course-service/.gitignore rename to microservices/search-service/.gitignore index 153c933..549e00a 100644 --- a/course-service/.gitignore +++ b/microservices/search-service/.gitignore @@ -1,6 +1,8 @@ HELP.md -/target/ +target/ !.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ ### STS ### .apt_generated @@ -23,7 +25,9 @@ HELP.md /dist/ /nbdist/ /.nb-gradle/ -/build/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ ### VS Code ### .vscode/ diff --git a/microservices/search-service/Dockerfile b/microservices/search-service/Dockerfile new file mode 100644 index 0000000..d06ca3c --- /dev/null +++ b/microservices/search-service/Dockerfile @@ -0,0 +1,20 @@ +# 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 +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 +WORKDIR application +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 diff --git a/microservices/search-service/pom.xml b/microservices/search-service/pom.xml new file mode 100644 index 0000000..ea9231f --- /dev/null +++ b/microservices/search-service/pom.xml @@ -0,0 +1,111 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.6.6 + + + io.javatab.microservices.core.search + search-service + 1.0.0 + search-service + Demo project for Spring Boot + + 17 + 1.16.2 + 2021.0.1 + + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-webflux + + + org.springframework.boot + spring-boot-starter-data-elasticsearch + + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-client + + + org.springframework.cloud + spring-cloud-starter-config + + + org.springframework.retry + spring-retry + + + + io.javatab.microservices.api + api + 1.0.0 + compile + + + io.javatab.microservices.util + util + 1.0.0 + compile + + + org.springframework.boot + spring-boot-starter-test + test + + + io.projectreactor + reactor-test + test + + + org.testcontainers + elasticsearch + test + + + org.testcontainers + junit-jupiter + test + + + + + + + org.testcontainers + testcontainers-bom + ${testcontainers.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/microservices/search-service/src/main/java/io/javatab/microservices/core/search/SearchServiceApplication.java b/microservices/search-service/src/main/java/io/javatab/microservices/core/search/SearchServiceApplication.java new file mode 100644 index 0000000..5ca8e37 --- /dev/null +++ b/microservices/search-service/src/main/java/io/javatab/microservices/core/search/SearchServiceApplication.java @@ -0,0 +1,17 @@ +package io.javatab.microservices.core.search; + +import io.javatab.microservices.core.search.persistence.ElasticRepository; +import io.javatab.microservices.core.search.persistence.SearchEntity; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; + +@SpringBootApplication +@ComponentScan("io.javatab") +public class SearchServiceApplication { + + public static void main(String[] args) { + SpringApplication.run(SearchServiceApplication.class, args); + } +} diff --git a/microservices/search-service/src/main/java/io/javatab/microservices/core/search/persistence/ElasticRepository.java b/microservices/search-service/src/main/java/io/javatab/microservices/core/search/persistence/ElasticRepository.java new file mode 100644 index 0000000..c85016e --- /dev/null +++ b/microservices/search-service/src/main/java/io/javatab/microservices/core/search/persistence/ElasticRepository.java @@ -0,0 +1,39 @@ +package io.javatab.microservices.core.search.persistence; + + +import com.fasterxml.jackson.databind.ObjectMapper; +import io.javatab.microservices.api.core.course.Course; +import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; +import org.elasticsearch.action.delete.DeleteResponse; +import org.elasticsearch.action.index.IndexResponse; +import org.elasticsearch.client.RequestOptions; +import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient; +import org.springframework.stereotype.Repository; +import reactor.core.publisher.Mono; + +import java.util.Map; +import java.util.UUID; + +@Repository +public class ElasticRepository { + + public static final String COURSE_INDEX = "course-store"; + private final ReactiveElasticsearchClient client; + private final ObjectMapper objectMapper; + + public ElasticRepository(ReactiveElasticsearchClient client, ObjectMapper objectMapper) { + this.client = client; + this.objectMapper = objectMapper; + } + + public Mono createCourse(SearchEntity course) { + String id = UUID.randomUUID().toString(); + Map documentMapper = objectMapper.convertValue(course, + Map.class); + return client.index(indexRequest -> indexRequest.index(COURSE_INDEX).id(id).source(documentMapper)); + } + + public Mono deleteCourse() { + return client.delete(deleteRequest -> deleteRequest.index(COURSE_INDEX)); + } +} diff --git a/microservices/search-service/src/main/java/io/javatab/microservices/core/search/persistence/SearchEntity.java b/microservices/search-service/src/main/java/io/javatab/microservices/core/search/persistence/SearchEntity.java new file mode 100644 index 0000000..fd9f35f --- /dev/null +++ b/microservices/search-service/src/main/java/io/javatab/microservices/core/search/persistence/SearchEntity.java @@ -0,0 +1,5 @@ +package io.javatab.microservices.core.search.persistence; + + +public record SearchEntity(String courseName, int courseId) { +} diff --git a/microservices/search-service/src/main/java/io/javatab/microservices/core/search/service/SearchServiceImpl.java b/microservices/search-service/src/main/java/io/javatab/microservices/core/search/service/SearchServiceImpl.java new file mode 100644 index 0000000..3e2025b --- /dev/null +++ b/microservices/search-service/src/main/java/io/javatab/microservices/core/search/service/SearchServiceImpl.java @@ -0,0 +1,18 @@ +package io.javatab.microservices.core.search.service; + +import io.javatab.microservices.api.core.search.SearchRecord; +import io.javatab.microservices.api.core.search.SearchService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import reactor.core.publisher.Mono; + +public class SearchServiceImpl implements SearchService { + private static final Logger LOG = LoggerFactory.getLogger(SearchServiceImpl.class); + + + @Override + public Mono getCourse(String courseName) { + LOG.info("In log service"); + return Mono.just(new SearchRecord(1, "course name", 1, 2)); + } +} diff --git a/microservices/search-service/src/main/resources/application.yml b/microservices/search-service/src/main/resources/application.yml new file mode 100644 index 0000000..d7039a6 --- /dev/null +++ b/microservices/search-service/src/main/resources/application.yml @@ -0,0 +1,19 @@ +spring.config.import: "configserver:" + +spring: + application.name: search + cloud.config: + failFast: true + retry: + initialInterval: 3000 + multiplier: 1.3 + maxInterval: 10000 + maxAttempts: 20 + uri: http://localhost:8888 + username: ${CONFIG_SERVER_USR} + password: ${CONFIG_SERVER_PWD} + +--- +spring.config.activate.on-profile: docker + +spring.cloud.config.uri: http://config-server:8888 \ No newline at end of file diff --git a/microservices/search-service/src/test/java/io/javatab/microservices/core/search/ElasticsearchTestBase.java b/microservices/search-service/src/test/java/io/javatab/microservices/core/search/ElasticsearchTestBase.java new file mode 100644 index 0000000..9ff4bc1 --- /dev/null +++ b/microservices/search-service/src/test/java/io/javatab/microservices/core/search/ElasticsearchTestBase.java @@ -0,0 +1,39 @@ +package io.javatab.microservices.core.search; + +import org.apache.http.HttpHost; +import org.elasticsearch.client.Request; +import org.elasticsearch.client.Response; +import org.elasticsearch.client.RestClient; +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; +import org.testcontainers.elasticsearch.ElasticsearchContainer; + +import java.io.IOException; +import java.util.Collections; + +public abstract class ElasticsearchTestBase { + private static ElasticsearchContainer database = new ElasticsearchContainer("elasticsearch:7.17.2"); + + static { + database.start(); + } + + @DynamicPropertySource + static void setProperties(DynamicPropertyRegistry registry) { + registry.add("spring.elasticsearch.uris", () -> Collections.singletonList("http://" + database.getContainerIpAddress() + "/9200")); + } + + RestClient client = RestClient.builder(HttpHost.create(database.getHttpHostAddress())) + .build(); + + Response response; + + { + try { + response = client.performRequest(new Request("GET", "/_cluster/health")); + } catch (IOException e) { + e.printStackTrace(); + } + } + +} diff --git a/microservices/search-service/src/test/java/io/javatab/microservices/core/search/PersistenceTests.java b/microservices/search-service/src/test/java/io/javatab/microservices/core/search/PersistenceTests.java new file mode 100644 index 0000000..38708c5 --- /dev/null +++ b/microservices/search-service/src/test/java/io/javatab/microservices/core/search/PersistenceTests.java @@ -0,0 +1,21 @@ +package io.javatab.microservices.core.search; + +import io.javatab.microservices.core.search.persistence.ElasticRepository; +import io.javatab.microservices.core.search.persistence.SearchEntity; +import org.junit.jupiter.api.BeforeEach; +import org.springframework.beans.factory.annotation.Autowired; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class PersistenceTests extends ElasticsearchTestBase { + + @Autowired + private ElasticRepository repository; + private SearchEntity savedEntity; + + @BeforeEach + void setUp() { + repository.deleteCourse(); + SearchEntity entity = new SearchEntity("Course Name", 1); + } +} diff --git a/microservices/search-service/src/test/java/io/javatab/microservices/core/search/SearchServiceApplicationTests.java b/microservices/search-service/src/test/java/io/javatab/microservices/core/search/SearchServiceApplicationTests.java new file mode 100644 index 0000000..81f100c --- /dev/null +++ b/microservices/search-service/src/test/java/io/javatab/microservices/core/search/SearchServiceApplicationTests.java @@ -0,0 +1,10 @@ +package io.javatab.microservices.core.search; + +import org.springframework.boot.test.context.SpringBootTest; + +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; + +@SpringBootTest(webEnvironment=RANDOM_PORT, properties = {"eureka.client.enabled=false", "spring.cloud.config.enabled=false"}) +class SearchServiceApplicationTests extends ElasticsearchTestBase { + +} diff --git a/microservices/search-service/src/test/resource/application.yml b/microservices/search-service/src/test/resource/application.yml new file mode 100644 index 0000000..e69de29 diff --git a/discovery-service/.gitignore b/microservices/student-service/.gitignore similarity index 72% rename from discovery-service/.gitignore rename to microservices/student-service/.gitignore index 153c933..549e00a 100644 --- a/discovery-service/.gitignore +++ b/microservices/student-service/.gitignore @@ -1,6 +1,8 @@ HELP.md -/target/ +target/ !.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ ### STS ### .apt_generated @@ -23,7 +25,9 @@ HELP.md /dist/ /nbdist/ /.nb-gradle/ -/build/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ ### VS Code ### .vscode/ diff --git a/microservices/student-service/Dockerfile b/microservices/student-service/Dockerfile new file mode 100644 index 0000000..d06ca3c --- /dev/null +++ b/microservices/student-service/Dockerfile @@ -0,0 +1,20 @@ +# 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 +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 +WORKDIR application +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 diff --git a/student-service/pom.xml b/microservices/student-service/pom.xml similarity index 55% rename from student-service/pom.xml rename to microservices/student-service/pom.xml index d2abad4..ff6afef 100644 --- a/student-service/pom.xml +++ b/microservices/student-service/pom.xml @@ -5,75 +5,90 @@ org.springframework.boot spring-boot-starter-parent - 2.5.4 + 2.6.6 - com.javatab + io.javatab.microservices.core.student student-service - 0.0.1-SNAPSHOT + 1.0.0 student-service Demo project for Spring Boot - 11 - javatab - 2020.0.3 + 17 + 1.16.2 + 2021.0.1 org.springframework.boot - spring-boot-starter-web + spring-boot-starter-actuator - org.springframework.boot - spring-boot-starter-data-mongodb + spring-boot-starter-webflux org.springframework.boot - spring-boot-starter-web + spring-boot-starter-data-jpa - - org.projectlombok - lombok - true + org.postgresql + postgresql + runtime - org.springframework.cloud spring-cloud-starter-netflix-eureka-client - org.springframework.cloud spring-cloud-starter-config - org.projectlombok - lombok + org.springframework.retry + spring-retry + + + + io.javatab.microservices.api + api + 1.0.0 + + + io.javatab.microservices.util + util + 1.0.0 - org.springframework.boot spring-boot-starter-test test - - - org.junit.vintage - junit-vintage-engine - - - - - org.springframework.cloud - spring-cloud-starter-stream-kafka + io.projectreactor + reactor-test + test + + + org.testcontainers + junit-jupiter + test + + + org.testcontainers + postgresql + test - + + org.testcontainers + testcontainers-bom + ${testcontainers.version} + pom + import + org.springframework.cloud spring-cloud-dependencies @@ -84,35 +99,12 @@ - org.springframework.boot spring-boot-maven-plugin - - - com.spotify - dockerfile-maven-plugin - 1.4.13 - - ${docker.image.prefix}/${project.artifactId} - ${project.version} - - target/${project.build.finalName}.jar - - - - - default - install - - build - - - - diff --git a/microservices/student-service/src/main/java/io/javatab/microservices/core/student/StudentServiceApplication.java b/microservices/student-service/src/main/java/io/javatab/microservices/core/student/StudentServiceApplication.java new file mode 100644 index 0000000..b4ecbdb --- /dev/null +++ b/microservices/student-service/src/main/java/io/javatab/microservices/core/student/StudentServiceApplication.java @@ -0,0 +1,19 @@ +package io.javatab.microservices.core.student; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.ComponentScan; + +@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class }) +@ComponentScan("io.javatab") +public class StudentServiceApplication { + + public static void main(String[] args) { + ConfigurableApplicationContext ctx = SpringApplication.run(StudentServiceApplication.class, args); + String postgresqlUri = ctx.getEnvironment().getProperty("spring.datasource.url"); + System.out.println("Connected to Postgres SQL: " + postgresqlUri); + } + +} diff --git a/microservices/student-service/src/main/java/io/javatab/microservices/core/student/persistence/StudentEntity.java b/microservices/student-service/src/main/java/io/javatab/microservices/core/student/persistence/StudentEntity.java new file mode 100644 index 0000000..6075dda --- /dev/null +++ b/microservices/student-service/src/main/java/io/javatab/microservices/core/student/persistence/StudentEntity.java @@ -0,0 +1,52 @@ +package io.javatab.microservices.core.student.persistence; + +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; + +import javax.persistence.*; + +@Entity +@Table(name = "student") +public class StudentEntity { + + @Id + @GeneratedValue + private int id; + + private int studentId; + private String studentName; + private String email; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public StudentEntity() { + } + + public StudentEntity(int studentId, String studentName, String email) { + this.studentId = studentId; + this.studentName = studentName; + this.email = email; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + + if (o == null || getClass() != o.getClass()) return false; + + StudentEntity that = (StudentEntity) o; + + return new EqualsBuilder().append(studentId, that.studentId).append(studentName, that.studentName).append(email, that.email).isEquals(); + } + + @Override + public int hashCode() { + return new HashCodeBuilder(17, 37).append(studentId).append(studentName).append(email).toHashCode(); + } +} diff --git a/microservices/student-service/src/main/java/io/javatab/microservices/core/student/persistence/StudentRepository.java b/microservices/student-service/src/main/java/io/javatab/microservices/core/student/persistence/StudentRepository.java new file mode 100644 index 0000000..3e78e3f --- /dev/null +++ b/microservices/student-service/src/main/java/io/javatab/microservices/core/student/persistence/StudentRepository.java @@ -0,0 +1,7 @@ +package io.javatab.microservices.core.student.persistence; + +import org.springframework.data.repository.PagingAndSortingRepository; + +public interface StudentRepository extends PagingAndSortingRepository { + +} diff --git a/microservices/student-service/src/main/java/io/javatab/microservices/core/student/service/StudentServiceImpl.java b/microservices/student-service/src/main/java/io/javatab/microservices/core/student/service/StudentServiceImpl.java new file mode 100644 index 0000000..fb92528 --- /dev/null +++ b/microservices/student-service/src/main/java/io/javatab/microservices/core/student/service/StudentServiceImpl.java @@ -0,0 +1,27 @@ +package io.javatab.microservices.core.student.service; + +import io.javatab.microservices.api.core.student.Student; +import io.javatab.microservices.api.core.student.StudentService; +import io.javatab.microservices.util.http.ServiceUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.annotation.RestController; +import reactor.core.publisher.Mono; + +@RestController +public class StudentServiceImpl implements StudentService { + + private static final Logger LOG = LoggerFactory.getLogger(StudentServiceImpl.class); + + private final ServiceUtil serviceUtil; + + public StudentServiceImpl(final ServiceUtil serviceUtil) { + this.serviceUtil = serviceUtil; + } + + @Override + public Mono getStudent(String studentId) { + LOG.info("In student service"); + return Mono.just(new Student(1, "Nasir", "nasir@gmail.com", "pass00d")); + } +} diff --git a/microservices/student-service/src/main/resources/application.yml b/microservices/student-service/src/main/resources/application.yml new file mode 100644 index 0000000..fffb97b --- /dev/null +++ b/microservices/student-service/src/main/resources/application.yml @@ -0,0 +1,19 @@ +spring.config.import: "configserver:" + +spring: + application.name: student + cloud.config: + failFast: true + retry: + initialInterval: 3000 + multiplier: 1.3 + maxInterval: 10000 + maxAttempts: 20 + uri: http://localhost:8888 + username: ${CONFIG_SERVER_USR} + password: ${CONFIG_SERVER_PWD} + +--- +spring.config.activate.on-profile: docker + +spring.cloud.config.uri: http://config-server:8888 \ No newline at end of file diff --git a/microservices/student-service/src/test/java/io/javatab/microservices/core/student/PersistenceTests.java b/microservices/student-service/src/test/java/io/javatab/microservices/core/student/PersistenceTests.java new file mode 100644 index 0000000..69b3030 --- /dev/null +++ b/microservices/student-service/src/test/java/io/javatab/microservices/core/student/PersistenceTests.java @@ -0,0 +1,41 @@ +package io.javatab.microservices.core.student; + +import io.javatab.microservices.core.student.persistence.StudentEntity; +import io.javatab.microservices.core.student.persistence.StudentRepository; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.transaction.annotation.Transactional; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.springframework.transaction.annotation.Propagation.NOT_SUPPORTED; + +@Transactional(propagation = NOT_SUPPORTED) +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) +@DataJpaTest(properties = {"spring.jpa.hibernate.ddl-auto=update", "spring.cloud.config.enabled=false"}) +public class PersistenceTests extends PostgresTestBase { + + @Autowired + private StudentRepository repository; + + private StudentEntity savedEntity; + + @BeforeEach + void setUp() { + repository.deleteAll(); + StudentEntity entity = new StudentEntity(1, "Student Name", "student@email.com"); + savedEntity = repository.save(entity); + assertEquals(entity, savedEntity); + } + + @Test + void create() { + StudentEntity newEntity = new StudentEntity(1, "Student Name", "student@email.com"); + repository.save(newEntity); + + StudentEntity foundEntity = repository.findById(newEntity.getId()).get(); + assertEquals(newEntity.getId(), newEntity.getId()); + } +} diff --git a/microservices/student-service/src/test/java/io/javatab/microservices/core/student/PostgresTestBase.java b/microservices/student-service/src/test/java/io/javatab/microservices/core/student/PostgresTestBase.java new file mode 100644 index 0000000..8cca0fb --- /dev/null +++ b/microservices/student-service/src/test/java/io/javatab/microservices/core/student/PostgresTestBase.java @@ -0,0 +1,21 @@ +package io.javatab.microservices.core.student; + +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; +import org.testcontainers.containers.PostgreSQLContainer; + +public class PostgresTestBase { + + private static PostgreSQLContainer database = new PostgreSQLContainer("postgres:alpine3.15"); + + static { + database.start(); + } + + @DynamicPropertySource + static void databaseProperties(DynamicPropertyRegistry registry) { + registry.add("spring.datasource.url", database::getJdbcUrl); + registry.add("spring.datasource.username", database::getUsername); + registry.add("spring.datasource.password", database::getPassword); + } +} diff --git a/microservices/student-service/src/test/java/io/javatab/microservices/core/student/StudentServiceApplicationTests.java b/microservices/student-service/src/test/java/io/javatab/microservices/core/student/StudentServiceApplicationTests.java new file mode 100644 index 0000000..ac9883b --- /dev/null +++ b/microservices/student-service/src/test/java/io/javatab/microservices/core/student/StudentServiceApplicationTests.java @@ -0,0 +1,11 @@ +package io.javatab.microservices.core.student; + +import org.springframework.boot.test.context.SpringBootTest; + +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; + +@SpringBootTest(webEnvironment=RANDOM_PORT, properties = {"eureka.client.enabled=false", "spring.cloud.config.enabled=false"}) +class StudentServiceApplicationTests { + + +} diff --git a/microservices/student-service/src/test/resources/application.yml b/microservices/student-service/src/test/resources/application.yml new file mode 100644 index 0000000..e69de29 diff --git a/auth-service/.gitignore b/microservices/vote-service/.gitignore similarity index 72% rename from auth-service/.gitignore rename to microservices/vote-service/.gitignore index 153c933..549e00a 100644 --- a/auth-service/.gitignore +++ b/microservices/vote-service/.gitignore @@ -1,6 +1,8 @@ HELP.md -/target/ +target/ !.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ ### STS ### .apt_generated @@ -23,7 +25,9 @@ HELP.md /dist/ /nbdist/ /.nb-gradle/ -/build/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ ### VS Code ### .vscode/ diff --git a/microservices/vote-service/Dockerfile b/microservices/vote-service/Dockerfile new file mode 100644 index 0000000..d06ca3c --- /dev/null +++ b/microservices/vote-service/Dockerfile @@ -0,0 +1,20 @@ +# 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 +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 +WORKDIR application +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 diff --git a/microservices/vote-service/pom.xml b/microservices/vote-service/pom.xml new file mode 100644 index 0000000..cb7306c --- /dev/null +++ b/microservices/vote-service/pom.xml @@ -0,0 +1,103 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.6.6 + + + io.javatab.microservices.core.vote + vote-service + 1.0.0 + vote-service + Demo project for Spring Boot + + 17 + 1.16.2 + 2021.0.1 + + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-webflux + + + org.springframework.boot + spring-boot-starter-data-redis-reactive + + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-client + + + org.springframework.cloud + spring-cloud-starter-config + + + org.springframework.retry + spring-retry + + + + io.javatab.microservices.api + api + 1.0.0 + compile + + + io.javatab.microservices.util + util + 1.0.0 + compile + + + org.springframework.boot + spring-boot-starter-test + test + + + io.projectreactor + reactor-test + test + + + org.testcontainers + junit-jupiter + test + + + + + + org.testcontainers + testcontainers-bom + ${testcontainers.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/microservices/vote-service/src/main/java/io/javatab/microservices/core/.DS_Store b/microservices/vote-service/src/main/java/io/javatab/microservices/core/.DS_Store new file mode 100644 index 0000000..a81c1d2 Binary files /dev/null and b/microservices/vote-service/src/main/java/io/javatab/microservices/core/.DS_Store differ diff --git a/microservices/vote-service/src/main/java/io/javatab/microservices/core/vote/VoteServiceApplication.java b/microservices/vote-service/src/main/java/io/javatab/microservices/core/vote/VoteServiceApplication.java new file mode 100644 index 0000000..6e25d4c --- /dev/null +++ b/microservices/vote-service/src/main/java/io/javatab/microservices/core/vote/VoteServiceApplication.java @@ -0,0 +1,27 @@ +package io.javatab.microservices.core.vote; + +import io.javatab.microservices.api.core.vote.Vote; +import io.javatab.microservices.core.vote.persistence.RedisRepository; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class VoteServiceApplication implements CommandLineRunner { + + private final RedisRepository repository; + + public VoteServiceApplication(RedisRepository repository) { + this.repository = repository; + } + + public static void main(String[] args) { + SpringApplication.run(VoteServiceApplication.class, args); + } + + @Override + public void run(String... args) throws Exception { + Vote vote = new Vote(1, 1, 3, 9); + repository.save(vote).subscribe(aLong -> System.out.println(repository.getVote(aLong).subscribe(vote1 -> System.out.println("Vote " + vote1.courseId())))); + } +} diff --git a/microservices/vote-service/src/main/java/io/javatab/microservices/core/vote/configuration/RedisConfig.java b/microservices/vote-service/src/main/java/io/javatab/microservices/core/vote/configuration/RedisConfig.java new file mode 100644 index 0000000..2bbc52a --- /dev/null +++ b/microservices/vote-service/src/main/java/io/javatab/microservices/core/vote/configuration/RedisConfig.java @@ -0,0 +1,21 @@ +package io.javatab.microservices.core.vote.configuration; + +import io.javatab.microservices.api.core.vote.Vote; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.ReactiveRedisConnectionFactory; +import org.springframework.data.redis.core.ReactiveRedisTemplate; +import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.RedisSerializationContext; + +@Configuration +public class RedisConfig { + + @Bean + public ReactiveRedisTemplate reactiveRedisTemplate(ReactiveRedisConnectionFactory factory) { + return new ReactiveRedisTemplate( + factory, + RedisSerializationContext.fromSerializer(new Jackson2JsonRedisSerializer(Vote.class)) + ); + } +} diff --git a/microservices/vote-service/src/main/java/io/javatab/microservices/core/vote/persistence/RedisRepository.java b/microservices/vote-service/src/main/java/io/javatab/microservices/core/vote/persistence/RedisRepository.java new file mode 100644 index 0000000..425b41a --- /dev/null +++ b/microservices/vote-service/src/main/java/io/javatab/microservices/core/vote/persistence/RedisRepository.java @@ -0,0 +1,29 @@ +package io.javatab.microservices.core.vote.persistence; + +import io.javatab.microservices.api.core.vote.Vote; +import org.springframework.data.redis.core.ReactiveHashOperations; +import org.springframework.data.redis.core.ReactiveRedisOperations; +import org.springframework.stereotype.Repository; +import reactor.core.publisher.Mono; + +@Repository +public class RedisRepository { + + private final static String KEY = "VOTE"; + + private final ReactiveRedisOperations redisOperations; + private final ReactiveHashOperations hashOperations; + + public RedisRepository(ReactiveRedisOperations redisOperations) { + this.redisOperations = redisOperations; + this.hashOperations = redisOperations.opsForHash(); + } + + public Mono save(Vote post){ + return this.redisOperations.opsForList().rightPush(KEY, post); + } + + public Mono getVote(Long id) { + return this.redisOperations.opsForList().rightPop(KEY); + } +} diff --git a/microservices/vote-service/src/main/java/io/javatab/microservices/core/vote/persistence/VoteEntity.java b/microservices/vote-service/src/main/java/io/javatab/microservices/core/vote/persistence/VoteEntity.java new file mode 100644 index 0000000..2537074 --- /dev/null +++ b/microservices/vote-service/src/main/java/io/javatab/microservices/core/vote/persistence/VoteEntity.java @@ -0,0 +1,23 @@ +package io.javatab.microservices.core.vote.persistence; + +import nonapi.io.github.classgraph.json.Id; +import org.springframework.data.annotation.Version; +import org.springframework.data.redis.core.RedisHash; + +@RedisHash("vote") +public class VoteEntity { + + @Id + private String id; + + @Version + private Integer version; + + private int courseId; + + private int studentId; + + private int like; + + private int dislike; +} diff --git a/microservices/vote-service/src/main/java/io/javatab/microservices/core/vote/service/VoteServiceImpl.java b/microservices/vote-service/src/main/java/io/javatab/microservices/core/vote/service/VoteServiceImpl.java new file mode 100644 index 0000000..9d0d77d --- /dev/null +++ b/microservices/vote-service/src/main/java/io/javatab/microservices/core/vote/service/VoteServiceImpl.java @@ -0,0 +1,29 @@ +package io.javatab.microservices.core.vote.service; + +import io.javatab.microservices.api.core.vote.Vote; +import io.javatab.microservices.api.core.vote.VoteService; +import io.javatab.microservices.util.http.ServiceUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.web.bind.annotation.RestController; +import reactor.core.publisher.Mono; + +@RestController +@ComponentScan("io.javatab") +public class VoteServiceImpl implements VoteService { + + private static final Logger LOG = LoggerFactory.getLogger(VoteServiceImpl.class); + + private final ServiceUtil serviceUtil; + + public VoteServiceImpl(ServiceUtil serviceUtil) { + this.serviceUtil = serviceUtil; + } + + @Override + public Mono getVote(int courseId) { + LOG.info("In vote service"); + return Mono.just(new Vote(1, 123, 1, 2)); + } +} diff --git a/microservices/vote-service/src/main/resources/application.yml b/microservices/vote-service/src/main/resources/application.yml new file mode 100644 index 0000000..84fa0e1 --- /dev/null +++ b/microservices/vote-service/src/main/resources/application.yml @@ -0,0 +1,19 @@ +spring.config.import: "configserver:" + +spring: + application.name: vote + cloud.config: + failFast: true + retry: + initialInterval: 3000 + multiplier: 1.3 + maxInterval: 10000 + maxAttempts: 20 + uri: http://localhost:8888 + username: ${CONFIG_SERVER_USR} + password: ${CONFIG_SERVER_PWD} + +--- +spring.config.activate.on-profile: docker + +spring.cloud.config.uri: http://config-server:8888 \ No newline at end of file diff --git a/microservices/vote-service/src/test/java/io/javatab/microservices/core/vote/PersistenceTest.java b/microservices/vote-service/src/test/java/io/javatab/microservices/core/vote/PersistenceTest.java new file mode 100644 index 0000000..2e2392b --- /dev/null +++ b/microservices/vote-service/src/test/java/io/javatab/microservices/core/vote/PersistenceTest.java @@ -0,0 +1,4 @@ +package io.javatab.microservices.core.vote; + +public class PersistenceTest { +} diff --git a/microservices/vote-service/src/test/java/io/javatab/microservices/core/vote/RedisTestBase.java b/microservices/vote-service/src/test/java/io/javatab/microservices/core/vote/RedisTestBase.java new file mode 100644 index 0000000..2ae7485 --- /dev/null +++ b/microservices/vote-service/src/test/java/io/javatab/microservices/core/vote/RedisTestBase.java @@ -0,0 +1,24 @@ +package io.javatab.microservices.core.vote; + +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.utility.DockerImageName; + +public abstract class RedisTestBase { + + private static GenericContainer redisContainer = new GenericContainer( + DockerImageName.parse("redis:6.2.6-alpine") + ).withExposedPorts(6379); + + static { + redisContainer.start(); + } + + @DynamicPropertySource + static void setProperties(DynamicPropertyRegistry registry) { + registry.add("redis.host", redisContainer::getContainerIpAddress); + registry.add("redis.port", () -> redisContainer.getMappedPort(6379)); + registry.add("redis.database", () -> "test"); + } +} diff --git a/microservices/vote-service/src/test/java/io/javatab/microservices/core/vote/VoteServiceApplicationTests.java b/microservices/vote-service/src/test/java/io/javatab/microservices/core/vote/VoteServiceApplicationTests.java new file mode 100644 index 0000000..dc76397 --- /dev/null +++ b/microservices/vote-service/src/test/java/io/javatab/microservices/core/vote/VoteServiceApplicationTests.java @@ -0,0 +1,14 @@ +package io.javatab.microservices.core.vote; + +import org.springframework.boot.test.context.SpringBootTest; + +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; + +@SpringBootTest(webEnvironment = RANDOM_PORT, properties = { + "eureka.client.enabled=false", + "spring.jpa.hibernate.ddl-auto=update", + "spring.cloud.config.enabled=false"}) +class VoteServiceApplicationTests extends RedisTestBase { + + +} diff --git a/microservices/vote-service/src/test/resources/application.yml b/microservices/vote-service/src/test/resources/application.yml new file mode 100644 index 0000000..e69de29 diff --git a/api-gateway-service/mvnw b/mvnw similarity index 94% rename from api-gateway-service/mvnw rename to mvnw index a16b543..8a8fb22 100755 --- a/api-gateway-service/mvnw +++ b/mvnw @@ -36,6 +36,10 @@ if [ -z "$MAVEN_SKIP_RC" ] ; then + if [ -f /usr/local/etc/mavenrc ] ; then + . /usr/local/etc/mavenrc + fi + if [ -f /etc/mavenrc ] ; then . /etc/mavenrc fi @@ -145,7 +149,7 @@ if [ -z "$JAVACMD" ] ; then JAVACMD="$JAVA_HOME/bin/java" fi else - JAVACMD="`which java`" + JAVACMD="`\\unset -f command; \\command -v java`" fi fi @@ -212,9 +216,9 @@ else echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." fi if [ -n "$MVNW_REPOURL" ]; then - jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" else - jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" fi while IFS="=" read key value; do case "$key" in (wrapperUrl) jarUrl="$value"; break ;; @@ -233,9 +237,9 @@ else echo "Found wget ... using wget" fi if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - wget "$jarUrl" -O "$wrapperJarPath" + wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" else - wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" fi elif command -v curl > /dev/null; then if [ "$MVNW_VERBOSE" = true ]; then @@ -305,6 +309,8 @@ WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain exec "$JAVACMD" \ $MAVEN_OPTS \ + $MAVEN_DEBUG_OPTS \ -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ - "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + "-Dmaven.home=${M2_HOME}" \ + "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/student-service/mvnw.cmd b/mvnw.cmd similarity index 84% rename from student-service/mvnw.cmd rename to mvnw.cmd index c8d4337..1d8ab01 100644 --- a/student-service/mvnw.cmd +++ b/mvnw.cmd @@ -46,8 +46,8 @@ if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") @REM Execute a user defined script before this one if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre @REM check for pre script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" -if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* +if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* :skipRcPre @setlocal @@ -120,9 +120,9 @@ SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain -set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" -FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B ) @@ -134,7 +134,7 @@ if exist %WRAPPER_JAR% ( ) ) else ( if not "%MVNW_REPOURL%" == "" ( - SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" ) if "%MVNW_VERBOSE%" == "true" ( echo Couldn't find %WRAPPER_JAR%, downloading it ... @@ -158,7 +158,13 @@ if exist %WRAPPER_JAR% ( @REM work with both Windows and non-Windows executions. set MAVEN_CMD_LINE_ARGS=%* -%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +%MAVEN_JAVA_EXE% ^ + %JVM_CONFIG_MAVEN_PROPS% ^ + %MAVEN_OPTS% ^ + %MAVEN_DEBUG_OPTS% ^ + -classpath %WRAPPER_JAR% ^ + "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ + %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* if ERRORLEVEL 1 goto error goto end @@ -168,15 +174,15 @@ set ERROR_CODE=1 :end @endlocal & set ERROR_CODE=%ERROR_CODE% -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost @REM check for post script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" -if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" +if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" :skipRcPost @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' -if "%MAVEN_BATCH_PAUSE%" == "on" pause +if "%MAVEN_BATCH_PAUSE%"=="on" pause -if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% +if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% -exit /B %ERROR_CODE% +cmd /C exit /B %ERROR_CODE% diff --git a/pom.xml b/pom.xml index 709a842..48c2a3f 100644 --- a/pom.xml +++ b/pom.xml @@ -4,27 +4,31 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.javatab - student-course-registration-system - 0.0.1-SNAPSHOT + io.javatab.microservices + student-course-system + 1.0.0 pom - student-course-registration-system - Parent Pom for the stduent course registration system project + student-course-system + Parent Pom for the student course registration system project org.springframework.boot spring-boot-starter-parent - 2.5.4 + 2.6.6 - discovery-service - config-server - course-service - api-gateway-service - auth-service - student-service - search-engine + api + util + microservices/course-composite-service + microservices/course-service + microservices/search-service + microservices/student-service + microservices/vote-service + spring-cloud/eureka-server + spring-cloud/gateway + spring-cloud/authorization-server + spring-cloud/config-server \ No newline at end of file diff --git a/run.sh b/run.sh new file mode 100644 index 0000000..e69de29 diff --git a/search-engine/Dockerfile b/search-engine/Dockerfile deleted file mode 100644 index 2669ada..0000000 --- a/search-engine/Dockerfile +++ /dev/null @@ -1,31 +0,0 @@ -#stage 1 -#Start with a base image containing Java runtime -FROM openjdk:11-slim as build - -# Add Maintainer Info -LABEL maintainer="Nasruddin " - -# The application's jar file -ARG JAR_FILE - -# Add the application's jar to the container -COPY ${JAR_FILE} app.jar - -#unpackage jar file -RUN mkdir -p target/dependency && (cd target/dependency; jar -xf /app.jar) - -#stage 2 -#Same Java runtime -FROM openjdk:11-slim - -#Add volume pointing to /tmp -VOLUME /tmp - -#Copy unpackaged application to new container -ARG DEPENDENCY=/target/dependency -COPY --from=build ${DEPENDENCY}/BOOT-INF/lib /app/lib -COPY --from=build ${DEPENDENCY}/META-INF /app/META-INF -COPY --from=build ${DEPENDENCY}/BOOT-INF/classes /app - -#execute the application -ENTRYPOINT ["java","-cp","app:app/lib/*","com.javatab.searchengine.SearchEngineApplication"] \ No newline at end of file diff --git a/search-engine/src/main/java/com/javatab/searchengine/StudentRepository.java b/search-engine/src/main/java/com/javatab/searchengine/StudentRepository.java deleted file mode 100644 index 68ee649..0000000 --- a/search-engine/src/main/java/com/javatab/searchengine/StudentRepository.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.javatab.searchengine; - -import com.javatab.searchengine.domain.Student; -import org.springframework.data.repository.reactive.ReactiveCrudRepository; -import org.springframework.stereotype.Repository; -import reactor.core.publisher.Flux; - -@Repository -public interface StudentRepository extends ReactiveCrudRepository { - Flux findStudentByUsername(String username); -} diff --git a/search-engine/src/main/java/com/javatab/searchengine/api/SearchApi.java b/search-engine/src/main/java/com/javatab/searchengine/api/SearchApi.java deleted file mode 100644 index 48cee72..0000000 --- a/search-engine/src/main/java/com/javatab/searchengine/api/SearchApi.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.javatab.searchengine.api; - -import com.javatab.searchengine.StudentRepository; -import com.javatab.searchengine.domain.Student; -import com.javatab.searchengine.service.StudentService; -import lombok.RequiredArgsConstructor; -import org.springframework.context.annotation.Bean; -import org.springframework.web.bind.annotation.*; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -import java.io.IOException; -import java.util.function.Supplier; - -@RestController -@RequestMapping("/search") -@RequiredArgsConstructor -public class SearchApi { - - private final StudentService studentService; - private final StudentRepository studentRepository; - - @PostMapping("/create-index") - public Mono createStudentIndex(@RequestBody Student student) throws IOException { - return studentRepository.save(student); - } - - @GetMapping("/id/{userid}") - public Mono getUserById(@PathVariable("userid") String id) throws IOException { - return studentRepository.findById(id); - } - - @GetMapping("/username/{username}") - public Flux getUserByUsername(@PathVariable("username") String username) throws IOException { - return studentRepository.findStudentByUsername(username); - } -} diff --git a/search-engine/src/main/java/com/javatab/searchengine/configuration/ElasticConfig.java b/search-engine/src/main/java/com/javatab/searchengine/configuration/ElasticConfig.java deleted file mode 100644 index 4ee8d1c..0000000 --- a/search-engine/src/main/java/com/javatab/searchengine/configuration/ElasticConfig.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.javatab.searchengine.configuration; - -import org.apache.http.HttpHost; -import org.elasticsearch.client.RestClient; -import org.elasticsearch.client.RestHighLevelClient; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -@Configuration -public class ElasticConfig { - - @Bean - public RestHighLevelClient client() { - return new RestHighLevelClient( - RestClient.builder( - new HttpHost("localhost", 9200, "http"))); - } -} diff --git a/search-engine/src/main/java/com/javatab/searchengine/configuration/MessageFunctionConfig.java b/search-engine/src/main/java/com/javatab/searchengine/configuration/MessageFunctionConfig.java deleted file mode 100644 index 659b3cf..0000000 --- a/search-engine/src/main/java/com/javatab/searchengine/configuration/MessageFunctionConfig.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.javatab.searchengine.configuration; - -import com.javatab.searchengine.domain.Student; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import java.util.function.Consumer; - -@Configuration -public class MessageFunctionConfig { - - @Bean - Consumer getNewlyCreatedStudent() { // change to event class instead of student - return student -> System.out.println("New created student " + student); - } -} \ No newline at end of file diff --git a/search-engine/src/main/java/com/javatab/searchengine/domain/Course.java b/search-engine/src/main/java/com/javatab/searchengine/domain/Course.java deleted file mode 100644 index 362e2e7..0000000 --- a/search-engine/src/main/java/com/javatab/searchengine/domain/Course.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.javatab.searchengine.domain; - -import lombok.Builder; -import lombok.Data; - -@Data -@Builder -public class Course { - - private String courseId; - private String courseName; - private String description; -} diff --git a/search-engine/src/main/java/com/javatab/searchengine/domain/Student.java b/search-engine/src/main/java/com/javatab/searchengine/domain/Student.java deleted file mode 100644 index 7bc967d..0000000 --- a/search-engine/src/main/java/com/javatab/searchengine/domain/Student.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.javatab.searchengine.domain; - -import lombok.Builder; -import lombok.Data; -import org.springframework.data.elasticsearch.annotations.Document; - -@Data -@Builder -@Document(indexName = "student") -public class Student { - - private String id; - private String username; - private String email; -} diff --git a/search-engine/src/main/java/com/javatab/searchengine/service/StudentService.java b/search-engine/src/main/java/com/javatab/searchengine/service/StudentService.java deleted file mode 100644 index 6dad630..0000000 --- a/search-engine/src/main/java/com/javatab/searchengine/service/StudentService.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.javatab.searchengine.service; - -import com.javatab.searchengine.domain.Student; -import lombok.RequiredArgsConstructor; -import org.elasticsearch.action.get.GetRequest; -import org.elasticsearch.action.get.GetResponse; -import org.elasticsearch.action.index.IndexRequest; -import org.elasticsearch.action.index.IndexResponse; -import org.elasticsearch.client.RequestOptions; -import org.elasticsearch.client.RestHighLevelClient; -import org.elasticsearch.common.collect.Map; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.elasticsearch.common.xcontent.XContentType; -import org.springframework.stereotype.Service; - -import java.io.IOException; -import java.util.UUID; - -@Service -@RequiredArgsConstructor -public class StudentService { - - private final RestHighLevelClient client; - private final ObjectMapper mapper; - - public String createStudentDocument(Student student) throws IOException { - Student aStudent = Student.builder() - .id(UUID.randomUUID().toString()) - .username(student.getUsername()) - .email(student.getEmail()).build(); - - Map documentMapper = mapper.convertValue(student, Map.class); - - IndexRequest indexRequest = new IndexRequest("student-document").id(student.getId()) - .source(documentMapper, XContentType.JSON); - - IndexResponse indexResponse = client.index(indexRequest, RequestOptions.DEFAULT); - - return indexResponse - .getResult() - .name(); - } - - public Student findById(String id) throws IOException { - GetRequest getRequest = new GetRequest("student-document", id); - - GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT); - return mapper - .convertValue(getResponse.getSource(), Student.class); - } - - public Student findByUsername(String username) throws IOException { - GetRequest getRequest = new GetRequest("student-document", username); - - GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT); - return mapper - .convertValue(getResponse.getSource(), Student.class); - } -} diff --git a/spring-cloud/authorization-server/Dockerfile b/spring-cloud/authorization-server/Dockerfile new file mode 100644 index 0000000..f73027b --- /dev/null +++ b/spring-cloud/authorization-server/Dockerfile @@ -0,0 +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 +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 +WORKDIR application +# We install install curl for health check +RUN apk --no-cache add curl +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 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 new file mode 100644 index 0000000..1102e05 --- /dev/null +++ b/spring-cloud/authorization-server/src/main/java/io/javatab/springcloud/auth/configuration/AuthorizationServerConfig.java @@ -0,0 +1,80 @@ +package io.javatab.springcloud.auth.configuration; + +import com.nimbusds.jose.jwk.JWKSet; +import com.nimbusds.jose.jwk.RSAKey; +import com.nimbusds.jose.jwk.source.JWKSource; +import com.nimbusds.jose.proc.SecurityContext; +import io.javatab.springcloud.auth.jose.Jwks; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.security.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration; +import org.springframework.security.oauth2.core.AuthorizationGrantType; +import org.springframework.security.oauth2.core.ClientAuthenticationMethod; +import org.springframework.security.oauth2.core.oidc.OidcScopes; +import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository; +import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; +import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository; +import org.springframework.security.oauth2.server.authorization.config.ProviderSettings; + +import java.time.Duration; +import java.util.UUID; + +@Configuration(proxyBeanMethods = false) +@Import(OAuth2AuthorizationServerConfiguration.class) +public class AuthorizationServerConfig { + + private static final Logger LOG = LoggerFactory.getLogger(AuthorizationServerConfig.class); + + // @formatter:off + @Bean + public RegisteredClientRepository registeredClientRepository() { + + LOG.info("register OAUth client allowing all grant flows..."); + RegisteredClient writerClient = RegisteredClient.withId(UUID.randomUUID().toString()) + .clientId("writer") + .clientSecret("secret") + .clientAuthenticationMethod(ClientAuthenticationMethod.BASIC) + .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) + .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN) + .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS) + .redirectUri("https://my.redirect.uri") + .redirectUri("https://localhost:8443/webjars/swagger-ui/oauth2-redirect.html") + .scope(OidcScopes.OPENID) + .scope("product:read") + .scope("product:write") + .clientSettings(clientSettings -> clientSettings.requireUserConsent(true)) + .tokenSettings(ts -> ts.accessTokenTimeToLive(Duration.ofHours(1))) + .build(); + + RegisteredClient readerClient = RegisteredClient.withId(UUID.randomUUID().toString()) + .clientId("reader") + .clientSecret("secret") + .clientAuthenticationMethod(ClientAuthenticationMethod.BASIC) + .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) + .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN) + .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS) + .redirectUri("https://my.redirect.uri") + .redirectUri("https://localhost:8443/webjars/swagger-ui/oauth2-redirect.html") + .scope(OidcScopes.OPENID) + .scope("product:read") + .clientSettings(clientSettings -> clientSettings.requireUserConsent(true)) + .tokenSettings(ts -> ts.accessTokenTimeToLive(Duration.ofHours(1))) + .build(); + return new InMemoryRegisteredClientRepository(writerClient, readerClient); + } + + @Bean + public JWKSource jwkSource() { + RSAKey rsaKey = Jwks.generateRsa(); + JWKSet jwkSet = new JWKSet(rsaKey); + return (jwkSelector, securityContext) -> jwkSelector.select(jwkSet); + } + + @Bean + public ProviderSettings providerSettings() { + return new ProviderSettings().issuer("http://auth-server:9999"); + } +} \ No newline at end of file diff --git a/spring-cloud/authorization-server/src/main/java/io/javatab/springcloud/auth/configuration/DefaultSecurityConfig.java b/spring-cloud/authorization-server/src/main/java/io/javatab/springcloud/auth/configuration/DefaultSecurityConfig.java new file mode 100644 index 0000000..f52fc19 --- /dev/null +++ b/spring-cloud/authorization-server/src/main/java/io/javatab/springcloud/auth/configuration/DefaultSecurityConfig.java @@ -0,0 +1,48 @@ +package io.javatab.springcloud.auth.configuration; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.oauth2.server.authorization.OAuth2AuthorizationServerConfigurer; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.provisioning.InMemoryUserDetailsManager; +import org.springframework.security.web.SecurityFilterChain; + +import static org.springframework.security.config.Customizer.withDefaults; + +@EnableWebSecurity +public class DefaultSecurityConfig { + + private static final Logger LOG = LoggerFactory.getLogger(DefaultSecurityConfig.class); + + // formatter:off + @Bean + SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception { + http + .authorizeRequests(authorizeRequests -> authorizeRequests + .antMatchers("/actuator/**").permitAll() + .anyRequest().authenticated() + ) + .formLogin(withDefaults()); + return http.build(); + } + // formatter:on + + // @formatter:off + @Bean + UserDetailsService users() { + UserDetails user = User.withDefaultPasswordEncoder() + .username("user") + .password("password") + .roles("USER") + .build(); + return new InMemoryUserDetailsManager(user); + } + // @formatter:on + +} +//CHECKSTYLE:ON \ No newline at end of file diff --git a/spring-cloud/authorization-server/src/main/java/io/javatab/springcloud/auth/jose/Jwks.java b/spring-cloud/authorization-server/src/main/java/io/javatab/springcloud/auth/jose/Jwks.java new file mode 100644 index 0000000..031e03c --- /dev/null +++ b/spring-cloud/authorization-server/src/main/java/io/javatab/springcloud/auth/jose/Jwks.java @@ -0,0 +1,75 @@ +//CHECKSTYLE:OFF +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.javatab.springcloud.auth.jose; + +import com.nimbusds.jose.jwk.Curve; +import com.nimbusds.jose.jwk.ECKey; +import com.nimbusds.jose.jwk.OctetSequenceKey; +import com.nimbusds.jose.jwk.RSAKey; + +import javax.crypto.SecretKey; +import java.security.KeyPair; +import java.security.interfaces.ECPrivateKey; +import java.security.interfaces.ECPublicKey; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.util.UUID; + +/** + * @author Joe Grandja + * @since 0.1.0 + */ +public final class Jwks { + + private Jwks() { + } + + public static RSAKey generateRsa() { + KeyPair keyPair = KeyGeneratorUtils.generateRsaKey(); + RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); + RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); + // @formatter:off + return new RSAKey.Builder(publicKey) + .privateKey(privateKey) + .keyID(UUID.randomUUID().toString()) + .build(); + // @formatter:on + } + + public static ECKey generateEc() { + KeyPair keyPair = KeyGeneratorUtils.generateEcKey(); + ECPublicKey publicKey = (ECPublicKey) keyPair.getPublic(); + ECPrivateKey privateKey = (ECPrivateKey) keyPair.getPrivate(); + Curve curve = Curve.forECParameterSpec(publicKey.getParams()); + // @formatter:off + return new ECKey.Builder(curve, publicKey) + .privateKey(privateKey) + .keyID(UUID.randomUUID().toString()) + .build(); + // @formatter:on + } + + public static OctetSequenceKey generateSecret() { + SecretKey secretKey = KeyGeneratorUtils.generateSecretKey(); + // @formatter:off + return new OctetSequenceKey.Builder(secretKey) + .keyID(UUID.randomUUID().toString()) + .build(); + // @formatter:on + } +} +//CHECKSTYLE:ON \ No newline at end of file diff --git a/spring-cloud/authorization-server/src/main/java/io/javatab/springcloud/auth/jose/KeyGeneratorUtils.java b/spring-cloud/authorization-server/src/main/java/io/javatab/springcloud/auth/jose/KeyGeneratorUtils.java new file mode 100644 index 0000000..787a302 --- /dev/null +++ b/spring-cloud/authorization-server/src/main/java/io/javatab/springcloud/auth/jose/KeyGeneratorUtils.java @@ -0,0 +1,85 @@ +//CHECKSTYLE:OFF +/* + * Copyright 2020-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.javatab.springcloud.auth.jose; + +import javax.crypto.KeyGenerator; +import javax.crypto.SecretKey; +import java.math.BigInteger; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.spec.ECFieldFp; +import java.security.spec.ECParameterSpec; +import java.security.spec.ECPoint; +import java.security.spec.EllipticCurve; + +/** + * @author Joe Grandja + * @since 0.1.0 + */ +final class KeyGeneratorUtils { + + private KeyGeneratorUtils() { + } + + static SecretKey generateSecretKey() { + SecretKey hmacKey; + try { + hmacKey = KeyGenerator.getInstance("HmacSha256").generateKey(); + } catch (Exception ex) { + throw new IllegalStateException(ex); + } + return hmacKey; + } + + static KeyPair generateRsaKey() { + KeyPair keyPair; + try { + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); + keyPairGenerator.initialize(2048); + keyPair = keyPairGenerator.generateKeyPair(); + } catch (Exception ex) { + throw new IllegalStateException(ex); + } + return keyPair; + } + + static KeyPair generateEcKey() { + EllipticCurve ellipticCurve = new EllipticCurve( + new ECFieldFp( + new BigInteger("115792089210356248762697446949407573530086143415290314195533631308867097853951")), + new BigInteger("115792089210356248762697446949407573530086143415290314195533631308867097853948"), + new BigInteger("41058363725152142129326129780047268409114441015993725554835256314039467401291")); + ECPoint ecPoint = new ECPoint( + new BigInteger("48439561293906451759052585252797914202762949526041747995844080717082404635286"), + new BigInteger("36134250956749795798585127919587881956611106672985015071877198253568414405109")); + ECParameterSpec ecParameterSpec = new ECParameterSpec( + ellipticCurve, + ecPoint, + new BigInteger("115792089210356248762697446949407573529996955224135760342422259061068512044369"), + 1); + + KeyPair keyPair; + try { + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC"); + keyPairGenerator.initialize(ecParameterSpec); + keyPair = keyPairGenerator.generateKeyPair(); + } catch (Exception ex) { + throw new IllegalStateException(ex); + } + return keyPair; + } +} \ No newline at end of file diff --git a/spring-cloud/authorization-server/src/main/resources/application.yml b/spring-cloud/authorization-server/src/main/resources/application.yml new file mode 100644 index 0000000..fc9942a --- /dev/null +++ b/spring-cloud/authorization-server/src/main/resources/application.yml @@ -0,0 +1,19 @@ +spring.config.import: "configserver:" + +spring: + application.name: auth-server + cloud.config: + failFast: true + retry: + initialInterval: 3000 + multiplier: 1.3 + maxInterval: 10000 + maxAttempts: 20 + uri: http://localhost:8888 + username: ${CONFIG_SERVER_USR} + password: ${CONFIG_SERVER_PWD} + +--- +spring.config.activate.on-profile: docker + +spring.cloud.config.uri: http://config-server:8888 \ No newline at end of file diff --git a/spring-cloud/config-server/Dockerfile b/spring-cloud/config-server/Dockerfile new file mode 100644 index 0000000..26387b7 --- /dev/null +++ b/spring-cloud/config-server/Dockerfile @@ -0,0 +1,20 @@ +# 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 +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 +WORKDIR application +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 diff --git a/spring-cloud/config-server/src/main/java/io/javatab/springcloud/configserver/SecurityConfig.java b/spring-cloud/config-server/src/main/java/io/javatab/springcloud/configserver/SecurityConfig.java new file mode 100644 index 0000000..101eb79 --- /dev/null +++ b/spring-cloud/config-server/src/main/java/io/javatab/springcloud/configserver/SecurityConfig.java @@ -0,0 +1,23 @@ +package io.javatab.springcloud.configserver; + +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + +@Configuration +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + // Disable CRCF to allow POST to /encrypt and /decrypt endpoins + .csrf() + .disable() + .authorizeRequests() + .anyRequest().authenticated() + .and() + .httpBasic(); + } +} + + diff --git a/spring-cloud/eureka-server/Dockerfile b/spring-cloud/eureka-server/Dockerfile new file mode 100644 index 0000000..4ddac48 --- /dev/null +++ b/spring-cloud/eureka-server/Dockerfile @@ -0,0 +1,20 @@ +# 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 +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 +WORKDIR application +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 diff --git a/spring-cloud/eureka-server/src/main/java/io/javatab/springcloud/eurekaserver/configuration/SecurityConfig.java b/spring-cloud/eureka-server/src/main/java/io/javatab/springcloud/eurekaserver/configuration/SecurityConfig.java new file mode 100644 index 0000000..ab4ab27 --- /dev/null +++ b/spring-cloud/eureka-server/src/main/java/io/javatab/springcloud/eurekaserver/configuration/SecurityConfig.java @@ -0,0 +1,39 @@ +package io.javatab.springcloud.eurekaserver.configuration; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.crypto.password.NoOpPasswordEncoder; + +@Configuration +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Value("${app.eureka-username}") + private String username; + + @Value("${app.eureka-password}") + private String password; + + @Override + public void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.inMemoryAuthentication() + .passwordEncoder(NoOpPasswordEncoder.getInstance()) + .withUser(username).password(password) + .authorities("USER"); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + // Disable CSRF to allow services to register themselves with Eureka + .csrf() + .disable() + .authorizeRequests() + .anyRequest().authenticated() + .and() + .httpBasic(); + } +} diff --git a/spring-cloud/eureka-server/src/main/resources/application.yml b/spring-cloud/eureka-server/src/main/resources/application.yml new file mode 100644 index 0000000..9654833 --- /dev/null +++ b/spring-cloud/eureka-server/src/main/resources/application.yml @@ -0,0 +1,22 @@ +spring.config.import: "configserver:" + +spring: + application.name: eureka-server + cloud.config: + failFast: true + retry: + initialInterval: 3000 + multiplier: 1.3 + maxInterval: 10000 + maxAttempts: 20 + uri: http://localhost:8888 + username: ${CONFIG_SERVER_USR} + password: ${CONFIG_SERVER_PWD} + +logging: + level: + root: DEBUG +--- +spring.config.activate.on-profile: docker + +spring.cloud.config.uri: http://config-server:8888 \ No newline at end of file diff --git a/spring-cloud/eureka-server/src/test/resources/application.yml b/spring-cloud/eureka-server/src/test/resources/application.yml new file mode 100644 index 0000000..31628c0 --- /dev/null +++ b/spring-cloud/eureka-server/src/test/resources/application.yml @@ -0,0 +1,19 @@ +spring.config.import: "configserver:" + +spring: + application.name: eureka-server + cloud.config: + failFast: true + retry: + initialInterval: 3000 + multiplier: 1.3 + maxInterval: 10000 + maxAttempts: 20 + uri: http://localhost:8888 + username: ${CONFIG_SERVER_USR} + password: ${CONFIG_SERVER_PWD} + +--- +spring.config.activate.on-profile: docker + +spring.cloud.config.uri: http://config-server:8888 \ No newline at end of file diff --git a/spring-cloud/gateway/Dockerfile b/spring-cloud/gateway/Dockerfile new file mode 100644 index 0000000..d06ca3c --- /dev/null +++ b/spring-cloud/gateway/Dockerfile @@ -0,0 +1,20 @@ +# 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 +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 +WORKDIR application +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 diff --git a/spring-cloud/gateway/src/main/java/io/javatab/springcloud/gateway/configuration/HealthCheckConfiguration.java b/spring-cloud/gateway/src/main/java/io/javatab/springcloud/gateway/configuration/HealthCheckConfiguration.java new file mode 100644 index 0000000..f71fcd2 --- /dev/null +++ b/spring-cloud/gateway/src/main/java/io/javatab/springcloud/gateway/configuration/HealthCheckConfiguration.java @@ -0,0 +1,54 @@ +package io.javatab.springcloud.gateway.configuration; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.actuate.health.CompositeReactiveHealthContributor; +import org.springframework.boot.actuate.health.Health; +import org.springframework.boot.actuate.health.ReactiveHealthContributor; +import org.springframework.boot.actuate.health.ReactiveHealthIndicator; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.reactive.function.client.WebClient; +import reactor.core.publisher.Mono; + +import java.util.LinkedHashMap; +import java.util.Map; + +import static java.util.logging.Level.FINE; + +@Configuration +public class HealthCheckConfiguration { + + private static final Logger LOG = LoggerFactory.getLogger(HealthCheckConfiguration.class); + + private final WebClient webClient; + + @Autowired + public HealthCheckConfiguration(WebClient.Builder webClientBuilder) { + this.webClient = webClientBuilder.build(); + } + + @Bean + ReactiveHealthContributor healthCheckMicroservices() { + + final Map registry = new LinkedHashMap<>(); + + registry.put("course", () -> getHealth("http://course")); + registry.put("student", () -> getHealth("http://student")); + registry.put("vote", () -> getHealth("http://vote")); + registry.put("search", () -> getHealth("http://search")); + registry.put("course-composite", () -> getHealth("http://course-composite")); + + return CompositeReactiveHealthContributor.fromMap(registry); + } + + private Mono getHealth(String baseUrl) { + String url = baseUrl + "/actuator/health"; + LOG.debug("Setting up a call to the Health API on URL: {}", url); + return webClient.get().uri(url).retrieve().bodyToMono(String.class) + .map(s -> new Health.Builder().up().build()) + .onErrorResume(ex -> Mono.just(new Health.Builder().down(ex).build())) + .log(LOG.getName(), FINE); + } +} \ No newline at end of file diff --git a/spring-cloud/gateway/src/main/java/io/javatab/springcloud/gateway/configuration/SecurityConfig.java b/spring-cloud/gateway/src/main/java/io/javatab/springcloud/gateway/configuration/SecurityConfig.java new file mode 100644 index 0000000..c257b6a --- /dev/null +++ b/spring-cloud/gateway/src/main/java/io/javatab/springcloud/gateway/configuration/SecurityConfig.java @@ -0,0 +1,35 @@ +package io.javatab.springcloud.gateway.configuration; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; +import org.springframework.security.config.web.server.ServerHttpSecurity; +import org.springframework.security.web.server.SecurityWebFilterChain; + +@EnableWebFluxSecurity +public class SecurityConfig { + + private static final Logger LOG = LoggerFactory.getLogger(SecurityConfig.class); + + @Bean + SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) throws Exception { + http + .csrf().disable() + .authorizeExchange() + .pathMatchers("/config/**").permitAll() + .pathMatchers("/actuator/**").permitAll() + .pathMatchers("/eureka/**").permitAll() + .pathMatchers("/oauth2/**").permitAll() + .pathMatchers("/login/**").permitAll() + .pathMatchers("/error/**").permitAll() + .pathMatchers("/openapi/**").permitAll() + .pathMatchers("/webjars/**").permitAll() + .anyExchange().authenticated() + .and() + .oauth2ResourceServer() + .jwt(); + return http.build(); + } + +} \ No newline at end of file diff --git a/spring-cloud/gateway/src/main/resources/application.yml b/spring-cloud/gateway/src/main/resources/application.yml new file mode 100644 index 0000000..8b07630 --- /dev/null +++ b/spring-cloud/gateway/src/main/resources/application.yml @@ -0,0 +1,19 @@ +spring.config.import: "configserver:" + +spring: + application.name: gateway + cloud.config: + failFast: true + retry: + initialInterval: 3000 + multiplier: 1.3 + maxInterval: 10000 + maxAttempts: 20 + uri: http://localhost:8888 + username: ${CONFIG_SERVER_USR} + password: ${CONFIG_SERVER_PWD} + +--- +spring.config.activate.on-profile: docker + +spring.cloud.config.uri: http://config-server:8888 \ No newline at end of file diff --git a/spring-cloud/gateway/src/test/resources/application.yml b/spring-cloud/gateway/src/test/resources/application.yml new file mode 100644 index 0000000..6a97b7f --- /dev/null +++ b/spring-cloud/gateway/src/test/resources/application.yml @@ -0,0 +1 @@ +spring.security.oauth2.resourceserver.jwt.jwk-set-uri: . \ No newline at end of file diff --git a/student-course-registration-system.iml b/student-course-registration-system.iml new file mode 100644 index 0000000..1daccae --- /dev/null +++ b/student-course-registration-system.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/student-service/.mvn/wrapper/MavenWrapperDownloader.java b/student-service/.mvn/wrapper/MavenWrapperDownloader.java deleted file mode 100644 index e76d1f3..0000000 --- a/student-service/.mvn/wrapper/MavenWrapperDownloader.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2007-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import java.net.*; -import java.io.*; -import java.nio.channels.*; -import java.util.Properties; - -public class MavenWrapperDownloader { - - private static final String WRAPPER_VERSION = "0.5.6"; - /** - * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. - */ - private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" - + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; - - /** - * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to - * use instead of the default one. - */ - private static final String MAVEN_WRAPPER_PROPERTIES_PATH = - ".mvn/wrapper/maven-wrapper.properties"; - - /** - * Path where the maven-wrapper.jar will be saved to. - */ - private static final String MAVEN_WRAPPER_JAR_PATH = - ".mvn/wrapper/maven-wrapper.jar"; - - /** - * Name of the property which should be used to override the default download url for the wrapper. - */ - private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; - - public static void main(String args[]) { - System.out.println("- Downloader started"); - File baseDirectory = new File(args[0]); - System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); - - // If the maven-wrapper.properties exists, read it and check if it contains a custom - // wrapperUrl parameter. - File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); - String url = DEFAULT_DOWNLOAD_URL; - if(mavenWrapperPropertyFile.exists()) { - FileInputStream mavenWrapperPropertyFileInputStream = null; - try { - mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); - Properties mavenWrapperProperties = new Properties(); - mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); - url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); - } catch (IOException e) { - System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); - } finally { - try { - if(mavenWrapperPropertyFileInputStream != null) { - mavenWrapperPropertyFileInputStream.close(); - } - } catch (IOException e) { - // Ignore ... - } - } - } - System.out.println("- Downloading from: " + url); - - File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); - if(!outputFile.getParentFile().exists()) { - if(!outputFile.getParentFile().mkdirs()) { - System.out.println( - "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); - } - } - System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); - try { - downloadFileFromURL(url, outputFile); - System.out.println("Done"); - System.exit(0); - } catch (Throwable e) { - System.out.println("- Error downloading"); - e.printStackTrace(); - System.exit(1); - } - } - - private static void downloadFileFromURL(String urlString, File destination) throws Exception { - if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { - String username = System.getenv("MVNW_USERNAME"); - char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); - Authenticator.setDefault(new Authenticator() { - @Override - protected PasswordAuthentication getPasswordAuthentication() { - return new PasswordAuthentication(username, password); - } - }); - } - URL website = new URL(urlString); - ReadableByteChannel rbc; - rbc = Channels.newChannel(website.openStream()); - FileOutputStream fos = new FileOutputStream(destination); - fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); - fos.close(); - rbc.close(); - } - -} diff --git a/student-service/.mvn/wrapper/maven-wrapper.jar b/student-service/.mvn/wrapper/maven-wrapper.jar deleted file mode 100644 index 2cc7d4a..0000000 Binary files a/student-service/.mvn/wrapper/maven-wrapper.jar and /dev/null differ diff --git a/student-service/.mvn/wrapper/maven-wrapper.properties b/student-service/.mvn/wrapper/maven-wrapper.properties deleted file mode 100644 index abd303b..0000000 --- a/student-service/.mvn/wrapper/maven-wrapper.properties +++ /dev/null @@ -1,2 +0,0 @@ -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.2/apache-maven-3.8.2-bin.zip -wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar diff --git a/student-service/Dockerfile b/student-service/Dockerfile deleted file mode 100644 index 9185d37..0000000 --- a/student-service/Dockerfile +++ /dev/null @@ -1,31 +0,0 @@ -#stage 1 -#Start with a base image containing Java runtime -FROM openjdk:11-slim as build - -# Add Maintainer Info -LABEL maintainer="Nasruddin " - -# The application's jar file -ARG JAR_FILE - -# Add the application's jar to the container -COPY ${JAR_FILE} app.jar - -#unpackage jar file -RUN mkdir -p target/dependency && (cd target/dependency; jar -xf /app.jar) - -#stage 2 -#Same Java runtime -FROM openjdk:11-slim - -#Add volume pointing to /tmp -VOLUME /tmp - -#Copy unpackaged application to new container -ARG DEPENDENCY=/target/dependency -COPY --from=build ${DEPENDENCY}/BOOT-INF/lib /app/lib -COPY --from=build ${DEPENDENCY}/META-INF /app/META-INF -COPY --from=build ${DEPENDENCY}/BOOT-INF/classes /app - -#execute the application -ENTRYPOINT ["java","-cp","app:app/lib/*","com.javatab.student.StudentServiceApplication"] \ No newline at end of file diff --git a/student-service/mvnw b/student-service/mvnw deleted file mode 100755 index a16b543..0000000 --- a/student-service/mvnw +++ /dev/null @@ -1,310 +0,0 @@ -#!/bin/sh -# ---------------------------------------------------------------------------- -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# ---------------------------------------------------------------------------- - -# ---------------------------------------------------------------------------- -# Maven Start Up Batch script -# -# Required ENV vars: -# ------------------ -# JAVA_HOME - location of a JDK home dir -# -# Optional ENV vars -# ----------------- -# M2_HOME - location of maven2's installed home dir -# MAVEN_OPTS - parameters passed to the Java VM when running Maven -# e.g. to debug Maven itself, use -# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -# MAVEN_SKIP_RC - flag to disable loading of mavenrc files -# ---------------------------------------------------------------------------- - -if [ -z "$MAVEN_SKIP_RC" ] ; then - - if [ -f /etc/mavenrc ] ; then - . /etc/mavenrc - fi - - if [ -f "$HOME/.mavenrc" ] ; then - . "$HOME/.mavenrc" - fi - -fi - -# OS specific support. $var _must_ be set to either true or false. -cygwin=false; -darwin=false; -mingw=false -case "`uname`" in - CYGWIN*) cygwin=true ;; - MINGW*) mingw=true;; - Darwin*) darwin=true - # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home - # See https://developer.apple.com/library/mac/qa/qa1170/_index.html - if [ -z "$JAVA_HOME" ]; then - if [ -x "/usr/libexec/java_home" ]; then - export JAVA_HOME="`/usr/libexec/java_home`" - else - export JAVA_HOME="/Library/Java/Home" - fi - fi - ;; -esac - -if [ -z "$JAVA_HOME" ] ; then - if [ -r /etc/gentoo-release ] ; then - JAVA_HOME=`java-config --jre-home` - fi -fi - -if [ -z "$M2_HOME" ] ; then - ## resolve links - $0 may be a link to maven's home - PRG="$0" - - # need this for relative symlinks - while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG="`dirname "$PRG"`/$link" - fi - done - - saveddir=`pwd` - - M2_HOME=`dirname "$PRG"`/.. - - # make it fully qualified - M2_HOME=`cd "$M2_HOME" && pwd` - - cd "$saveddir" - # echo Using m2 at $M2_HOME -fi - -# For Cygwin, ensure paths are in UNIX format before anything is touched -if $cygwin ; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --unix "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --unix "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --unix "$CLASSPATH"` -fi - -# For Mingw, ensure paths are in UNIX format before anything is touched -if $mingw ; then - [ -n "$M2_HOME" ] && - M2_HOME="`(cd "$M2_HOME"; pwd)`" - [ -n "$JAVA_HOME" ] && - JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" -fi - -if [ -z "$JAVA_HOME" ]; then - javaExecutable="`which javac`" - if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then - # readlink(1) is not available as standard on Solaris 10. - readLink=`which readlink` - if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then - if $darwin ; then - javaHome="`dirname \"$javaExecutable\"`" - javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" - else - javaExecutable="`readlink -f \"$javaExecutable\"`" - fi - javaHome="`dirname \"$javaExecutable\"`" - javaHome=`expr "$javaHome" : '\(.*\)/bin'` - JAVA_HOME="$javaHome" - export JAVA_HOME - fi - fi -fi - -if [ -z "$JAVACMD" ] ; then - if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - else - JAVACMD="`which java`" - fi -fi - -if [ ! -x "$JAVACMD" ] ; then - echo "Error: JAVA_HOME is not defined correctly." >&2 - echo " We cannot execute $JAVACMD" >&2 - exit 1 -fi - -if [ -z "$JAVA_HOME" ] ; then - echo "Warning: JAVA_HOME environment variable is not set." -fi - -CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher - -# traverses directory structure from process work directory to filesystem root -# first directory with .mvn subdirectory is considered project base directory -find_maven_basedir() { - - if [ -z "$1" ] - then - echo "Path not specified to find_maven_basedir" - return 1 - fi - - basedir="$1" - wdir="$1" - while [ "$wdir" != '/' ] ; do - if [ -d "$wdir"/.mvn ] ; then - basedir=$wdir - break - fi - # workaround for JBEAP-8937 (on Solaris 10/Sparc) - if [ -d "${wdir}" ]; then - wdir=`cd "$wdir/.."; pwd` - fi - # end of workaround - done - echo "${basedir}" -} - -# concatenates all lines of a file -concat_lines() { - if [ -f "$1" ]; then - echo "$(tr -s '\n' ' ' < "$1")" - fi -} - -BASE_DIR=`find_maven_basedir "$(pwd)"` -if [ -z "$BASE_DIR" ]; then - exit 1; -fi - -########################################################################################## -# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -# This allows using the maven wrapper in projects that prohibit checking in binary data. -########################################################################################## -if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found .mvn/wrapper/maven-wrapper.jar" - fi -else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." - fi - if [ -n "$MVNW_REPOURL" ]; then - jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - else - jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - fi - while IFS="=" read key value; do - case "$key" in (wrapperUrl) jarUrl="$value"; break ;; - esac - done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" - if [ "$MVNW_VERBOSE" = true ]; then - echo "Downloading from: $jarUrl" - fi - wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" - if $cygwin; then - wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` - fi - - if command -v wget > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found wget ... using wget" - fi - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - wget "$jarUrl" -O "$wrapperJarPath" - else - wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" - fi - elif command -v curl > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found curl ... using curl" - fi - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - curl -o "$wrapperJarPath" "$jarUrl" -f - else - curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f - fi - - else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Falling back to using Java to download" - fi - javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" - # For Cygwin, switch paths to Windows format before running javac - if $cygwin; then - javaClass=`cygpath --path --windows "$javaClass"` - fi - if [ -e "$javaClass" ]; then - if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Compiling MavenWrapperDownloader.java ..." - fi - # Compiling the Java class - ("$JAVA_HOME/bin/javac" "$javaClass") - fi - if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - # Running the downloader - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Running MavenWrapperDownloader.java ..." - fi - ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") - fi - fi - fi -fi -########################################################################################## -# End of extension -########################################################################################## - -export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} -if [ "$MVNW_VERBOSE" = true ]; then - echo $MAVEN_PROJECTBASEDIR -fi -MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" - -# For Cygwin, switch paths to Windows format before running java -if $cygwin; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --path --windows "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --windows "$CLASSPATH"` - [ -n "$MAVEN_PROJECTBASEDIR" ] && - MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` -fi - -# Provide a "standardized" way to retrieve the CLI args that will -# work with both Windows and non-Windows executions. -MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" -export MAVEN_CMD_LINE_ARGS - -WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -exec "$JAVACMD" \ - $MAVEN_OPTS \ - -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ - "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ - ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/student-service/src/main/java/com/javatab/student/Event.java b/student-service/src/main/java/com/javatab/student/Event.java deleted file mode 100644 index 1a269ce..0000000 --- a/student-service/src/main/java/com/javatab/student/Event.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.javatab.student; - -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.fasterxml.jackson.datatype.jsr310.ser.ZonedDateTimeSerializer; - -import java.time.ZonedDateTime; - -import static java.time.ZonedDateTime.now; - -public class Event { - - public enum Type { - CREATE, - DELETE - } - - private final Type eventType; - private final K key; - private final T data; - private final ZonedDateTime eventCreatedAt; - - public Event() { - this.eventType = null; - this.key = null; - this.data = null; - this.eventCreatedAt = null; - } - - public Event(Type eventType, K key, T data) { - this.eventType = eventType; - this.key = key; - this.data = data; - this.eventCreatedAt = now(); - } - - public Type getEventType() { - return eventType; - } - - public K getKey() { - return key; - } - - public T getData() { - return data; - } - - @JsonSerialize(using = ZonedDateTimeSerializer.class) - public ZonedDateTime getEventCreatedAt() { - return eventCreatedAt; - } -} diff --git a/student-service/src/main/java/com/javatab/student/MessageFunctionConfiguration.java b/student-service/src/main/java/com/javatab/student/MessageFunctionConfiguration.java deleted file mode 100644 index 31b50e7..0000000 --- a/student-service/src/main/java/com/javatab/student/MessageFunctionConfiguration.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.javatab.student; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.cloud.stream.function.StreamBridge; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import java.util.function.Consumer; - -@Configuration -public class MessageFunctionConfiguration { - - @Autowired - private StreamBridge streamBridge; - - static final String STUDENT_CREATED_OUTPUT = "studentCreatedOutput"; - - @Bean - Consumer getNewlyCreatedUser() { - return userEvent -> { - System.out.println("New created user " + userEvent); - Student student = Student.builder().username(userEvent.getUsername()).build(); - boolean isSent = streamBridge.send(STUDENT_CREATED_OUTPUT, student); - System.out.println("Is sent " + isSent); - }; - } -} diff --git a/student-service/src/main/java/com/javatab/student/Student.java b/student-service/src/main/java/com/javatab/student/Student.java deleted file mode 100644 index 8ba0050..0000000 --- a/student-service/src/main/java/com/javatab/student/Student.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.javatab.student; - -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.bson.types.ObjectId; -import org.springframework.data.mongodb.core.mapping.Document; - -@AllArgsConstructor -@NoArgsConstructor -@Builder -@Data -@Document(collection = "users") -public class Student { - @JsonSerialize(using = ToStringSerializer.class) - private ObjectId id; - private String username; - private String email; - private String password; -} diff --git a/student-service/src/main/java/com/javatab/student/StudentController.java b/student-service/src/main/java/com/javatab/student/StudentController.java deleted file mode 100644 index 3e3847e..0000000 --- a/student-service/src/main/java/com/javatab/student/StudentController.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.javatab.student; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.cloud.stream.function.StreamBridge; -import org.springframework.web.bind.annotation.*; - -@RestController -@RequestMapping(value = "/students") -public class StudentController { - - @Autowired - StudentRepository studentRepository; - - @PostMapping - public Student save(@RequestBody Student student) { - return studentRepository.save(student); - } - - @GetMapping("{username}") - public Student getUsername(@PathVariable("username") String username) { - return studentRepository.findByUsername(username).get(); - } -} diff --git a/student-service/src/main/java/com/javatab/student/StudentRepository.java b/student-service/src/main/java/com/javatab/student/StudentRepository.java deleted file mode 100644 index 47dece1..0000000 --- a/student-service/src/main/java/com/javatab/student/StudentRepository.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.javatab.student; - -import org.bson.types.ObjectId; -import org.springframework.data.mongodb.repository.MongoRepository; -import org.springframework.stereotype.Repository; - -import java.util.Optional; - -@Repository -public interface StudentRepository extends MongoRepository { - Optional findByUsername(String username); -} diff --git a/student-service/src/main/java/com/javatab/student/StudentServiceApplication.java b/student-service/src/main/java/com/javatab/student/StudentServiceApplication.java deleted file mode 100644 index 1d993d5..0000000 --- a/student-service/src/main/java/com/javatab/student/StudentServiceApplication.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.javatab.student; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.cloud.client.loadbalancer.LoadBalanced; -import org.springframework.context.annotation.Bean; -import org.springframework.web.client.RestTemplate; - -import java.util.function.Consumer; -import java.util.function.Function; - -@SpringBootApplication -public class StudentServiceApplication { - - public static void main(String[] args) { - SpringApplication.run(StudentServiceApplication.class, args); - } - - @Bean - @LoadBalanced - public RestTemplate restTemplate() { - return new RestTemplate(); - } - -} diff --git a/student-service/src/main/java/com/javatab/student/UserEvent.java b/student-service/src/main/java/com/javatab/student/UserEvent.java deleted file mode 100644 index bbddca7..0000000 --- a/student-service/src/main/java/com/javatab/student/UserEvent.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.javatab.student; - -import lombok.Builder; -import lombok.Data; - -@Data -@Builder -public class UserEvent { - private String username; - private String email; -} diff --git a/student-service/src/main/resources/application.yml b/student-service/src/main/resources/application.yml deleted file mode 100644 index 54bbe0b..0000000 --- a/student-service/src/main/resources/application.yml +++ /dev/null @@ -1,35 +0,0 @@ -spring: - application: - name: student-service - config: - import: optional:configserver:config-server - cloud: - config: - discovery: - enabled: true - service-id: config-server - - stream: - kafka: - binder: - brokers: kafka - #function: - # defination: getNewlyCreatedUser - bindings: - getNewlyCreatedUser-in-0: - destination: userCreatedOutput - #binder: kafka - group: mygroup - studentCreatedOutput-out-0: - destination: studentCreatedOutput - data: - mongodb: - host: localhost - port: 27017 - database: student_db - -eureka: - client: - service-url: - default-zone: http://discoveryservice:8761/eureka/ - diff --git a/util/.gitignore b/util/.gitignore new file mode 100644 index 0000000..549e00a --- /dev/null +++ b/util/.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/util/pom.xml b/util/pom.xml new file mode 100644 index 0000000..82b8cf4 --- /dev/null +++ b/util/pom.xml @@ -0,0 +1,55 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.6.6 + + + io.javatab.microservices.util + util + 1.0.0 + util + Demo project for Spring Boot + + 17 + + + + org.springframework.boot + spring-boot-starter-webflux + + + + org.springframework.boot + spring-boot-starter-test + test + + + io.projectreactor + reactor-test + test + + + io.javatab.microservices.api + api + 1.0.0 + compile + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + exec + + + + + + diff --git a/util/src/main/java/io/javatab/microservices/util/UtilApplication.java b/util/src/main/java/io/javatab/microservices/util/UtilApplication.java new file mode 100644 index 0000000..b34e1e2 --- /dev/null +++ b/util/src/main/java/io/javatab/microservices/util/UtilApplication.java @@ -0,0 +1,13 @@ +package io.javatab.microservices.util; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class UtilApplication { + + public static void main(String[] args) { + SpringApplication.run(UtilApplication.class, args); + } + +} diff --git a/util/src/main/java/io/javatab/microservices/util/http/GlobalControllerExceptionHandler.java b/util/src/main/java/io/javatab/microservices/util/http/GlobalControllerExceptionHandler.java new file mode 100644 index 0000000..5a2e274 --- /dev/null +++ b/util/src/main/java/io/javatab/microservices/util/http/GlobalControllerExceptionHandler.java @@ -0,0 +1,47 @@ +package io.javatab.microservices.util.http; + +import io.javatab.microservices.api.exceptions.InvalidInputException; +import io.javatab.microservices.api.exceptions.NotFoundException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +import static org.springframework.http.HttpStatus.NOT_FOUND; +import static org.springframework.http.HttpStatus.UNPROCESSABLE_ENTITY; + +@RestControllerAdvice +class GlobalControllerExceptionHandler { + + private static final Logger LOG = LoggerFactory.getLogger(GlobalControllerExceptionHandler.class); + + @ResponseStatus(NOT_FOUND) + @ExceptionHandler(NotFoundException.class) + public @ResponseBody HttpErrorInfo handleNotFoundExceptions( + ServerHttpRequest request, NotFoundException ex) { + + return createHttpErrorInfo(NOT_FOUND, request, ex); + } + + @ResponseStatus(UNPROCESSABLE_ENTITY) + @ExceptionHandler(InvalidInputException.class) + public @ResponseBody HttpErrorInfo handleInvalidInputException( + ServerHttpRequest request, InvalidInputException ex) { + + return createHttpErrorInfo(UNPROCESSABLE_ENTITY, request, ex); + } + + private HttpErrorInfo createHttpErrorInfo( + HttpStatus httpStatus, ServerHttpRequest request, Exception ex) { + + final String path = request.getPath().pathWithinApplication().value(); + final String message = ex.getMessage(); + + LOG.debug("Returning HTTP status: {} for path: {}, message: {}", httpStatus, path, message); + return new HttpErrorInfo(httpStatus, path, message); + } +} diff --git a/util/src/main/java/io/javatab/microservices/util/http/HttpErrorInfo.java b/util/src/main/java/io/javatab/microservices/util/http/HttpErrorInfo.java new file mode 100644 index 0000000..9720bc8 --- /dev/null +++ b/util/src/main/java/io/javatab/microservices/util/http/HttpErrorInfo.java @@ -0,0 +1,46 @@ +package io.javatab.microservices.util.http; + +import org.springframework.http.HttpStatus; + +import java.time.ZonedDateTime; + +public class HttpErrorInfo { + private final ZonedDateTime timestamp; + private final String path; + private final HttpStatus httpStatus; + private final String message; + + public HttpErrorInfo() { + timestamp = null; + this.httpStatus = null; + this.path = null; + this.message = null; + } + + public HttpErrorInfo(HttpStatus httpStatus, String path, String message) { + timestamp = ZonedDateTime.now(); + this.httpStatus = httpStatus; + this.path = path; + this.message = message; + } + + public ZonedDateTime getTimestamp() { + return timestamp; + } + + public String getPath() { + return path; + } + + public int getStatus() { + return httpStatus.value(); + } + + public String getError() { + return httpStatus.getReasonPhrase(); + } + + public String getMessage() { + return message; + } +} diff --git a/util/src/main/java/io/javatab/microservices/util/http/ServiceUtil.java b/util/src/main/java/io/javatab/microservices/util/http/ServiceUtil.java new file mode 100644 index 0000000..58bc640 --- /dev/null +++ b/util/src/main/java/io/javatab/microservices/util/http/ServiceUtil.java @@ -0,0 +1,48 @@ +package io.javatab.microservices.util.http; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import java.net.InetAddress; +import java.net.UnknownHostException; + +@Component +public class ServiceUtil { + private static final Logger LOG = LoggerFactory.getLogger(ServiceUtil.class); + + private final String port; + + private String serviceAddress = null; + + @Autowired + public ServiceUtil(@Value("${server.port}") String port) { + + this.port = port; + } + + public String getServiceAddress() { + if (serviceAddress == null) { + serviceAddress = findMyHostname() + "/" + findMyIpAddress() + ":" + port; + } + return serviceAddress; + } + + private String findMyHostname() { + try { + return InetAddress.getLocalHost().getHostName(); + } catch (UnknownHostException e) { + return "unknown host name"; + } + } + + private String findMyIpAddress() { + try { + return InetAddress.getLocalHost().getHostAddress(); + } catch (UnknownHostException e) { + return "unknown IP address"; + } + } +} diff --git a/util/src/main/resources/application.properties b/util/src/main/resources/application.properties new file mode 100644 index 0000000..cbe617e --- /dev/null +++ b/util/src/main/resources/application.properties @@ -0,0 +1 @@ +server.port=0 diff --git a/api-gateway-service/src/test/java/com/javatab/gatewayservice/ApiGatewayServiceApplicationTests.java b/util/src/test/java/io/javatab/microservices/util/UtilApplicationTests.java similarity index 52% rename from api-gateway-service/src/test/java/com/javatab/gatewayservice/ApiGatewayServiceApplicationTests.java rename to util/src/test/java/io/javatab/microservices/util/UtilApplicationTests.java index 644fd1a..dc083f1 100644 --- a/api-gateway-service/src/test/java/com/javatab/gatewayservice/ApiGatewayServiceApplicationTests.java +++ b/util/src/test/java/io/javatab/microservices/util/UtilApplicationTests.java @@ -1,13 +1,12 @@ -package com.javatab.gatewayservice; +package io.javatab.microservices.util; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest -class ApiGatewayServiceApplicationTests { +class UtilApplicationTests { - @Disabled + @Test void contextLoads() { }