diff --git a/application.properties b/application.properties index 88df955..076e6a1 100644 --- a/application.properties +++ b/application.properties @@ -1,8 +1,8 @@ # ======================================================================= # MS-Vanilla Service Properties # ======================================================================= -build.number=170 -build.date=Sat Dec 21 22:17:16 IST 2024 +build.number=173 +build.date=Sun Dec 22 02:25:58 IST 2024 # ------------------------------------------------------------------------ # Spring Profile # ------------------------------------------------------------------------ diff --git a/src/docker/application.properties b/src/docker/application.properties index 88df955..076e6a1 100644 --- a/src/docker/application.properties +++ b/src/docker/application.properties @@ -1,8 +1,8 @@ # ======================================================================= # MS-Vanilla Service Properties # ======================================================================= -build.number=170 -build.date=Sat Dec 21 22:17:16 IST 2024 +build.number=173 +build.date=Sun Dec 22 02:25:58 IST 2024 # ------------------------------------------------------------------------ # Spring Profile # ------------------------------------------------------------------------ diff --git a/src/main/java/io/fusion/air/microservice/adapters/security/jwt/ClaimsManager.java b/src/main/java/io/fusion/air/microservice/adapters/security/jwt/ClaimsManager.java index 3d14c27..c597992 100644 --- a/src/main/java/io/fusion/air/microservice/adapters/security/jwt/ClaimsManager.java +++ b/src/main/java/io/fusion/air/microservice/adapters/security/jwt/ClaimsManager.java @@ -128,6 +128,19 @@ public String getUserRole() { return (String) claims.get("rol"); } + /** + * Returns the Token Types + * 1. auth (For Auth Token) + * 2. refresh (For Refresh Token) + * 3. tx-users (For Tx Token) + * 4. tx-internal (For Internal Service Tokens) + * 5. tx-external (For External Service Tokens) + * @return + */ + public String getTokenType() { + return (String) claims.get("type"); + } + // ==================================================================================================== // Claims from KeyCloak Authentication // ==================================================================================================== diff --git a/src/main/java/io/fusion/air/microservice/adapters/security/jwt/UserTokenAuthorization.java b/src/main/java/io/fusion/air/microservice/adapters/security/jwt/UserTokenAuthorization.java index a188daa..7b80dc9 100644 --- a/src/main/java/io/fusion/air/microservice/adapters/security/jwt/UserTokenAuthorization.java +++ b/src/main/java/io/fusion/air/microservice/adapters/security/jwt/UserTokenAuthorization.java @@ -23,8 +23,6 @@ import io.fusion.air.microservice.security.jwt.core.TokenDataFactory; import static io.fusion.air.microservice.security.jwt.core.JsonWebTokenConstants.*; // JWT -import io.jsonwebtoken.Claims; -import io.jsonwebtoken.ExpiredJwtException; // Jakarta import jakarta.servlet.http.HttpServletRequest; // Aspect @@ -95,25 +93,23 @@ public Object validateRequest(boolean singleToken, String tokenMode, ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); - logTime(startTime, "Validating", request.getRequestURI(), joinPoint); - final String token = getToken(startTime, request.getHeader(AUTH_TOKEN), joinPoint); - TokenData tokenData = tokenFactory.createTokenData(token); + logTime(startTime, "Extracting & Validating Token", request.getRequestURI(), joinPoint); + // Create Token Data from the TokenDataFactory + final TokenData tokenData = tokenFactory.getTokenData( request.getHeader(AUTH_TOKEN), AUTH_TOKEN, joinPoint.toString()); + // Get the User (Subject) from the Token final String user = getUser(startTime, tokenData, joinPoint); - log.info("Step 0: User Extracted... {} ", user); - // Validate the Token when User is NOT Null - if (user != null) { - // Validate Token - UserDetails userDetails = validateToken(startTime, singleToken, user, tokenMode, tokenData, joinPoint, tokenCtg); - // Create Authorize Token - UsernamePasswordAuthenticationToken authorizeToken = new UsernamePasswordAuthenticationToken( - userDetails, null, userDetails.getAuthorities()); - authorizeToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); - // Set the Security Context with current user as Authorized for the request, - // So it passes the Spring Security Configurations successfully. - SecurityContextHolder.getContext().setAuthentication(authorizeToken); - logTime(startTime, SUCCESS, "User Authorized for the request", joinPoint); - } + log.info("Step 1: Validate Request: User Extracted... {} ", user); // If the User == NULL then ERROR is thrown from getUser() method itself + // Validate the Token when User is NOT Null + UserDetails userDetails = validateToken(startTime, user, tokenMode, tokenData, joinPoint, tokenCtg); + // Create Authorize Token + UsernamePasswordAuthenticationToken authorizeToken = new UsernamePasswordAuthenticationToken( + userDetails, null, userDetails.getAuthorities()); + authorizeToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); + // Set the Security Context with current user as Authorized for the request, + // So it passes the Spring Security Configurations successfully. + SecurityContextHolder.getContext().setAuthentication(authorizeToken); + logTime(startTime, SUCCESS, "User Authorized for the request", joinPoint); // Check the Tx Token if It's NOT a SINGLE_TOKEN Request if(!singleToken ) { validateAndSetClaimsFromTxToken(startTime, user, request.getHeader(TX_TOKEN), joinPoint); @@ -121,26 +117,6 @@ public Object validateRequest(boolean singleToken, String tokenMode, return joinPoint.proceed(); } - /** - * Extract the Token fromm the Authorization Header - * ------------------------------------------------------------------------------------------------------ - * Authorization: Bearer AAA.BBB.CCC - * ------------------------------------------------------------------------------------------------------ - * - * @param startTime - * @param jwToken - * @param joinPoint - * @return - */ - private String getToken(long startTime, String jwToken, ProceedingJoinPoint joinPoint) { - if (jwToken != null && jwToken.startsWith(BEARER)) { - return jwToken.substring(7); - } - String msg = "Access Denied: Unable to extract token from Header!"; - logTime(startTime, ERROR, msg, joinPoint); - throw new JWTTokenExtractionException(msg); - } - /** * Returns the user from the Token * @@ -157,18 +133,9 @@ private String getUser(long startTime, TokenData token, ProceedingJoinPoint join // Store the user info for logging MDC.put("user", user); return user; - } catch (IllegalArgumentException e) { - msg = "Access Denied: Unable to get Subject JWT Token Error: "+e.getMessage(); - throw new JWTTokenSubjectException(msg, e); - } catch (ExpiredJwtException e) { - msg = "Access Denied: JWT Token has expired Error: "+e.getMessage(); - throw new JWTTokenExpiredException(msg, e); - } catch (NullPointerException e) { - msg = "Access Denied: Invalid Token (Null Token) Error: "+e.getMessage(); - throw new JWTUnDefinedException(msg, e); } catch (Exception e) { - msg = "Access Denied: Error Extracting User: "+e.getMessage(); - throw new JWTUnDefinedException(msg, e); + msg = e.getMessage(); + throw e; } finally { if(msg != null) { logTime(startTime, ERROR, msg, joinPoint); @@ -182,31 +149,25 @@ private String getUser(long startTime, TokenData token, ProceedingJoinPoint join * - Expiry Time * * @param startTime - * @param singleToken * @param user * @param tokenMode - * @param token + * @param tokenData * @param joinPoint * @param tokenCtg * @return */ - private UserDetails validateToken(long startTime, boolean singleToken, String user, String tokenMode, - TokenData token, ProceedingJoinPoint joinPoint, int tokenCtg) { + private UserDetails validateToken(long startTime, String user, String tokenMode, + TokenData tokenData, ProceedingJoinPoint joinPoint, int tokenCtg) { UserDetails userDetails = userDetailsService.loadUserByUsername(user); String msg = null; try { - // Validate the Token - if (JsonWebTokenValidator.validateToken(userDetails.getUsername(), token)) { - String role = JsonWebTokenValidator.getUserRoleFromToken(token); - // Set the Claims ONLY If it's a Single Token - Claims claims = JsonWebTokenValidator.getAllClaims(token); - if(singleToken) { - claimsManager.setClaims(claims); - claimsManager.isClaimsInitialized(); - } + // Validate the Token with the User details and Token Expiry + if (JsonWebTokenValidator.validateToken(userDetails.getUsername(), tokenData)) { // Validate the Token Type - getTokenTypeFromClaims( startTime, user, tokenMode, claims, tokenCtg, joinPoint); + String tokenType = JsonWebTokenValidator.getTokenType(tokenData); + validateTokenType( startTime, user, tokenType, tokenMode, tokenCtg, joinPoint); // Verify that the user role name matches the role name defined by the protected resource + String role = JsonWebTokenValidator.getUserRoleFromToken(tokenData); verifyTheUserRole( role, tokenMode, joinPoint); return userDetails; } else { @@ -231,27 +192,21 @@ private UserDetails validateToken(long startTime, boolean singleToken, String us * * @param startTime * @param user - * @param claims * @param tokenCtg * @param joinPoint */ - private void getTokenTypeFromClaims(long startTime, String user, String tokenMode, Claims claims, + private void validateTokenType(long startTime, String user, String tokenType, String tokenMode, int tokenCtg, ProceedingJoinPoint joinPoint) { String msg = null; try { - if (claims == null) { - msg = "Invalid Token! No Claims available! " + user; - throw new AuthorizationException(msg); - } - String tokenType = getTokenTypeFromClaims( user, claims); switch(tokenCtg) { case CONSUMERS: if (tokenMode.equals(REFRESH_TOKEN_MODE) && !tokenType.equals(AUTH_REFRESH)) { - msg = "Invalid Refresh Token! " + user; + msg = "Invalid Refresh Token! (" + tokenType + ") " + user; throw new AuthorizationException(msg); } if ( !tokenType.equals(AUTH)) { - msg = "Invalid Auth Token! (" + tokenType + ") For " + user; + msg = "Invalid Auth Token! (" + tokenType + ") " + user; throw new AuthorizationException(msg); } break; @@ -321,37 +276,20 @@ private void verifyTheUserRole(String role, String tokenMode, ProceedingJoinPoin */ private void validateAndSetClaimsFromTxToken(long startTime, String user, String token, ProceedingJoinPoint joinPoint) { - TokenData tokenData; - if (token != null && token.startsWith("Bearer ")) { - String txToken = token.substring(7); - tokenData = tokenFactory.createTokenData(txToken); - } else { - String msg = "TX-Token: Access Denied: Unable to extract TX-Token from Header! "+user; - logTime(startTime, ERROR, msg, joinPoint); - throw new JWTTokenExtractionException(msg); - } + + final TokenData tokenData = tokenFactory.getTokenData(token, TX_TOKEN, joinPoint.toString()); String msg = null; try { - Claims claims = null; if (JsonWebTokenValidator.validateToken(user, tokenData)) { - claims = JsonWebTokenValidator.getAllClaims(tokenData); - String tokenType = getTokenTypeFromClaims( user, claims); - if (!tokenType.equals(TX_USERS)) { - msg = "Invalid TX Token Type ("+tokenType+") ! " + user; - throw new AuthorizationException(msg); - } - claimsManager.setClaims(claims); - claimsManager.isClaimsInitialized(); + String tokenType = validateClaimsTokenType( user); logTime(startTime, "SUCCESS", "TX-Token: User TX Authorized for the request", joinPoint); } else { msg = "TX-Token: Unauthorized Access: Token Validation Failed!"; throw new AuthorizationException(msg); } } catch(AuthorizationException e) { + msg = e.getMessage(); throw e; - } catch(Exception e) { - msg = "TX-Token: Unauthorized Access: Error: "+e.getMessage(); - throw new AuthorizationException(msg, e); } finally { // Error is Logged ONLY if msg != NULL if(msg != null) { @@ -363,20 +301,17 @@ private void validateAndSetClaimsFromTxToken(long startTime, String user, /** * Validates Token Type * @param user - * @param claims * @return */ - private String getTokenTypeFromClaims(String user, Claims claims) { - String tokenType; + private String validateClaimsTokenType(String user) { + String tokenType = claimsManager.getTokenType(); String msg; - try { - tokenType = (String) claims.get("type"); - } catch (Exception e) { - msg = "Unable to get Token Type from Claims for user: "+user; - throw new AuthorizationException(msg, e); - } if (tokenType == null) { - msg = "Invalid Token Type from Claims! for user: " + user; + msg = "Invalid Tx Token Type (NULL) from Claims! for user: " + user; + throw new AuthorizationException(msg); + } + if (!tokenType.equals(TX_USERS)) { + msg = "Invalid TX Token Type ("+tokenType+") ! " + user; throw new AuthorizationException(msg); } return tokenType; diff --git a/src/main/java/io/fusion/air/microservice/domain/models/order/CartItem.java b/src/main/java/io/fusion/air/microservice/domain/models/order/CartItem.java index 997ae63..013cf20 100644 --- a/src/main/java/io/fusion/air/microservice/domain/models/order/CartItem.java +++ b/src/main/java/io/fusion/air/microservice/domain/models/order/CartItem.java @@ -37,7 +37,7 @@ * * @author: Araf Karsh Hamid * @version: 0.1 - * @date: 2024-12-20T10:29 AM + * @date: 2024-12-20T10:29 AM */ public record CartItem( @NotBlank(message = "The Customer ID is required.") String customerId, diff --git a/src/main/java/io/fusion/air/microservice/security/jwt/client/JsonWebTokenValidator.java b/src/main/java/io/fusion/air/microservice/security/jwt/client/JsonWebTokenValidator.java index 53e3b38..2f4c138 100644 --- a/src/main/java/io/fusion/air/microservice/security/jwt/client/JsonWebTokenValidator.java +++ b/src/main/java/io/fusion/air/microservice/security/jwt/client/JsonWebTokenValidator.java @@ -16,9 +16,13 @@ package io.fusion.air.microservice.security.jwt.client; // JWT +import io.fusion.air.microservice.domain.exceptions.JWTTokenExpiredException; +import io.fusion.air.microservice.domain.exceptions.JWTTokenSubjectException; +import io.fusion.air.microservice.domain.exceptions.JWTUnDefinedException; import io.fusion.air.microservice.security.jwt.core.TokenData; import io.fusion.air.microservice.security.jwt.core.JsonWebTokenConstants; import io.jsonwebtoken.Claims; +import io.jsonwebtoken.ExpiredJwtException; import io.jsonwebtoken.Jws; import io.jsonwebtoken.Jwts; // Spring @@ -79,7 +83,17 @@ public static boolean isTokenExpired(TokenData token) { * @return */ public static String getSubjectFromToken(TokenData token) { - return getClaimFromToken(token, Claims::getSubject); + try { + return getClaimFromToken(token, Claims::getSubject); + } catch (IllegalArgumentException e) { + throw new JWTTokenSubjectException("Access Denied: Unable to get Subject JWT Token Error: "+e.getMessage(), e); + } catch (ExpiredJwtException e) { + throw new JWTTokenExpiredException("Access Denied: JWT Token has expired Error: "+e.getMessage(), e); + } catch (NullPointerException e) { + throw new JWTUnDefinedException("Access Denied: Invalid Token (Null Token) Error: "+e.getMessage(), e); + } catch (Exception e) { + throw new JWTUnDefinedException("Access Denied: Error Extracting User: "+e.getMessage(), e); + } } /** @@ -144,6 +158,16 @@ public static String getUserRoleFromToken(TokenData token) { return (role == null) ? "Public" : role; } + /** + * Return Token Type + * @param token + * @return + */ + public static String getTokenType(TokenData token) { + Claims claims = getAllClaims(token); + return (String) claims.get("type"); + } + /** * Get the Cloak User from the Token * @param token diff --git a/src/main/java/io/fusion/air/microservice/security/jwt/core/TokenDataFactory.java b/src/main/java/io/fusion/air/microservice/security/jwt/core/TokenDataFactory.java index 721d59c..946603a 100644 --- a/src/main/java/io/fusion/air/microservice/security/jwt/core/TokenDataFactory.java +++ b/src/main/java/io/fusion/air/microservice/security/jwt/core/TokenDataFactory.java @@ -14,9 +14,17 @@ * limitations under the License. */ package io.fusion.air.microservice.security.jwt.core; - +// Custom +import io.fusion.air.microservice.domain.exceptions.JWTTokenExtractionException; +import static io.fusion.air.microservice.security.jwt.core.JsonWebTokenConstants.*; +import static io.fusion.air.microservice.security.jwt.core.JsonWebTokenConstants.ERROR; +// Spring import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +// Log +import org.slf4j.Logger; +import static java.lang.invoke.MethodHandles.lookup; +import static org.slf4j.LoggerFactory.getLogger; /** * @author: Araf Karsh Hamid @@ -26,8 +34,8 @@ @Component public class TokenDataFactory { - public static final int LOCAL_KEY = 1; - public static final int KEYCLOAK_KEY = 2; + // Set Logger -> Lookup will automatically determine the class name. + private static final Logger log = getLogger(lookup().lookupClass()); // Autowired using the Constructor private JsonWebTokenConfig jwtConfig; @@ -52,12 +60,34 @@ public TokenDataFactory(JsonWebTokenConfig jwtCfg, KeyCloakConfig kCloakCfg, keyManager = kManager; } + /** + * Extract the Token fromm the Authorization Header + * ------------------------------------------------------------------------------------------------------ + * Authorization: Bearer AAA.BBB.CCC + * ------------------------------------------------------------------------------------------------------ + * + * @param jwToken + * @param className + * @return + */ + public final TokenData getTokenData(String jwToken, String tokenType, String className) { + if (jwToken != null && jwToken.startsWith(BEARER)) { + String token = jwToken.substring(7); + if(token != null) { + return createTokenData(token); + } + } + String msg = "Access Denied: Unable to extract ["+tokenType+"] token from Header!"; + logTime( ERROR, msg, className); + throw new JWTTokenExtractionException(msg); + } + /** * Create Token Data with JWT and Validating Key * @param token * @return */ - public TokenData createTokenData(String token) { + public final TokenData createTokenData(String token) { if(keyCloakConfig.isKeyCloakEnabled()) { return createKeyCloakTokenData( token); } else { @@ -91,4 +121,14 @@ public boolean isKeyCloakEnabled() { return keyCloakConfig.isKeyCloakEnabled(); } + /** + * Log Time + * @param status + * @param msg + * @param className + */ + private void logTime(String status, String msg, String className) { + log.info("2|TDF|TIME=0 ms|STATUS={}|CLASS={}|Msg={}", status,className, msg); + } + } diff --git a/src/main/java/io/fusion/air/microservice/security/jwt/server/TokenManager.java b/src/main/java/io/fusion/air/microservice/security/jwt/server/TokenManager.java index 69b221d..319e808 100755 --- a/src/main/java/io/fusion/air/microservice/security/jwt/server/TokenManager.java +++ b/src/main/java/io/fusion/air/microservice/security/jwt/server/TokenManager.java @@ -260,8 +260,8 @@ public Map createAuthorizationToken(String subject, HttpHeaders * @param tokens */ private void setHeaders(HttpHeaders headers, Map tokens) { - String authToken = tokens.get("token"); - String refreshTkn = tokens.get(AUTH_REFRESH); + String authToken = tokens.get(AUTH_TOKEN); + String refreshTkn = tokens.get(REFRESH_TOKEN); setHeaders( headers, authToken, refreshTkn); } diff --git a/src/main/resources/app.props.build b/src/main/resources/app.props.build index b9ff98b..4abed47 100644 --- a/src/main/resources/app.props.build +++ b/src/main/resources/app.props.build @@ -1,5 +1,5 @@ # ======================================================================= # MS-Vanilla Service Properties # ======================================================================= -build.number=170 -build.date=Sat Dec 21 22:17:16 IST 2024 +build.number=173 +build.date=Sun Dec 22 02:25:58 IST 2024 diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 88df955..076e6a1 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,8 +1,8 @@ # ======================================================================= # MS-Vanilla Service Properties # ======================================================================= -build.number=170 -build.date=Sat Dec 21 22:17:16 IST 2024 +build.number=173 +build.date=Sun Dec 22 02:25:58 IST 2024 # ------------------------------------------------------------------------ # Spring Profile # ------------------------------------------------------------------------ diff --git a/src/main/resources/backup/application.properties.172 b/src/main/resources/backup/application.properties.172 new file mode 100644 index 0000000..c70fdc8 --- /dev/null +++ b/src/main/resources/backup/application.properties.172 @@ -0,0 +1,226 @@ +# ======================================================================= +# MS-Vanilla Service Properties +# ======================================================================= +build.number=173 +build.date=Sun Dec 22 02:18:27 IST 2024 +# ------------------------------------------------------------------------ +# Spring Profile +# ------------------------------------------------------------------------ +spring.profiles.default=dev +# ======================================================================= +# Service Name & API Details - Version, Path +# ======================================================================= +service.org=orgname +service.name=MS-Vanilla +service.api.name=ms-vanilla +service.api.prefix=api +service.api.version=v1 +service.api.error.prefix=13 +service.container=ms-vanilla-service +service.api.repository=https://github.com/arafkarsh/ms-springboot-334-vanilla +service.api.path=/${service.api.name}/${service.api.prefix}/${service.api.version} +service.url=http://www.arafkarsh.com/ +service.license=Apache 2 License +service.license.url=https://github.com/arafkarsh/ms-springboot-334-vanilla?tab=Apache-2.0-1-ov-file +# ======================================================================= +# Microservice Server Properties +# ======================================================================= +server.port=9334 +server.version=0.1.5 +server.restart=false +server.leak.test=3 +server.resources.url=${service.url}${service.api.path} +server.api.url.print=true +# ------------------------------------------------------------------------ +# Host SSL Details : +# Rename the file fusionAir.pkcs12 in resources folder and uncomment the +# following lines to enable SSL +# ------------------------------------------------------------------------ +#server.ssl.key-store=classpath:fusionAir.pkcs12 +#server.ssl.key-store-type=PKCS12 +#server.ssl.key-store-password=Fusion.2023 +#server.ssl.key-alias=fusionAir +# ------------------------------------------------------------------------ +# Security & JWT Token (Type 1 = secret key, 2 = public / private key) +# ------------------------------------------------------------------------ +server.crypto.public.key=publicKey.pem +server.crypto.private.key=privateKey.pem +server.token.issuer=${service.org} +# Type 1 = Secret, Type 2 = Public / Private Key +server.token.type=1 +server.token.test=true +# Token Expiry Times - Security Policy will reject High Expiry Time +server.token.auth.expiry=600000 +server.token.refresh.expiry=3600000 +server.token.key=<([1234567890SecretKey!!To??Encrypt##Data@12345%6790])> +server.secure.data.key=<([1234567890SecretKEY!!TO??Encrypt##DATA@12345%6790])> +# ------------------------------------------------------------------------ +# Keycloak Details for OAuth 2 Authentication +# ------------------------------------------------------------------------ +server.keycloak.url=http://localhost:8080/realms/Fusion-Air/protocol/openid-connect/token +server.keycloak.certs=http://localhost:8080/realms/Fusion-Air/protocol/openid-connect/certs +server.keycloak.clientId=fusion-air-user-service +server.keycloak.secret=2AGe7XxP8evCmhdjD3cmgpE23y0g6PGU +server.keycloak.grantType=password +server.keycloak.publicKey=publicKey.KeyCloak.pem +server.keycloak.issuer=http://localhost:8080/realms/Fusion-Air +server.keycloak.enabled=false +# ------------------------------------------------------------------------ +# Host Details +# ------------------------------------------------------------------------ +server.host=localhost +server.host.dev=http://localhost:${server.port} +server.host.dev.desc=Development Server +server.host.uat=https://uat.${service.org}.com +server.host.uat.desc=UAT Server +server.host.prod=https://prod.${service.org}.com +server.host.prod.desc=Production Server +server.error.whitelabel.enabled=true +server.vulnerability.demos.allowed=false +# Service Properties Details +# ------------------------------------------------------------------------ +spring.codec.max-in-memory-size=3MB +app.property.product=fusion.air.product +app.property.product.list=/create, /status, /all/secured, /search/product, /search/price, /search/active, /deactivate, /activate, /update, /update/price, /update/details, /delete +app.property.list=element1, element2, element3 +app.property.map={key1:'val1', key2 : 'val2', key3 : 'val3'} +# ------------------------------------------------------------------------ +# Logging / Events: LogBack Setup / File Roll Over, +# ------------------------------------------------------------------------ +# Log Groups +logging.group.tomcat=org.apache.catalina, org.apache.coyote, org.apache.tomcat +# Logging Levels for various components +logging.level.org.springframework.boot.web.servlet=INFO +logging.level.org.springframework.web.servlet.DispatcherServlet=INFO +logging.level.org.springframework.security.web.FilterChainProxy=INFO +# Spring Default Groups +logging.level.web=INFO +logging.level.sql=INFO +logging.level.tomcat=INFO +# Root level logging +logging.level.root=INFO +# Specify the logback configuration file +logging.config=classpath:logback-spring.xml +# Supported Log Format plain / json +logging.format=plain +# Log file paths and rolling policy +logging.path=/tmp/logs/${service.api.name} +# Log File Name. File Extension .log or .json is added dynamically based on logging format. +logging.file.name=${service.api.name}.v${server.version} +# Log File Pattern for Size and Time based File Roll Over Name +logging.pattern.rolling-file-name=${logging.path}/${logging.file.name}-%d{yyyy-MM-dd}-%i +# Max Single File Size = 30 MB +logging.file.max-size=10MB +# Retention and total size cap for logs +# Keep Log Files for 100 Days with Max Cap at 3 GB +logging.file.max-history=100 +logging.file.total-size-cap=3GB +# ------------------------------------------------------------------------ +# Metrics: Micrometer / Prometheus / Actuator / +# ------------------------------------------------------------------------ +# Enable exposure of specific actuator endpoints (health, metrics, prometheus) +management.endpoints.web.exposure.include=health,metrics,prometheus,info +# Enable Spring Boot Actuator Endpoints +management.endpoint.health.enabled=true +management.endpoint.metrics.enabled=true +management.endpoint.prometheus.enabled=true +# Enable Metrics +management.metrics.export.prometheus.enabled=true +management.metrics.enable.jvm=false +management.metrics.enable.jvm.gc=false +management.metrics.enable.datasource=false +# ------------------------------------------------------------------------ +# Tracing: Open Telemetry / Micrometer +# Micrometer only supports HTTP/Protobuf (http) for OTLP. grpc is not supported. +# ------------------------------------------------------------------------ +# Enable OpenTelemetry +management.tracing.enabled=false +# OpenTelemetry Tracing Configuration +management.otlp.metrics.export.enabled=false +management.otlp.metrics.export.url=http://localhost:4318/v1/metrics +# number of Meter to include in a single payload sent to the backend. The default is 10,000. +management.otlp.metrics.export.batchSize=15000 +management.otlp.metrics.export.timeout=5s +# Determines how the additive quantities are expressed, in relation to time. Values are cumulative or delta +management.otlp.metrics.export.aggregationTemporality=cumulative +# Additional headers to send with exported metrics +management.otlp.metrics.export.headers.Authorization=Bearer abc123 +# the interval at which metrics will be published. +management.otlp.metrics.export.step=10s +# Resource Attributes are used for all metrics published. +management.otlp.metrics.export.resourceAttributes.service.name=ms-vanilla-service +# ======================================================================= +# Text Encryption +# ======================================================================= +# Ensure this matches your environment variable +jasypt.encryptor.password=${JASYPT_ENCRYPTOR_PASSWORD} +# Match the algorithm +jasypt.encryptor.algorithm=PBEWithHmacSHA512AndAES_256 +jasypt.encryptor.iv-generator-classname=org.jasypt.iv.RandomIvGenerator +jasypt.encryptor.salt-generator-classname=org.jasypt.salt.RandomSaltGenerator +# ======================================================================= +# Database Properties +# ======================================================================= +db.server=mem +db.port=5432 +db.name=ms_cache +db.schema=ms_schema +db.vendor=H2 +# To Store the Data in File +#spring.datasource.url=jdbc:h2:file:/data/demo +spring.datasource.url=jdbc:h2:${db.server}:${db.name};DB_CLOSE_ON_EXIT=FALSE +spring.datasource.driverClassName=org.h2.Driver +spring.datasource.username=sa +spring.datasource.password=ENC(lA6JCEpK7+wuHDpB1A41DOUfn6L74DQxaazXLTjyQHY5/X6CONfUEyDt6erWifrN) +spring.jpa.database-platform=org.hibernate.dialect.H2Dialect +spring.datasource.hikari.connection-test-query=SELECT 1 +# ======================================================================= +# JPA / Hibernate Properties +# ------------------------------------------------------------------------ +spring.jpa.show-sql=true +spring.jpa.defer-datasource-initialization=true +#spring.sql.init.data-locations=data-trans.sql +# Hibernate ddl auto (create, create-drop, validate, update) +spring.jpa.hibernate.ddl-auto=create-drop +spring.jpa.properties.hibernate.format_sql=true +spring.jpa.properties.hibernate.validator.apply_to_ddl=false +#spring.jpa.properties.hibernate.check_nullability=true +# ======================================================================= +# External Remote Server Properties +# ======================================================================= +remote.host=127.0.0.1 +remote.port=8080 +remote.protocol=http +# ======================================================================= +# Open API Properties +# For More Info: https://springdoc.org/#Introduction +# springdoc.api-docs.path=/api-docs +# ======================================================================= +springdoc.api-docs.path=${service.api.path} +springdoc.swagger-ui.path=${service.api.path}/swagger-ui.html +springdoc.swagger-ui.tryItOutEnabled=true +springdoc.swagger-ui.filter=true +springdoc.swagger-ui.use-root-path=true +springdoc.swagger-ui.disable-swagger-default-url=true +server.forward-headers-strategy=framework +springdoc.cache.disabled=true +springdoc.writer-with-default-pretty-printer=true +#springdoc.swagger-ui.configUrl=${service.api.path}/swagger-config/swagger-config.json +# Disabling the api-docs endpoint +springdoc.api-docs.enabled=true +# Disabling the swagger-ui +#springdoc.swagger-ui.enabled=true +springdoc.swagger-ui.operationsSorter=method +#For sorting tags alphabetically +springdoc.swagger-ui.tagsSorter=alpha +springdoc.show-actuator=true +# Packages to include +# springdoc.packagesToScan=io.fusion.water, io.fusion.fire +# Paths to include +# springdoc.pathsToMatch=/v1, /api/health/** +# To expose the swagger-ui, on the management port +#springdoc.use-management-port=true +# This property enables the openapi and swaggerui endpoints to be exposed +# beneath the actuator base path. +# management.endpoints.web.exposure.include=openapi, swaggerui +# ======================================================================= \ No newline at end of file