diff --git a/MiniKms/logs/controller.log b/MiniKms/logs/controller.log new file mode 100644 index 0000000..c08ccfc --- /dev/null +++ b/MiniKms/logs/controller.log @@ -0,0 +1,22 @@ +2025-09-30 22:02:56 [http-nio-8080-exec-10] INFO f.s.m.l.RequestResponseLoggingFilter - [f3738aa7-dd26-4730-ae55-a03e82dc5cf9] REQUEST POST /api/v1/test/add | Body={ + "name":"testname" +} +2025-09-30 22:02:56 [http-nio-8080-exec-10] INFO f.s.m.l.RequestResponseLoggingFilter - [f3738aa7-dd26-4730-ae55-a03e82dc5cf9] RESPONSE POST /api/v1/test/add | Status=200 | Duration=196ms | Body={"id":1,"name":"testname"} +2025-09-30 22:04:21 [http-nio-8080-exec-5] INFO f.s.m.l.RequestResponseLoggingFilter - [1ae5c07a-e782-49cd-beee-beb87e96a6a2] REQUEST POST /api/v1/test/add | Body={ + "name":"testname" +} +2025-09-30 22:04:21 [http-nio-8080-exec-5] INFO f.s.m.l.RequestResponseLoggingFilter - [1ae5c07a-e782-49cd-beee-beb87e96a6a2] RESPONSE POST /api/v1/test/add | Status=200 | Duration=177ms | Body={"id":1,"name":"testname"} +2025-09-30 22:06:18 [http-nio-8080-exec-2] INFO f.s.m.l.RequestResponseLoggingFilter - [f90fb9c0-869b-4001-9054-5f3d7788c051] REQUEST POST /api/v1/test/add | Body={ + "name":"testname" +} +2025-09-30 22:06:18 [http-nio-8080-exec-2] INFO f.s.m.l.RequestResponseLoggingFilter - [f90fb9c0-869b-4001-9054-5f3d7788c051] RESPONSE POST /api/v1/test/add | Status=200 | Duration=191ms | Body={"id":1,"name":"testname"} +2025-09-30 22:08:15 [http-nio-8080-exec-1] INFO f.s.m.l.RequestResponseLoggingFilter - [717eb391-cb49-4bce-8232-7f3f6af1da74] REQUEST POST /api/v1/test/add | Body={ + "name":"testname" +} +2025-09-30 22:08:15 [http-nio-8080-exec-1] INFO f.s.m.l.RequestResponseLoggingFilter - [717eb391-cb49-4bce-8232-7f3f6af1da74] RESPONSE POST /api/v1/test/add | Status=200 | Duration=183ms | Body={"id":1,"name":"testname"} +2025-10-01 09:10:05 [https-jsse-nio-8443-exec-6] INFO f.s.m.l.RequestResponseLoggingFilter - [9ddbfebf-0170-4483-a22c-7cf2851c74fe] REQUEST POST /api/v1/test/add | Body={ + "name":"testname" +} +2025-10-01 09:10:05 [https-jsse-nio-8443-exec-6] INFO f.s.m.l.RequestResponseLoggingFilter - [9ddbfebf-0170-4483-a22c-7cf2851c74fe] RESPONSE POST /api/v1/test/add | Status=200 | Duration=388ms | Body={"id":1,"name":"testname"} +2025-10-01 09:10:10 [https-jsse-nio-8443-exec-7] INFO f.s.m.l.RequestResponseLoggingFilter - [a5ea9e10-5849-4b51-8f00-314520b739d8] REQUEST GET /api/v1/test/1 | Body= +2025-10-01 09:10:10 [https-jsse-nio-8443-exec-7] INFO f.s.m.l.RequestResponseLoggingFilter - [a5ea9e10-5849-4b51-8f00-314520b739d8] RESPONSE GET /api/v1/test/1 | Status=200 | Duration=79ms | Body={"id":1,"name":"testname"} diff --git a/MiniKms/logs/entity.log b/MiniKms/logs/entity.log new file mode 100644 index 0000000..ad0c060 --- /dev/null +++ b/MiniKms/logs/entity.log @@ -0,0 +1,4 @@ +2025-09-30 22:08:15 [http-nio-8080-exec-1] INFO f.s.minikms.logging.EntityLogger - Creating: TestEntity(id=null, name=testname) +2025-09-30 22:08:15 [http-nio-8080-exec-1] INFO f.s.minikms.logging.EntityLogger - Created: TestEntity(id=1, name=testname) +2025-10-01 09:10:05 [https-jsse-nio-8443-exec-6] INFO f.s.minikms.logging.EntityLogger - Creating: TestEntity(id=null, name=testname) +2025-10-01 09:10:05 [https-jsse-nio-8443-exec-6] INFO f.s.minikms.logging.EntityLogger - Created: TestEntity(id=1, name=testname) diff --git a/MiniKms/pom.xml b/MiniKms/pom.xml index 25837cc..8e75f7c 100644 --- a/MiniKms/pom.xml +++ b/MiniKms/pom.xml @@ -127,5 +127,4 @@ - diff --git a/MiniKms/src/main/java/ftn/security/minikms/config/SecurityConfig.java b/MiniKms/src/main/java/ftn/security/minikms/config/SecurityConfig.java index e2839bf..67fe541 100644 --- a/MiniKms/src/main/java/ftn/security/minikms/config/SecurityConfig.java +++ b/MiniKms/src/main/java/ftn/security/minikms/config/SecurityConfig.java @@ -53,6 +53,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { .authorizeHttpRequests(auth -> auth .requestMatchers(HttpMethod.OPTIONS, "/**").permitAll() .requestMatchers("/api/v1/auth/**").permitAll() + .requestMatchers("/api/v1/test/**").permitAll() .requestMatchers(HttpMethod.GET, "/api/v1/keys/**").authenticated() // Allow all roles to GET .requestMatchers("/api/v1/keys/**").hasRole("MANAGER") .anyRequest().authenticated() diff --git a/MiniKms/src/main/java/ftn/security/minikms/controller/TestController.java b/MiniKms/src/main/java/ftn/security/minikms/controller/TestController.java new file mode 100644 index 0000000..3fc1ac8 --- /dev/null +++ b/MiniKms/src/main/java/ftn/security/minikms/controller/TestController.java @@ -0,0 +1,31 @@ +package ftn.security.minikms.controller; + +import ftn.security.minikms.dto.TestDTO; +import ftn.security.minikms.entity.TestEntity; +import ftn.security.minikms.service.TestService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +@Slf4j +@RestController +@RequestMapping(value = "/api/v1/test") +public class TestController { + @Autowired + private TestService testService; + + @GetMapping("/{id}") + public TestEntity getTest(@PathVariable Long id) { + return testService.getById(id); + } + + @PostMapping("/add") + public TestEntity addTest(@RequestBody TestDTO testDTO){ + TestEntity entity = new TestEntity(); + entity.setName(testDTO.getName()); + + TestEntity savedEntity = testService.addTest(entity); + return ResponseEntity.ok(savedEntity).getBody(); + } +} diff --git a/MiniKms/src/main/java/ftn/security/minikms/dto/TestDTO.java b/MiniKms/src/main/java/ftn/security/minikms/dto/TestDTO.java new file mode 100644 index 0000000..ef9511f --- /dev/null +++ b/MiniKms/src/main/java/ftn/security/minikms/dto/TestDTO.java @@ -0,0 +1,8 @@ +package ftn.security.minikms.dto; + +import lombok.Data; + +@Data +public class TestDTO { + private String name; +} \ No newline at end of file diff --git a/MiniKms/src/main/java/ftn/security/minikms/entity/TestEntity.java b/MiniKms/src/main/java/ftn/security/minikms/entity/TestEntity.java new file mode 100644 index 0000000..818e855 --- /dev/null +++ b/MiniKms/src/main/java/ftn/security/minikms/entity/TestEntity.java @@ -0,0 +1,16 @@ +package ftn.security.minikms.entity; + +import ftn.security.minikms.logging.EntityLogger; +import jakarta.persistence.*; +import lombok.Data; + +@Entity +@Data +@EntityListeners(EntityLogger.class) +public class TestEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String name; +} diff --git a/MiniKms/src/main/java/ftn/security/minikms/logging/EntityLogger.java b/MiniKms/src/main/java/ftn/security/minikms/logging/EntityLogger.java new file mode 100644 index 0000000..fe8de94 --- /dev/null +++ b/MiniKms/src/main/java/ftn/security/minikms/logging/EntityLogger.java @@ -0,0 +1,38 @@ +package ftn.security.minikms.logging; + +import jakarta.persistence.*; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class EntityLogger { + + @PrePersist + public void prePersist(Object entity) { + log.info("Creating: {}", entity); + } + + @PostPersist + public void postPersist(Object entity) { + log.info("Created: {}", entity); + } + + @PreUpdate + public void preUpdate(Object entity) { + log.info("Updating: {}", entity); + } + + @PostUpdate + public void postUpdate(Object entity) { + log.info("Updated: {}", entity); + } + + @PreRemove + public void preRemove(Object entity) { + log.info("Deleting: {}", entity); + } + + @PostRemove + public void postRemove(Object entity) { + log.info("Deleted: {}", entity); + } +} diff --git a/MiniKms/src/main/java/ftn/security/minikms/logging/RequestResponseLoggingFilter.java b/MiniKms/src/main/java/ftn/security/minikms/logging/RequestResponseLoggingFilter.java new file mode 100644 index 0000000..8f75a82 --- /dev/null +++ b/MiniKms/src/main/java/ftn/security/minikms/logging/RequestResponseLoggingFilter.java @@ -0,0 +1,61 @@ +package ftn.security.minikms.logging; + +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; +import org.springframework.web.util.ContentCachingRequestWrapper; +import org.springframework.web.util.ContentCachingResponseWrapper; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.UUID; + +@Slf4j +@Component +public class RequestResponseLoggingFilter extends OncePerRequestFilter { + + @Override + protected void doFilterInternal(HttpServletRequest request, + HttpServletResponse response, + FilterChain filterChain) throws ServletException, IOException { + + ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper(request); + ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper(response); + + String requestId = request.getHeader("X-Request-ID"); + if (requestId == null || requestId.isBlank()) { + requestId = UUID.randomUUID().toString(); + } + + responseWrapper.setHeader("X-Request-ID", requestId); + + long start = System.currentTimeMillis(); + try { + filterChain.doFilter(requestWrapper, responseWrapper); + } finally { + long duration = System.currentTimeMillis() - start; + + String requestBody = new String(requestWrapper.getContentAsByteArray(), StandardCharsets.UTF_8); + log.info("[{}] REQUEST {} {} | Body={}", + requestId, + request.getMethod(), + request.getRequestURI(), + requestBody); + + String responseBody = new String(responseWrapper.getContentAsByteArray(), StandardCharsets.UTF_8); + log.info("[{}] RESPONSE {} {} | Status={} | Duration={}ms | Body={}", + requestId, + request.getMethod(), + request.getRequestURI(), + responseWrapper.getStatus(), + duration, + responseBody); + + responseWrapper.copyBodyToResponse(); + } + } +} diff --git a/MiniKms/src/main/java/ftn/security/minikms/repository/TestRepository.java b/MiniKms/src/main/java/ftn/security/minikms/repository/TestRepository.java new file mode 100644 index 0000000..cc1acd6 --- /dev/null +++ b/MiniKms/src/main/java/ftn/security/minikms/repository/TestRepository.java @@ -0,0 +1,9 @@ +package ftn.security.minikms.repository; + +import ftn.security.minikms.entity.TestEntity; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface TestRepository extends JpaRepository { +} diff --git a/MiniKms/src/main/java/ftn/security/minikms/service/TestService.java b/MiniKms/src/main/java/ftn/security/minikms/service/TestService.java new file mode 100644 index 0000000..992de83 --- /dev/null +++ b/MiniKms/src/main/java/ftn/security/minikms/service/TestService.java @@ -0,0 +1,20 @@ +package ftn.security.minikms.service; + +import ftn.security.minikms.entity.TestEntity; +import ftn.security.minikms.repository.TestRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class TestService { + @Autowired + TestRepository testRepository; + + public TestEntity getById(Long id){ + return testRepository.findById(id).get(); + } + + public TestEntity addTest(TestEntity testEntity){ + return testRepository.save(testEntity); + } +} diff --git a/MiniKms/src/main/resources/application.properties b/MiniKms/src/main/resources/application.properties index 1274bc2..5dbf986 100644 --- a/MiniKms/src/main/resources/application.properties +++ b/MiniKms/src/main/resources/application.properties @@ -1,5 +1,4 @@ spring.application.name=MiniKms - # Development values, won't be used in prod ROOT_KEY=onX6qBcMY+LtSTtDSWIS8xhnCkM8v/mozZhYL56dkf8= @@ -28,4 +27,4 @@ server.ssl.key-alias=minikms # 1 hour jwt.expiration=3600000 -jwt.secret=Dubt4z4Lba9fc82KES/2uRcxOR9LcTTwxh7UuxE4f9Q= +jwt.secret=Dubt4z4Lba9fc82KES/2uRcxOR9LcTTwxh7UuxE4f9Q= \ No newline at end of file diff --git a/MiniKms/src/main/resources/logback-spring.xml b/MiniKms/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..7fb8512 --- /dev/null +++ b/MiniKms/src/main/resources/logback-spring.xml @@ -0,0 +1,50 @@ + + + + + logs/controller.log + + logs/controller-%d{yyyy-MM-dd}.%i.log.gz + 10MB + 14 + 500MB + + + %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + logs/entity.log + + logs/entity-%d{yyyy-MM-dd}.%i.log.gz + 10MB + 14 + 500MB + + + %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n + + + + + + + +