Skip to content
Snippets Groups Projects
Commit 21125ed0 authored by nahyun's avatar nahyun
Browse files

Merge branch 'feat/forwarding' into 'dev'

Feat/forwarding nginx 테스트, 리로드 / 파일 롤백

See merge request !9
parents 5b1a3a59 82fd3ae9
No related branches found
No related tags found
2 merge requests!15Feat/certificate,!9Feat/forwarding nginx 테스트, 리로드 / 파일 롤백
...@@ -20,7 +20,14 @@ public enum ErrorCode { ...@@ -20,7 +20,14 @@ public enum ErrorCode {
NOT_FOUND_FORWARDING(HttpStatus.BAD_REQUEST, "포트포워딩 파일이 존재하지 않습니다"), NOT_FOUND_FORWARDING(HttpStatus.BAD_REQUEST, "포트포워딩 파일이 존재하지 않습니다"),
INVALID_CONF_INPUT(HttpStatus.BAD_REQUEST, "잘못된 입력이 존재합니다"), INVALID_CONF_INPUT(HttpStatus.BAD_REQUEST, "잘못된 입력이 존재합니다"),
DUPLICATED_INSTANCE_INFO(HttpStatus.BAD_REQUEST, "중복된 인스턴스 IP와 포트입니다"), DUPLICATED_INSTANCE_INFO(HttpStatus.BAD_REQUEST, "중복된 인스턴스 IP와 포트입니다"),
DUPLICATED_SERVER_PORT(HttpStatus.BAD_REQUEST, "중복된 서버 포트입니다"); DUPLICATED_SERVER_PORT(HttpStatus.BAD_REQUEST, "중복된 서버 포트입니다"),
// Nginx
FAIL_NGINX_CONF_TEST(HttpStatus.BAD_REQUEST, "Conf 파일 테스트에 실패했습니다"),
FAIL_NGINX_CONF_RELOAD(HttpStatus.BAD_REQUEST, "Nginx 재시작에 실패했습니다"),
FAIL_DELETE_CONF(HttpStatus.BAD_REQUEST, "Conf 파일을 삭제하지 못했습니다"),
FAIL_ROLL_BACK(HttpStatus.BAD_REQUEST, "롤백 실패");
private final HttpStatus status; private final HttpStatus status;
private final String message; private final String message;
......
...@@ -7,12 +7,20 @@ import com.aolda.itda.exception.CustomException; ...@@ -7,12 +7,20 @@ import com.aolda.itda.exception.CustomException;
import com.aolda.itda.exception.ErrorCode; import com.aolda.itda.exception.ErrorCode;
import com.aolda.itda.repository.forwarding.ForwardingRepository; import com.aolda.itda.repository.forwarding.ForwardingRepository;
import com.aolda.itda.template.ForwardingTemplate; import com.aolda.itda.template.ForwardingTemplate;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.validation.ConstraintViolation; import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validation; import jakarta.validation.Validation;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import java.io.BufferedWriter; import java.io.BufferedWriter;
import java.io.File; import java.io.File;
...@@ -21,16 +29,20 @@ import java.io.IOException; ...@@ -21,16 +29,20 @@ import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Map;
@Service @Service
@Transactional @Transactional
@RequiredArgsConstructor @RequiredArgsConstructor
@Slf4j
public class ForwardingService { public class ForwardingService {
@Value("${spring.server.base-ip}") @Value("${spring.server.base-ip}")
private String serverBaseIp; private String serverBaseIp;
private final ForwardingTemplate forwardingTemplate; private final ForwardingTemplate forwardingTemplate;
private final ForwardingRepository forwardingRepository; private final ForwardingRepository forwardingRepository;
private final RestTemplate restTemplate = new RestTemplate();
/* 포트포워딩 정보 조회 */ /* 포트포워딩 정보 조회 */
public ForwardingDTO getForwarding(Long forwardingId) { public ForwardingDTO getForwarding(Long forwardingId) {
...@@ -95,18 +107,53 @@ public class ForwardingService { ...@@ -95,18 +107,53 @@ public class ForwardingService {
/* conf 파일 작성 및 예외 처리 */ /* conf 파일 작성 및 예외 처리 */
try { try {
BufferedWriter bw = new BufferedWriter(new FileWriter(file, true)); // 예외처리 필요 BufferedWriter bw = new BufferedWriter(new FileWriter(file, false)); // 예외처리 필요
bw.write(content); bw.write(content);
bw.flush(); bw.flush();
bw.close(); bw.close();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
if (file.exists()) { if (file.delete()) {
file.delete(); throw new CustomException(ErrorCode.FAIL_DELETE_CONF);
} }
throw new CustomException(ErrorCode.FAIL_CREATE_CONF, "포트포워딩 Conf 파일을 작성하지 못했습니다"); throw new CustomException(ErrorCode.FAIL_CREATE_CONF, "포트포워딩 Conf 파일을 작성하지 못했습니다");
} }
/* nginx test */
String url = "http://nginx:8081/nginx-api/test";
try {
restTemplate.getForEntity(url, String.class);
} catch (HttpServerErrorException.InternalServerError e) {
log.error("[nginxApiException] {} : {}", e.getResponseBodyAsString(), e.getMessage());
if (file.delete()) {
throw new CustomException(ErrorCode.FAIL_NGINX_CONF_TEST, "(롤백 실패)");
}
throw new CustomException(ErrorCode.FAIL_NGINX_CONF_TEST);
} catch (Exception e) {
log.error("[RestClientException] {} : {}", "Nginx Conf Test (forwarding)", e.getMessage());
if (file.delete()) {
throw new CustomException(ErrorCode.FAIL_NGINX_CONF_TEST, "(롤백 실패)");
}
throw new CustomException(ErrorCode.FAIL_NGINX_CONF_TEST);
}
/* nginx reload */
url = "http://nginx:8081/nginx-api/reload";
try {
restTemplate.getForEntity(url, String.class);
} catch (HttpServerErrorException.InternalServerError e) {
log.error("[nginxApiException] {} : {}", e.getResponseBodyAsString(), e.getMessage());
if (file.delete()) {
throw new CustomException(ErrorCode.FAIL_NGINX_CONF_TEST, "(롤백 실패)");
}
throw new CustomException(ErrorCode.FAIL_NGINX_CONF_RELOAD);
} catch (Exception e) {
log.error("[RestClientException] {} : {}", "Nginx Conf Reload (forwarding)", e.getMessage());
if (file.delete()) {
throw new CustomException(ErrorCode.FAIL_NGINX_CONF_TEST, "(롤백 실패)");
}
throw new CustomException(ErrorCode.FAIL_NGINX_CONF_RELOAD);
}
} }
...@@ -115,21 +162,31 @@ public class ForwardingService { ...@@ -115,21 +162,31 @@ public class ForwardingService {
Forwarding forwarding = forwardingRepository.findByForwardingIdAndIsDeleted(forwardingId, false) Forwarding forwarding = forwardingRepository.findByForwardingIdAndIsDeleted(forwardingId, false)
.orElseThrow(() -> new CustomException(ErrorCode.NOT_FOUND_FORWARDING)); .orElseThrow(() -> new CustomException(ErrorCode.NOT_FOUND_FORWARDING));
forwarding.edit(dto);
/* 중복 검증 */ /* 중복 검증 */
if (dto.getServerPort() != null && forwardingRepository.existsByServerPortAndIsDeleted(dto.getServerPort(), false)) {
System.out.println(dto.getServerPort());
System.out.println(forwarding.getServerPort());
forwardingRepository.existsByServerPortAndIsDeleted(dto.getServerPort(), false);
throw new CustomException(ErrorCode.DUPLICATED_SERVER_PORT);
}
if (!(dto.getInstanceIp() == null && dto.getInstancePort() == null) && if (!(dto.getInstanceIp() == null && dto.getInstancePort() == null) &&
forwardingRepository.existsByInstanceIpAndInstancePortAndIsDeleted(forwarding.getInstanceIp() forwardingRepository.existsByInstanceIpAndInstancePortAndIsDeleted(
, forwarding.getInstancePort() dto.getInstanceIp() == null ? forwarding.getInstanceIp() : dto.getInstanceIp()
, dto.getInstancePort() == null ? forwarding.getInstancePort() : dto.getInstancePort()
, false)) { , false)) {
System.out.println(dto.getInstanceIp());
System.out.println(forwarding.getInstanceIp());
System.out.println(forwardingRepository.existsByInstanceIpAndInstancePortAndIsDeleted(
dto.getInstanceIp() == null ? forwarding.getInstanceIp() : dto.getInstanceIp()
, dto.getInstancePort() == null ? forwarding.getInstancePort() : dto.getInstancePort()
, false));
throw new CustomException(ErrorCode.DUPLICATED_INSTANCE_INFO); throw new CustomException(ErrorCode.DUPLICATED_INSTANCE_INFO);
} }
if (dto.getServerPort() != null && forwardingRepository.existsByServerPortAndIsDeleted(dto.getServerPort(), false)) {
throw new CustomException(ErrorCode.DUPLICATED_SERVER_PORT);
}
/* 파일 수정 */ /* 파일 수정 */
forwarding.edit(dto);
String content = forwardingTemplate.getPortForwardingWithTCP(forwarding.getServerPort(), String content = forwardingTemplate.getPortForwardingWithTCP(forwarding.getServerPort(),
forwarding.getInstanceIp(), forwarding.getInstanceIp(),
forwarding.getInstancePort(), forwarding.getInstancePort(),
...@@ -140,8 +197,13 @@ public class ForwardingService { ...@@ -140,8 +197,13 @@ public class ForwardingService {
throw new CustomException(ErrorCode.NOT_FOUND_FORWARDING, "Conf 파일이 존재하지 않아 수정할 수 없습니다"); throw new CustomException(ErrorCode.NOT_FOUND_FORWARDING, "Conf 파일이 존재하지 않아 수정할 수 없습니다");
} }
Path backup;
try { try {
BufferedWriter bw = new BufferedWriter(new FileWriter(file, true)); // 예외처리 필요 backup = Files.createTempFile("temp_", ".tmp");
Files.copy(Paths.get(confPath), backup, StandardCopyOption.REPLACE_EXISTING
, StandardCopyOption.COPY_ATTRIBUTES);
BufferedWriter bw = new BufferedWriter(new FileWriter(file, false));
bw.write(content); bw.write(content);
bw.flush(); bw.flush();
bw.close(); bw.close();
...@@ -150,6 +212,59 @@ public class ForwardingService { ...@@ -150,6 +212,59 @@ public class ForwardingService {
throw new CustomException(ErrorCode.FAIL_UPDATE_CONF, "포트포워딩 Conf 파일을 수정하지 못했습니다"); throw new CustomException(ErrorCode.FAIL_UPDATE_CONF, "포트포워딩 Conf 파일을 수정하지 못했습니다");
} }
/* nginx test */
String url = "http://nginx:8081/nginx-api/test";
try {
restTemplate.getForEntity(url, String.class);
} catch (HttpServerErrorException.InternalServerError e) {
log.error("[nginxApiException] {} : {}", e.getResponseBodyAsString(), e.getMessage());
try {
Files.copy(backup, Paths.get(confPath), StandardCopyOption.REPLACE_EXISTING
, StandardCopyOption.COPY_ATTRIBUTES);
Files.delete(backup);
} catch (IOException e1) {
throw new CustomException(ErrorCode.FAIL_UPDATE_CONF, "(포트포워딩 Conf 파일 수정)");
}
throw new CustomException(ErrorCode.FAIL_NGINX_CONF_TEST);
} catch (RuntimeException e) {
log.error("[RestClientException] {} : {}", "Nginx Conf Test (forwarding)", e.getMessage());
try {
Files.copy(backup, Paths.get(confPath), StandardCopyOption.REPLACE_EXISTING
, StandardCopyOption.COPY_ATTRIBUTES);
Files.delete(backup);
} catch (IOException e1) {
throw new CustomException(ErrorCode.FAIL_UPDATE_CONF, "(포트포워딩 Conf 파일 수정)");
}
throw new CustomException(ErrorCode.FAIL_NGINX_CONF_TEST);
}
/* nginx reload */
url = "http://nginx:8081/nginx-api/reload";
try {
restTemplate.getForEntity(url, String.class);
} catch (HttpServerErrorException.InternalServerError e) {
log.error("[nginxApiException] {} : {}", e.getResponseBodyAsString(), e.getMessage());
try {
Files.copy(backup, Paths.get(confPath), StandardCopyOption.REPLACE_EXISTING
, StandardCopyOption.COPY_ATTRIBUTES);
Files.delete(backup);
} catch (IOException e1) {
throw new CustomException(ErrorCode.FAIL_UPDATE_CONF, "(포트포워딩 Conf 파일 수정)");
}
throw new CustomException(ErrorCode.FAIL_NGINX_CONF_RELOAD);
} catch (RuntimeException e) {
log.error("[RestClientException] {} : {}", "Nginx Conf Reload (forwarding)", e.getMessage());
try {
Files.copy(backup, Paths.get(confPath), StandardCopyOption.REPLACE_EXISTING
, StandardCopyOption.COPY_ATTRIBUTES);
Files.delete(backup);
} catch (IOException e1) {
throw new CustomException(ErrorCode.FAIL_UPDATE_CONF, "(포트포워딩 Conf 파일 수정)");
}
throw new CustomException(ErrorCode.FAIL_NGINX_CONF_RELOAD);
}
/* DB 정보 수정 */ /* DB 정보 수정 */
forwardingRepository.save(forwarding); forwardingRepository.save(forwarding);
} }
...@@ -161,9 +276,55 @@ public class ForwardingService { ...@@ -161,9 +276,55 @@ public class ForwardingService {
/* 파일 삭제 */ /* 파일 삭제 */
String confPath = "/data/nginx/stream/" + forwarding.getForwardingId() + ".conf"; String confPath = "/data/nginx/stream/" + forwarding.getForwardingId() + ".conf";
File file = new File(confPath); String deletePath = confPath + ".deleted";
if (!file.delete()) { try {
throw new CustomException(ErrorCode.NOT_FOUND_FORWARDING, "Conf 파일이 존재하지 않아 삭제할 수 없습니다"); Files.move(Paths.get(confPath), Paths.get(deletePath));
} catch (IOException e) {
throw new CustomException(ErrorCode.FAIL_DELETE_CONF);
}
/* nginx test */
String url = "http://nginx:8081/nginx-api/test";
try {
restTemplate.getForEntity(url, String.class);
} catch (HttpServerErrorException.InternalServerError e) {
log.error("[nginxApiException] {} : {}", e.getResponseBodyAsString(), e.getMessage());
try {
Files.move(Paths.get(deletePath), Paths.get(confPath));
} catch (IOException e1) {
throw new CustomException(ErrorCode.FAIL_ROLL_BACK, "(포트포워딩 Conf 삭제)");
}
throw new CustomException(ErrorCode.FAIL_NGINX_CONF_TEST);
} catch (Exception e) {
log.error("[RestClientException] {} : {}", "Nginx Conf Test (forwarding)", e.getMessage());
try {
Files.move(Paths.get(deletePath), Paths.get(confPath));
} catch (IOException e1) {
throw new CustomException(ErrorCode.FAIL_ROLL_BACK, "(포트포워딩 Conf 삭제)");
}
throw new CustomException(ErrorCode.FAIL_NGINX_CONF_TEST);
}
/* nginx reload */
url = "http://nginx:8081/nginx-api/reload";
try {
restTemplate.getForEntity(url, String.class);
} catch (HttpServerErrorException.InternalServerError e) {
log.error("[nginxApiException] {} : {}", e.getResponseBodyAsString(), e.getMessage());
try {
Files.move(Paths.get(deletePath), Paths.get(confPath));
} catch (IOException e1) {
throw new CustomException(ErrorCode.FAIL_ROLL_BACK, "(포트포워딩 Conf 삭제)");
}
throw new CustomException(ErrorCode.FAIL_NGINX_CONF_RELOAD);
} catch (Exception e) {
log.error("[RestClientException] {} : {}", "Nginx Conf Reload (forwarding)", e.getMessage());
try {
Files.move(Paths.get(deletePath), Paths.get(confPath));
} catch (IOException e1) {
throw new CustomException(ErrorCode.FAIL_ROLL_BACK, "(포트포워딩 Conf 삭제)");
}
throw new CustomException(ErrorCode.FAIL_NGINX_CONF_RELOAD);
} }
/* DB */ /* DB */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment