- K8sUtil 파일 삭제
- 승인관리 완전삭제 기능 추가 - DJBank로 명칭 업데이트
This commit is contained in:
@@ -14,6 +14,7 @@ public class PortalApprovalAuthorizer implements ApprovalAuthorizer {
|
||||
return approval.getApprovers().stream()
|
||||
.filter(this::isCurrentApprover)
|
||||
.map(this::getApproverId)
|
||||
.filter(java.util.Objects::nonNull)
|
||||
.anyMatch(id -> id.equals(approverId));
|
||||
}
|
||||
|
||||
@@ -22,6 +23,6 @@ public class PortalApprovalAuthorizer implements ApprovalAuthorizer {
|
||||
}
|
||||
|
||||
private String getApproverId(Approver approver) {
|
||||
return approver.getUser().getId();
|
||||
return approver.getUser() != null ? approver.getUser().getId() : null;
|
||||
}
|
||||
}
|
||||
|
||||
+50
-2
@@ -13,10 +13,16 @@ import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.web.SortDefault;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Controller
|
||||
@RequiredArgsConstructor
|
||||
public class PortalApprovalManController extends BaseAnnotationController {
|
||||
@@ -24,8 +30,8 @@ public class PortalApprovalManController extends BaseAnnotationController {
|
||||
private final PortalApprovalManService portalApprovalManService;
|
||||
|
||||
@GetMapping(value = "/onl/apim/approval/portalApprovalMan.view")
|
||||
public void view() {
|
||||
// view
|
||||
public void view(Model model) {
|
||||
model.addAttribute("hardDeleteEnabled", portalApprovalManService.isHardDeleteEnabled());
|
||||
}
|
||||
|
||||
@GetMapping(value = "/onl/apim/approval/portalApprovalMan.view", params = "cmd=DETAIL")
|
||||
@@ -76,4 +82,46 @@ public class PortalApprovalManController extends BaseAnnotationController {
|
||||
portalApprovalManService.redeploy(id);
|
||||
return ResponseEntity.ok().build();
|
||||
}
|
||||
|
||||
@PostMapping(value = "/onl/apim/approval/portalApprovalMan.json", params = "cmd=HARD_DELETE_MULTIPLE")
|
||||
public ResponseEntity<Map<String, Object>> hardDeleteMultiple(String ids) {
|
||||
Map<String, Object> resultMap = new HashMap<>();
|
||||
try {
|
||||
if (StringUtils.isBlank(ids)) {
|
||||
resultMap.put("status", "fail");
|
||||
resultMap.put("message", "삭제할 승인 요청을 선택해주세요.");
|
||||
return ResponseEntity.ok(resultMap);
|
||||
}
|
||||
|
||||
String[] idArray = ids.split(",");
|
||||
int successCount = 0;
|
||||
List<String> failMessages = new ArrayList<>();
|
||||
|
||||
for (String id : idArray) {
|
||||
if (StringUtils.isNotBlank(id.trim())) {
|
||||
try {
|
||||
portalApprovalManService.hardDelete(id.trim());
|
||||
successCount++;
|
||||
} catch (BizException e) {
|
||||
failMessages.add(e.getMessage());
|
||||
} catch (Exception e) {
|
||||
failMessages.add(id.trim() + ": " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (failMessages.isEmpty()) {
|
||||
resultMap.put("status", "success");
|
||||
resultMap.put("message", successCount + "건의 승인 요청이 완전삭제되었습니다.");
|
||||
} else {
|
||||
resultMap.put("status", "fail");
|
||||
resultMap.put("message", "완전삭제 실패: " + String.join(", ", failMessages)
|
||||
+ (successCount > 0 ? " (" + successCount + "건 성공)" : ""));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
resultMap.put("status", "fail");
|
||||
resultMap.put("message", "완전삭제 중 오류가 발생했습니다: " + e.getMessage());
|
||||
}
|
||||
return ResponseEntity.ok(resultMap);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.eactive.apim.portal.apprequest.repository.AppRequestRepository;
|
||||
import com.eactive.apim.portal.approval.entity.Approval;
|
||||
import com.eactive.apim.portal.approval.entity.ApprovalType;
|
||||
import com.eactive.apim.portal.approval.statemachine.*;
|
||||
import com.eactive.apim.portal.portalproperty.service.PortalPropertyService;
|
||||
import com.eactive.apim.portal.portaluser.entity.PortalUser;
|
||||
import com.eactive.apim.portal.portaluser.repository.PortalUserRepository;
|
||||
import com.eactive.eai.data.entity.onl.apim.apigroup.ApiGroup;
|
||||
@@ -25,6 +26,7 @@ import com.eactive.eai.rms.onl.apim.portalorg.PortalOrgManService;
|
||||
import com.eactive.eai.rms.onl.apim.portaluser.PortalUserManService;
|
||||
import com.eactive.eai.rms.onl.apim.portaluser.PortalUserUI;
|
||||
import com.eactive.eai.rms.common.acl.user.ui.UserUI;
|
||||
import com.eactive.eai.rms.onl.common.exception.BizException;
|
||||
import com.eactive.eai.rms.onl.transaction.apim.ApiInterfaceService;
|
||||
import com.eactive.eai.rms.onl.transaction.apim.mapping.ApiSpecUIMapper;
|
||||
import com.eactive.eai.rms.onl.transaction.apim.ui.ApiInterfaceUI;
|
||||
@@ -36,6 +38,8 @@ import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import java.util.*;
|
||||
|
||||
@Service
|
||||
@@ -43,6 +47,9 @@ import java.util.*;
|
||||
@RequiredArgsConstructor
|
||||
public class PortalApprovalManService extends BaseService {
|
||||
|
||||
private static final String PORTAL_PROPERTY_GROUP = "Portal";
|
||||
private static final String HARD_DELETE_FLAG_KEY = "approval.hard-delete.enabled";
|
||||
|
||||
private final ApprovalService approvalService;
|
||||
private final ApprovalStateMachine approvalStateMachine;
|
||||
private final AppRequestRepository appRequestRepository;
|
||||
@@ -59,6 +66,10 @@ public class PortalApprovalManService extends BaseService {
|
||||
private final ApiGroupUIMapper apiGroupUIMapper;
|
||||
private final PortalApprovalAuthorizer portalApprovalAuthorizer;
|
||||
private final PortalOrgManService portalOrgManService;
|
||||
private final PortalPropertyService portalPropertyService;
|
||||
|
||||
@PersistenceContext(unitName = "entityManagerFactoryForEMS")
|
||||
private EntityManager entityManager;
|
||||
|
||||
public Page<PortalApprovalUI> selectList(Pageable pageable, PortalApprovalUISearch portalApprovalUISearch) {
|
||||
Page<Approval> approval = approvalService.findAll(pageable, portalApprovalUISearch);
|
||||
@@ -330,6 +341,28 @@ public class PortalApprovalManService extends BaseService {
|
||||
|
||||
}
|
||||
|
||||
public boolean isHardDeleteEnabled() {
|
||||
Map<String, String> properties = portalPropertyService.getPortalPropertiesAsMap(PORTAL_PROPERTY_GROUP);
|
||||
return Boolean.parseBoolean(properties.getOrDefault(HARD_DELETE_FLAG_KEY, "false"));
|
||||
}
|
||||
|
||||
public void hardDelete(String id) {
|
||||
if (!isHardDeleteEnabled()) {
|
||||
throw new BizException("승인 요청 완전삭제 기능이 비활성화되어 있습니다. (PTL_PROPERTY: " + HARD_DELETE_FLAG_KEY + ")");
|
||||
}
|
||||
// Approval.approvers 가 EAGER + Approver.user 가 NotFound 처리 없음 → 사라진 UserInfo 로 인해
|
||||
// findById/deleteById 가 hydration 단계에서 실패하는 row 가 존재. 네이티브 SQL 로 우회.
|
||||
entityManager.createNativeQuery("DELETE FROM PTL_APPROVER WHERE APPROVAL_ID = :id")
|
||||
.setParameter("id", id)
|
||||
.executeUpdate();
|
||||
int affected = entityManager.createNativeQuery("DELETE FROM PTL_APPROVAL WHERE ID = :id")
|
||||
.setParameter("id", id)
|
||||
.executeUpdate();
|
||||
if (affected == 0) {
|
||||
throw new BizException("승인 정보를 찾을 수 없습니다. ID: " + id);
|
||||
}
|
||||
}
|
||||
|
||||
public void sendEvent(String id, ApprovalEvent event, Map<String, Object> options) {
|
||||
approvalService.findById(id).ifPresent(approval -> {
|
||||
options.put("authorizer", portalApprovalAuthorizer);
|
||||
|
||||
+10
-17
@@ -6,7 +6,6 @@ import com.eactive.apim.portal.apprequest.repository.AppRequestRepository;
|
||||
import com.eactive.apim.portal.approval.entity.Approval;
|
||||
import com.eactive.apim.portal.approval.service.ApprovalDeployException;
|
||||
import com.eactive.apim.portal.approval.statemachine.listener.ApprovalListener;
|
||||
import com.eactive.apim.portal.portalproperty.service.PortalPropertyService;
|
||||
import com.eactive.apim.portal.template.entity.MessageCode;
|
||||
import com.eactive.apim.portal.template.service.MessageRecipient;
|
||||
import com.eactive.apim.portal.template.service.MessageSendService;
|
||||
@@ -19,10 +18,8 @@ import com.eactive.eai.rms.onl.apim.approval.RandomStringGenerator;
|
||||
import com.eactive.eai.rms.onl.apim.approval.credential.CredentialManService;
|
||||
import com.eactive.eai.rms.onl.apim.approval.credential.CredentialUI;
|
||||
import com.eactive.eai.rms.onl.apim.approval.credential.CredentialUIMapper;
|
||||
import com.eactive.eai.rms.onl.apim.portaluser.PortalUserUI;
|
||||
import com.eactive.eai.rms.onl.common.service.AgentUtilService;
|
||||
import com.eactive.eai.rms.onl.manage.authserver.client.ClientManService;
|
||||
import com.eactive.eai.rms.onl.manage.authserver.client.ClientUI;
|
||||
import com.eactive.eai.rms.onl.transaction.apim.ui.ApiSpecInfoUI;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
@@ -35,22 +32,12 @@ import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@@ -116,9 +103,15 @@ public class PortalAppApprovalListener implements ApprovalListener {
|
||||
}
|
||||
|
||||
private void sendApprovalResult(AppRequest appRequest) {
|
||||
com.eactive.apim.portal.portaluser.entity.PortalUser requester =
|
||||
appRequest.getApproval() != null ? appRequest.getApproval().getRequester() : null;
|
||||
if (requester == null) {
|
||||
logger.warn("승인 결과 통지 생략 - 요청자 정보 없음. appRequestId: {}", appRequest.getId());
|
||||
return;
|
||||
}
|
||||
MessageRecipient recipient = new MessageRecipient();
|
||||
recipient.setPhone(appRequest.getApproval().getRequester().getMobileNumber());
|
||||
recipient.setUserId(appRequest.getApproval().getRequester().getEmailAddr());
|
||||
recipient.setPhone(requester.getMobileNumber());
|
||||
recipient.setUserId(requester.getEmailAddr());
|
||||
Map<String, String> params = new HashMap<>();
|
||||
params.put("apiKey", appRequest.getClientName());
|
||||
messageSendService.sendMessage(MessageCode.APP_REGISTER_APPROVED, recipient, params);
|
||||
@@ -165,8 +158,8 @@ public class PortalAppApprovalListener implements ApprovalListener {
|
||||
credentialUI.setClientname(appRequest.getClientName());
|
||||
credentialUI.setScope("api");
|
||||
credentialUI.setGranttypes("client_credentials");
|
||||
credentialUI.setOrgid(appRequest.getOrg().getId());
|
||||
credentialUI.setOrgname(appRequest.getOrg().getOrgName());
|
||||
credentialUI.setOrgid(appRequest.getOrg() != null ? appRequest.getOrg().getId() : null);
|
||||
credentialUI.setOrgname(appRequest.getOrg() != null ? appRequest.getOrg().getOrgName() : null);
|
||||
credentialUI.setAllowedips(appRequest.getIpWhitelist());
|
||||
credentialUI.setRedirecturi(appRequest.getCallbackUrl());
|
||||
credentialUI.setAppIconFileId(appRequest.getAppIconFileId());
|
||||
|
||||
@@ -27,6 +27,8 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
@@ -48,6 +50,9 @@ public class PortalOrgManService extends BaseService {
|
||||
private final PortalUserCorpManagerUIMapper portalUserCorpManagerUIMapper;
|
||||
private final FileService fileService;
|
||||
|
||||
@PersistenceContext(unitName = "entityManagerFactoryForEMS")
|
||||
private EntityManager entityManager;
|
||||
|
||||
public Page<PortalOrgUI> selectList(Pageable pageable, PortalOrgUISearch portalOrgUISearch) {
|
||||
Page<PortalOrg> portalOrg = portalOrgService.findAll(pageable, portalOrgUISearch);
|
||||
return portalOrg.map(entity -> convertToUIWithMaskOption(entity, true));
|
||||
@@ -146,19 +151,37 @@ public class PortalOrgManService extends BaseService {
|
||||
throw new BizException("삭제(탈퇴) 상태인 법인만 완전삭제할 수 있습니다.");
|
||||
}
|
||||
|
||||
List<String> dependencies = new ArrayList<>();
|
||||
// 사용자(PortalUser)는 별도 화면에서 정리해야 하므로 cascade 하지 않고 차단
|
||||
long userCount = portalUserService.countByOrgId(id);
|
||||
if (userCount > 0) dependencies.add("사용자 " + userCount + "건");
|
||||
long appRequestCount = portalOrgService.countAppRequestByOrgId(id);
|
||||
if (appRequestCount > 0) dependencies.add("앱 신청 " + appRequestCount + "건");
|
||||
|
||||
if (!dependencies.isEmpty()) {
|
||||
throw new BizException("의존 데이터가 존재하여 완전삭제할 수 없습니다: " + String.join(", ", dependencies));
|
||||
if (userCount > 0) {
|
||||
throw new BizException("의존 데이터가 존재하여 완전삭제할 수 없습니다: 사용자 " + userCount + "건");
|
||||
}
|
||||
|
||||
// 앱 신청(AppRequest) + 연결된 승인(Approval/Approver) 은 cascade 삭제
|
||||
cascadeDeleteAppRequestsByOrg(id);
|
||||
|
||||
portalOrgService.deleteById(id);
|
||||
}
|
||||
|
||||
private void cascadeDeleteAppRequestsByOrg(String orgId) {
|
||||
// 1) 해당 org 의 app_request 가 참조하는 approval 의 approver 제거
|
||||
entityManager.createNativeQuery(
|
||||
"DELETE FROM PTL_APPROVER WHERE APPROVAL_ID IN " +
|
||||
"(SELECT APPROVAL_ID FROM PTL_APP_REQUEST WHERE ORG_ID = :orgId AND APPROVAL_ID IS NOT NULL)"
|
||||
).setParameter("orgId", orgId).executeUpdate();
|
||||
|
||||
// 2) approval 제거
|
||||
entityManager.createNativeQuery(
|
||||
"DELETE FROM PTL_APPROVAL WHERE ID IN " +
|
||||
"(SELECT APPROVAL_ID FROM PTL_APP_REQUEST WHERE ORG_ID = :orgId AND APPROVAL_ID IS NOT NULL)"
|
||||
).setParameter("orgId", orgId).executeUpdate();
|
||||
|
||||
// 3) app_request 제거
|
||||
entityManager.createNativeQuery(
|
||||
"DELETE FROM PTL_APP_REQUEST WHERE ORG_ID = :orgId"
|
||||
).setParameter("orgId", orgId).executeUpdate();
|
||||
}
|
||||
|
||||
public Map<String, Object> selectDetailWithUsers(String id) {
|
||||
return getDetailWithUsers(id, true);
|
||||
}
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
package com.eactive.eai.rms.onl.common.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.eactive.eai.rms.onl.common.service.OnlAgentUtilServiceImpl;
|
||||
|
||||
import io.kubernetes.client.openapi.ApiClient;
|
||||
import io.kubernetes.client.openapi.Configuration;
|
||||
import io.kubernetes.client.openapi.apis.CoreV1Api;
|
||||
import io.kubernetes.client.openapi.models.V1EndpointAddress;
|
||||
import io.kubernetes.client.openapi.models.V1EndpointSubset;
|
||||
import io.kubernetes.client.openapi.models.V1Endpoints;
|
||||
import io.kubernetes.client.util.ClientBuilder;
|
||||
|
||||
public class K8sUtil {
|
||||
private static final Logger logger = Logger.getLogger(K8sUtil.class);
|
||||
|
||||
public static List<Map<String, String>> getServerInfoByK8sUrl(String namespace, String serviceName, int port, String extUrl) throws Exception {
|
||||
|
||||
List<Map<String, String>> resultList = getServerInfoByK8sApi(namespace,serviceName);
|
||||
|
||||
for (Map<String,String> map : resultList) {
|
||||
String EAISEVRINSTNCNAME = map.get("EAISEVRINSTNCNAME");
|
||||
String EAISEVRIP = map.get("EAISEVRIP");
|
||||
Map<String, String> serverInfo = new HashMap<>();
|
||||
|
||||
serverInfo.put(OnlAgentUtilServiceImpl.FIELD_URL, new StringBuilder().append("http://" + EAISEVRIP + ":"+String.valueOf(port) + extUrl).toString());
|
||||
serverInfo.put(OnlAgentUtilServiceImpl.FIELD_INST_NAME, EAISEVRINSTNCNAME);
|
||||
}
|
||||
|
||||
return resultList;
|
||||
}
|
||||
public static List<Map<String, String>> getServerInfoByK8sApi(String namespace, String serviceName) throws Exception {
|
||||
|
||||
logger.info("K8sAgentUtilService getServerInfoByK8sApi start.");
|
||||
|
||||
List<Map<String, String>> resultList = new ArrayList<>();
|
||||
|
||||
try {
|
||||
ApiClient client = ClientBuilder.cluster().build();
|
||||
Configuration.setDefaultApiClient(client);
|
||||
|
||||
if (StringUtils.isBlank(namespace)) {
|
||||
new RuntimeException("Can't find kubernetes_namespace in Engine Property");
|
||||
}
|
||||
if (StringUtils.isBlank(serviceName)) {
|
||||
new RuntimeException("Can't find kubernetes_servicename in Engine Property");
|
||||
}
|
||||
|
||||
logger.info("getServerInfoByK8sApi Codes [ namespace: " + namespace + ", serviceName:" + serviceName + " ]");
|
||||
|
||||
V1Endpoints endpoints = new CoreV1Api().readNamespacedEndpoints(serviceName, namespace, null);
|
||||
|
||||
for (V1EndpointSubset subset : endpoints.getSubsets()) {
|
||||
for (V1EndpointAddress address : subset.getAddresses()) {
|
||||
Map<String, String> serverInfo = new HashMap<>();
|
||||
serverInfo.put("EAISEVRINSTNCNAME", address.getTargetRef().getName());
|
||||
serverInfo.put("EAISEVRIP", address.getIp());
|
||||
resultList.add(serverInfo);
|
||||
}
|
||||
}
|
||||
|
||||
logger.info("getServerInfoByK8sApi resultList [ " + resultList.toString() + " ]");
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error(e);
|
||||
throw new RuntimeException("K8S Mode로 AgentUtilService를 기동중 실패하였습니다.", e);
|
||||
}
|
||||
|
||||
return resultList;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user