From 88e8e972827daa6d3b8e7fe1330641e42e8e7a89 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EC=B2=9C=20=EC=A7=84=EA=B0=95?= <jjjjjk12@ajou.ac.kr>
Date: Sat, 29 Mar 2025 13:20:16 +0900
Subject: [PATCH] =?UTF-8?q?feat:=20=EB=AA=A9=EB=A1=9D=20=EC=A1=B0=ED=9A=8C?=
 =?UTF-8?q?=EC=97=90=20=EA=B2=80=EC=83=89=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94?=
 =?UTF-8?q?=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../forwarding/ForwardingController.java      |  5 ++--
 .../controller/routing/RoutingController.java |  5 ++--
 .../forwarding/ForwardingRepository.java      |  4 ++++
 .../repository/routing/RoutingRepository.java |  4 ++++
 .../service/forwarding/ForwardingService.java | 16 ++++++++++---
 .../itda/service/routing/RoutingService.java  | 23 ++++++++++++++++---
 6 files changed, 47 insertions(+), 10 deletions(-)

diff --git a/src/main/java/com/aolda/itda/controller/forwarding/ForwardingController.java b/src/main/java/com/aolda/itda/controller/forwarding/ForwardingController.java
index 36e6f9a..999707a 100644
--- a/src/main/java/com/aolda/itda/controller/forwarding/ForwardingController.java
+++ b/src/main/java/com/aolda/itda/controller/forwarding/ForwardingController.java
@@ -30,8 +30,9 @@ public class ForwardingController {
     }
 
     @GetMapping("/forwardings")
-    public ResponseEntity<Object> lists(@RequestParam String projectId) {
-        return ResponseEntity.ok(forwardingService.getForwardings(projectId));
+    public ResponseEntity<Object> lists(@RequestParam String projectId,
+                                        @RequestParam(required = false) String query) {
+        return ResponseEntity.ok(forwardingService.getForwardingsWithSearch(projectId, query));
     }
 
     @PatchMapping("/forwarding")
diff --git a/src/main/java/com/aolda/itda/controller/routing/RoutingController.java b/src/main/java/com/aolda/itda/controller/routing/RoutingController.java
index 4b9d551..c96e910 100644
--- a/src/main/java/com/aolda/itda/controller/routing/RoutingController.java
+++ b/src/main/java/com/aolda/itda/controller/routing/RoutingController.java
@@ -31,8 +31,9 @@ public class RoutingController {
     }
 
     @GetMapping("/routings")
-    public ResponseEntity<Object> lists(@RequestParam String projectId) {
-        return ResponseEntity.ok(routingService.getRoutings(projectId));
+    public ResponseEntity<Object> lists(@RequestParam String projectId,
+                                        @RequestParam(required = false) String query) {
+        return ResponseEntity.ok(routingService.getRoutingsWithSearch(projectId, query));
     }
 
     @PatchMapping("/routing")
diff --git a/src/main/java/com/aolda/itda/repository/forwarding/ForwardingRepository.java b/src/main/java/com/aolda/itda/repository/forwarding/ForwardingRepository.java
index c461762..9a330f0 100644
--- a/src/main/java/com/aolda/itda/repository/forwarding/ForwardingRepository.java
+++ b/src/main/java/com/aolda/itda/repository/forwarding/ForwardingRepository.java
@@ -2,6 +2,7 @@ package com.aolda.itda.repository.forwarding;
 
 import com.aolda.itda.entity.forwarding.Forwarding;
 import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
 
 import java.util.List;
 import java.util.Optional;
@@ -11,4 +12,7 @@ public interface ForwardingRepository extends JpaRepository<Forwarding, Long> {
     Optional<Forwarding> findByForwardingIdAndIsDeleted(Long forwardingId, Boolean isDeleted);
     Boolean existsByInstanceIpAndInstancePortAndIsDeleted(String instanceIp, String instancePort, Boolean isDeleted);
     Boolean existsByServerPortAndIsDeleted(String serverPort, Boolean isDeleted);
+
+    @Query("SELECT f FROM Forwarding f WHERE f.projectId = ?1 AND f.isDeleted = ?3 AND (f.instanceIp LIKE %?2% OR f.serverPort LIKE %?2% OR f.name LIKE %?2%)")
+    List<Forwarding> findWithSearch(String projectId, String query, Boolean isDeleted);
 }
diff --git a/src/main/java/com/aolda/itda/repository/routing/RoutingRepository.java b/src/main/java/com/aolda/itda/repository/routing/RoutingRepository.java
index 046296c..44b88ae 100644
--- a/src/main/java/com/aolda/itda/repository/routing/RoutingRepository.java
+++ b/src/main/java/com/aolda/itda/repository/routing/RoutingRepository.java
@@ -3,6 +3,7 @@ package com.aolda.itda.repository.routing;
 import com.aolda.itda.entity.forwarding.Forwarding;
 import com.aolda.itda.entity.routing.Routing;
 import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
 
 import java.util.List;
 import java.util.Optional;
@@ -11,4 +12,7 @@ public interface RoutingRepository extends JpaRepository<Routing, Long> {
     List<Routing> findByProjectIdAndIsDeleted(String projectId, Boolean isDeleted);
     Optional<Routing> findByRoutingIdAndIsDeleted(Long routingId, Boolean isDeleted);
     Boolean existsByDomainAndIsDeleted(String domain, Boolean isDeleted);
+
+    @Query("SELECT r FROM Routing r WHERE r.projectId = ?1 AND r.isDeleted = ?3 AND (r.domain LIKE %?2% OR r.instanceIp LIKE %?2% OR r.name LIKE %?2%)")
+    List<Routing> findWithSearch(String projectId, String query, Boolean isDeleted);
 }
diff --git a/src/main/java/com/aolda/itda/service/forwarding/ForwardingService.java b/src/main/java/com/aolda/itda/service/forwarding/ForwardingService.java
index cae38c3..e6fc9d4 100644
--- a/src/main/java/com/aolda/itda/service/forwarding/ForwardingService.java
+++ b/src/main/java/com/aolda/itda/service/forwarding/ForwardingService.java
@@ -27,6 +27,7 @@ import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.nio.file.StandardCopyOption;
 import java.util.List;
+import java.util.regex.Pattern;
 
 @Service
 @Transactional
@@ -52,11 +53,20 @@ public class ForwardingService {
         return forwarding.toForwardingDTO();
     }
 
-    /* 포트포워딩 목록 조회 */
-    public PageResp<ForwardingDTO> getForwardings(String projectId) {
+    /* 포트포워딩 목록 조회 + 검색 */
+    public PageResp<ForwardingDTO> getForwardingsWithSearch(String projectId, String query) {
+
+        /* 입력 검증 */
+        if (query == null || query.isBlank()) {
+            return PageResp.<ForwardingDTO>builder()
+                    .contents(forwardingRepository.findByProjectIdAndIsDeleted(projectId, false)
+                            .stream()
+                            .map(Forwarding::toForwardingDTO)
+                            .toList()).build();
+        }
 
         return PageResp.<ForwardingDTO>builder()
-                .contents(forwardingRepository.findByProjectIdAndIsDeleted(projectId, false)
+                .contents(forwardingRepository.findWithSearch(projectId, query, false)
                         .stream()
                         .map(Forwarding::toForwardingDTO)
                         .toList()).build();
diff --git a/src/main/java/com/aolda/itda/service/routing/RoutingService.java b/src/main/java/com/aolda/itda/service/routing/RoutingService.java
index 769278d..d01eb02 100644
--- a/src/main/java/com/aolda/itda/service/routing/RoutingService.java
+++ b/src/main/java/com/aolda/itda/service/routing/RoutingService.java
@@ -28,6 +28,7 @@ import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.nio.file.StandardCopyOption;
 import java.util.List;
+import java.util.regex.Pattern;
 
 @Service
 @Transactional
@@ -52,10 +53,26 @@ public class RoutingService {
         return routing.toRoutingDTO();
     }
 
-    /* Routing 목록 조회 */
-    public PageResp<RoutingDTO> getRoutings(String projectId) {
+    /* Routing 목록 조회 + 검색 */
+    public PageResp<RoutingDTO> getRoutingsWithSearch(String projectId, String query) {
+
+        /* 입력 검증 */
+        if (query == null || query.isBlank()) {
+            return PageResp.<RoutingDTO>builder()
+                    .contents(routingRepository.findByProjectIdAndIsDeleted(projectId, false)
+                            .stream()
+                            .map(Routing::toRoutingDTO)
+                            .toList()).build();
+        }
+
+        /* 도메인 패턴 검증 */
+        String domainPattern = "^(\\*\\.)?([a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,}$";
+        if (Pattern.matches(domainPattern, query) && query.startsWith("*.")) {
+            query = query.substring(2);
+        }
+
         return PageResp.<RoutingDTO>builder()
-                .contents(routingRepository.findByProjectIdAndIsDeleted(projectId, false)
+                .contents(routingRepository.findWithSearch(projectId, query, false)
                         .stream()
                         .map(Routing::toRoutingDTO)
                         .toList()).build();
-- 
GitLab