HISTORYTYPE > HISTORYDETAILTYPE 변경
로그 유저 아닐시 시스템으로 남기게 변경 히스토리 남기는 방식 추가 적용 HistoryRequest 생성 히스토리 API 작업 히스토리 mongodb 조회
This commit is contained in:
448
src/main/java/com/caliverse/admin/mongodb/ChangeDetector.java
Normal file
448
src/main/java/com/caliverse/admin/mongodb/ChangeDetector.java
Normal file
@@ -0,0 +1,448 @@
|
||||
package com.caliverse.admin.mongodb;
|
||||
|
||||
import com.caliverse.admin.domain.adminlog.FieldChange;
|
||||
import com.caliverse.admin.dynamodb.domain.DocAttributeHandler;
|
||||
import com.caliverse.admin.dynamodb.domain.doc.DynamoDBDocBase;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
|
||||
public class ChangeDetector {
|
||||
private static final ObjectMapper objectMapper = new ObjectMapper()
|
||||
.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE)
|
||||
.registerModule(new JavaTimeModule())
|
||||
.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
|
||||
|
||||
// 제외할 필드 목록
|
||||
private static final Set<String> EXCLUDED_FIELDS = new HashSet<>(Arrays.asList(
|
||||
"update_dt",
|
||||
"update_by",
|
||||
"created_dt",
|
||||
"created_by"
|
||||
));
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static List<FieldChange> detectInsertChanges(DynamoDBDocBase newDoc) {
|
||||
Object attrib = DocAttributeHandler.getAttribValue(newDoc);
|
||||
if (attrib == null) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
return (attrib instanceof String)
|
||||
? detectChangesFromJsonString((String) attrib)
|
||||
: detectChangesFromObject(attrib);
|
||||
}
|
||||
|
||||
private static List<FieldChange> detectChangesFromJsonString(String jsonString) {
|
||||
try {
|
||||
Map<String, Object> attribMap = objectMapper.readValue(jsonString,
|
||||
new TypeReference<LinkedHashMap<String, Object>>() {});
|
||||
return createFieldChanges(attribMap);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new RuntimeException("Error processing JSON string changes", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<FieldChange> detectChangesFromObject(Object attrib) {
|
||||
Map<String, Object> attribMap = objectMapper.convertValue(attrib,
|
||||
new TypeReference<LinkedHashMap<String, Object>>() {});
|
||||
return createFieldChanges(attribMap);
|
||||
}
|
||||
|
||||
// @SuppressWarnings("unchecked")
|
||||
// public static List<FieldChange> detectInsertChanges(DynamoDBDocBase newDoc) {
|
||||
// List<FieldChange> changes = new ArrayList<>();
|
||||
// Object attrib = DocAttributeHandler.getAttribValue(newDoc);
|
||||
//
|
||||
// if (attrib == null) {
|
||||
// return changes;
|
||||
// }
|
||||
//
|
||||
// Map<String, Object> attribMap = objectMapper.convertValue(attrib, Map.class);
|
||||
//
|
||||
// for (Map.Entry<String, Object> entry : attribMap.entrySet()) {
|
||||
// changes.add(new FieldChange(
|
||||
// entry.getKey(),
|
||||
// null,
|
||||
// entry.getValue()
|
||||
// ));
|
||||
// }
|
||||
//
|
||||
// return changes;
|
||||
// }
|
||||
|
||||
public static <T> List<FieldChange> detectInsertChanges(T newObj) {
|
||||
List<FieldChange> changes = new ArrayList<>();
|
||||
|
||||
if (newObj == null) {
|
||||
return changes;
|
||||
}
|
||||
|
||||
Map<String, Object> newObjMap = objectMapper.convertValue(newObj, Map.class);
|
||||
|
||||
for (Map.Entry<String, Object> entry : newObjMap.entrySet()) {
|
||||
String fieldName = entry.getKey();
|
||||
Object newValue = entry.getValue();
|
||||
if (isExcludedField(fieldName)) {
|
||||
continue;
|
||||
}
|
||||
if (newValue instanceof String && isDateTimeString((String) newValue)) {
|
||||
newValue = ((String) newValue).replace('T', ' ');
|
||||
}
|
||||
changes.add(new FieldChange(
|
||||
fieldName,
|
||||
null,
|
||||
newValue
|
||||
));
|
||||
}
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static List<FieldChange> detectChanges(DynamoDBDocBase beforeDoc, DynamoDBDocBase afterDoc) {
|
||||
List<FieldChange> changes = new ArrayList<>();
|
||||
|
||||
if (beforeDoc == null || afterDoc == null) {
|
||||
return changes;
|
||||
}
|
||||
|
||||
try {
|
||||
Object beforeAttrib = DocAttributeHandler.getAttribValue(beforeDoc);
|
||||
Object afterAttrib = DocAttributeHandler.getAttribValue(afterDoc);
|
||||
|
||||
if (beforeAttrib == null || afterAttrib == null) {
|
||||
return changes;
|
||||
}
|
||||
|
||||
Map<String, Object> oldAttribMap = convertToMap(beforeAttrib);
|
||||
Map<String, Object> newAttribMap = convertToMap(afterAttrib);
|
||||
|
||||
for (Map.Entry<String, Object> entry : newAttribMap.entrySet()) {
|
||||
String fieldName = entry.getKey();
|
||||
Object newValue = entry.getValue();
|
||||
Object oldValue = oldAttribMap.get(fieldName);
|
||||
|
||||
if (!isEqual(oldValue, newValue)) {
|
||||
changes.add(new FieldChange(fieldName, oldValue, newValue));
|
||||
}
|
||||
}
|
||||
|
||||
for (String fieldName : oldAttribMap.keySet()) {
|
||||
if (!newAttribMap.containsKey(fieldName)) {
|
||||
changes.add(new FieldChange(fieldName, oldAttribMap.get(fieldName), null));
|
||||
}
|
||||
}
|
||||
|
||||
return changes;
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new RuntimeException("Error processing document changes", e);
|
||||
}
|
||||
}
|
||||
|
||||
// @SuppressWarnings("unchecked")
|
||||
// public static List<FieldChange> detectChanges(DynamoDBDocBase beforeDoc, DynamoDBDocBase afterDoc) {
|
||||
// List<FieldChange> changes = new ArrayList<>();
|
||||
//
|
||||
// if (beforeDoc == null || afterDoc == null) {
|
||||
// return changes;
|
||||
// }
|
||||
//
|
||||
// Object beforeAttrib = DocAttributeHandler.getAttribValue(beforeDoc);
|
||||
// Object afterAttrib = DocAttributeHandler.getAttribValue(afterDoc);
|
||||
//
|
||||
// if (beforeAttrib == null || afterAttrib == null) {
|
||||
// return changes;
|
||||
// }
|
||||
//
|
||||
// Map<String, Object> oldAttribMap = objectMapper.convertValue(beforeAttrib, Map.class);
|
||||
// Map<String, Object> newAttribMap = objectMapper.convertValue(afterAttrib, Map.class);
|
||||
//
|
||||
// for (Map.Entry<String, Object> entry : newAttribMap.entrySet()) {
|
||||
// String fieldName = entry.getKey();
|
||||
// Object newValue = entry.getValue();
|
||||
// Object oldValue = oldAttribMap.get(fieldName);
|
||||
//
|
||||
// if (!isEqual(oldValue, newValue)) {
|
||||
// changes.add(new FieldChange(fieldName, oldValue, newValue));
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// for (String fieldName : oldAttribMap.keySet()) {
|
||||
// if (!newAttribMap.containsKey(fieldName)) {
|
||||
// changes.add(new FieldChange(fieldName, oldAttribMap.get(fieldName), null));
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return changes;
|
||||
// }
|
||||
|
||||
public static <T> List<FieldChange> detectChanges(T beforeObj, T afterObj) {
|
||||
List<FieldChange> changes = new ArrayList<>();
|
||||
|
||||
if (beforeObj == null || afterObj == null) {
|
||||
return changes;
|
||||
}
|
||||
|
||||
Map<String, Object> oldObjMap = objectMapper.convertValue(beforeObj, Map.class);
|
||||
Map<String, Object> newObjMap = objectMapper.convertValue(afterObj, Map.class);
|
||||
|
||||
// 새로운 값의 모든 필드 확인
|
||||
for (Map.Entry<String, Object> entry : newObjMap.entrySet()) {
|
||||
String fieldName = entry.getKey();
|
||||
if (isExcludedField(fieldName)) {
|
||||
continue;
|
||||
}
|
||||
Object newValue = entry.getValue();
|
||||
Object oldValue = oldObjMap.get(fieldName);
|
||||
|
||||
if (newValue instanceof String && isDateTimeString((String) newValue)) {
|
||||
newValue = ((String) newValue).replace('T', ' ');
|
||||
}
|
||||
if (oldValue instanceof String && isDateTimeString((String) oldValue)) {
|
||||
oldValue = ((String) oldValue).replace('T', ' ');
|
||||
}
|
||||
|
||||
if (!isEqual(oldValue, newValue)) {
|
||||
changes.add(new FieldChange(fieldName, oldValue, newValue));
|
||||
}
|
||||
}
|
||||
|
||||
// 삭제된 필드 확인
|
||||
for (String fieldName : oldObjMap.keySet()) {
|
||||
if (!newObjMap.containsKey(fieldName)) {
|
||||
changes.add(new FieldChange(fieldName, oldObjMap.get(fieldName), null));
|
||||
}
|
||||
}
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static List<FieldChange> detectDeleteChanges(DynamoDBDocBase deletedDoc) {
|
||||
Object attrib = DocAttributeHandler.getAttribValue(deletedDoc);
|
||||
if (attrib == null) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
return (attrib instanceof String)
|
||||
? detectDeleteChangesFromJsonString((String) attrib)
|
||||
: detectDeleteChangesFromObject(attrib);
|
||||
}
|
||||
|
||||
private static List<FieldChange> detectDeleteChangesFromJsonString(String jsonString) {
|
||||
try {
|
||||
Map<String, Object> attribMap = objectMapper.readValue(jsonString,
|
||||
new TypeReference<LinkedHashMap<String, Object>>() {});
|
||||
return createFieldChanges(attribMap);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new RuntimeException("Error processing JSON string changes for delete", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<FieldChange> detectDeleteChangesFromObject(Object attrib) {
|
||||
Map<String, Object> attribMap = objectMapper.convertValue(attrib,
|
||||
new TypeReference<LinkedHashMap<String, Object>>() {});
|
||||
return createFieldChanges(attribMap);
|
||||
}
|
||||
|
||||
// @SuppressWarnings("unchecked")
|
||||
// public static List<FieldChange> detectDeleteChanges(DynamoDBDocBase deletedDoc) {
|
||||
// List<FieldChange> changes = new ArrayList<>();
|
||||
// Object attrib = DocAttributeHandler.getAttribValue(deletedDoc);
|
||||
//
|
||||
// if (attrib == null) {
|
||||
// return changes;
|
||||
// }
|
||||
//
|
||||
// Map<String, Object> attribMap = objectMapper.convertValue(attrib, Map.class);
|
||||
//
|
||||
// for (Map.Entry<String, Object> entry : attribMap.entrySet()) {
|
||||
// changes.add(new FieldChange(
|
||||
// entry.getKey(),
|
||||
// entry.getValue(),
|
||||
// null
|
||||
// ));
|
||||
// }
|
||||
//
|
||||
// return changes;
|
||||
// }
|
||||
|
||||
public static <T> List<FieldChange> detectDeleteChanges(T deletedObj) {
|
||||
List<FieldChange> changes = new ArrayList<>();
|
||||
|
||||
if (deletedObj == null) {
|
||||
return changes;
|
||||
}
|
||||
|
||||
Map<String, Object> objMap = objectMapper.convertValue(deletedObj, Map.class);
|
||||
|
||||
for (Map.Entry<String, Object> entry : objMap.entrySet()) {
|
||||
String fieldName = entry.getKey();
|
||||
if (isExcludedField(fieldName)) {
|
||||
continue;
|
||||
}
|
||||
Object oldValue = entry.getValue();
|
||||
if (oldValue instanceof String && isDateTimeString((String) oldValue)) {
|
||||
oldValue = ((String) oldValue).replace('T', ' ');
|
||||
}
|
||||
changes.add(new FieldChange(
|
||||
fieldName,
|
||||
oldValue,
|
||||
null
|
||||
));
|
||||
}
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
public static <T> List<FieldChange> detectCollectionChanges(Collection<T> items, String tableName) {
|
||||
List<FieldChange> changes = new ArrayList<>();
|
||||
|
||||
if (items.isEmpty()) {
|
||||
return changes;
|
||||
}
|
||||
|
||||
// 첫 번째 항목의 클래스를 기준으로 처리
|
||||
Object firstItem = items.iterator().next();
|
||||
|
||||
// 연관 ID 필드 추출
|
||||
String idFieldName = findIdFieldName(firstItem.getClass());
|
||||
|
||||
// 모든 항목을 처리하되 주요 식별자는 한 번만 기록
|
||||
boolean idRecorded = false;
|
||||
|
||||
for (T item : items) {
|
||||
Map<String, Object> itemMap = objectMapper.convertValue(item, Map.class);
|
||||
|
||||
// ID 기록 (한번만)
|
||||
if (!idRecorded && itemMap.containsKey(idFieldName)) {
|
||||
changes.add(new FieldChange(idFieldName, itemMap.get(idFieldName), null));
|
||||
idRecorded = true;
|
||||
}
|
||||
|
||||
// 각 항목의 고유한 식별자와 내용 기록
|
||||
for (Map.Entry<String, Object> entry : itemMap.entrySet()) {
|
||||
String fieldName = entry.getKey();
|
||||
if (isExcludedField(fieldName) || fieldName.equals(idFieldName)) continue;
|
||||
|
||||
// 고유 식별자로 필드 구분
|
||||
String uniqueId = getUniqueIdentifier(item, itemMap, tableName);
|
||||
String uniqueFieldName = fieldName + "-" + uniqueId;
|
||||
|
||||
changes.add(new FieldChange(uniqueFieldName, entry.getValue(), null));
|
||||
}
|
||||
}
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
// 고유 식별자 생성 메서드
|
||||
private static String getUniqueIdentifier(Object item, Map<String, Object> itemMap, String tableName) {
|
||||
// 테이블별 특별 처리
|
||||
if ("item".equalsIgnoreCase(tableName)) {
|
||||
return String.valueOf(itemMap.get("type")) + "-" +
|
||||
String.valueOf(itemMap.get("reward_group_id"));
|
||||
} else if ("message".equalsIgnoreCase(tableName)) {
|
||||
return String.valueOf(itemMap.get("language"));
|
||||
}
|
||||
|
||||
// 기본 로직
|
||||
if (itemMap.containsKey("lang") || itemMap.containsKey("language")) {
|
||||
return String.valueOf(itemMap.getOrDefault("lang",
|
||||
itemMap.getOrDefault("language", "unknown")));
|
||||
}
|
||||
|
||||
// 기타 식별자 검사
|
||||
for (String key : Arrays.asList("type", "code", "uuid", "seq", "order")) {
|
||||
if (itemMap.containsKey(key)) {
|
||||
return String.valueOf(itemMap.get(key));
|
||||
}
|
||||
}
|
||||
|
||||
// 최후 수단: 해시코드
|
||||
return String.valueOf(System.identityHashCode(item));
|
||||
}
|
||||
|
||||
private static String findIdFieldName(Class<?> clazz) {
|
||||
// 일반적인 ID 필드명
|
||||
String[] candidates = {"id", "ID", clazz.getSimpleName().toLowerCase() + "Id"};
|
||||
|
||||
for (String candidate : candidates) {
|
||||
try {
|
||||
clazz.getDeclaredField(candidate);
|
||||
return candidate;
|
||||
} catch (NoSuchFieldException e) {
|
||||
// 다음 후보 시도
|
||||
}
|
||||
}
|
||||
|
||||
return "id"; // 기본값
|
||||
}
|
||||
|
||||
private static boolean isExcludedField(String fieldName) {
|
||||
return EXCLUDED_FIELDS.contains(fieldName) ||
|
||||
EXCLUDED_FIELDS.contains(toSnakeCase(fieldName)) ||
|
||||
EXCLUDED_FIELDS.contains(toCamelCase(fieldName));
|
||||
}
|
||||
|
||||
private static String toSnakeCase(String str) {
|
||||
return str.replaceAll("([a-z])([A-Z])", "$1_$2").toLowerCase();
|
||||
}
|
||||
|
||||
private static String toCamelCase(String str) {
|
||||
String[] words = str.split("[\\W_]+");
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(words[0].toLowerCase());
|
||||
for (int i = 1; i < words.length; i++) {
|
||||
builder.append(words[i].substring(0, 1).toUpperCase());
|
||||
builder.append(words[i].substring(1).toLowerCase());
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private static boolean isDateTimeString(String value) {
|
||||
return value != null && value.matches("\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}.*");
|
||||
}
|
||||
|
||||
|
||||
private static boolean isEqual(Object obj1, Object obj2) {
|
||||
if (obj1 == null && obj2 == null) return true;
|
||||
if (obj1 == null || obj2 == null) return false;
|
||||
return obj1.equals(obj2);
|
||||
}
|
||||
|
||||
private static List<FieldChange> createFieldChanges(Map<String, Object> attribMap) {
|
||||
List<FieldChange> changes = new ArrayList<>();
|
||||
for (Map.Entry<String, Object> entry : attribMap.entrySet()) {
|
||||
changes.add(new FieldChange(
|
||||
entry.getKey(),
|
||||
null,
|
||||
entry.getValue()
|
||||
));
|
||||
}
|
||||
return changes;
|
||||
}
|
||||
|
||||
private static Map<String, Object> convertToMap(Object attrib) throws JsonProcessingException {
|
||||
if (attrib == null) {
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
if (attrib instanceof String) {
|
||||
// JSON 문자열인 경우
|
||||
return objectMapper.readValue((String) attrib, Map.class);
|
||||
} else if (attrib instanceof Map) {
|
||||
// 이미 Map인 경우
|
||||
return (Map<String, Object>) attrib;
|
||||
} else {
|
||||
// 다른 객체 타입인 경우
|
||||
return objectMapper.convertValue(attrib, Map.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.caliverse.admin.mongodb.domain;
|
||||
|
||||
import com.caliverse.admin.global.common.utils.DateUtils;
|
||||
import com.caliverse.admin.mongodb.entity.EActionType;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Document(collection = "apiLog")
|
||||
public class APILogInfo extends APILogInfoBase {
|
||||
public APILogInfo(EActionType actionType, String tranId, Object body) {
|
||||
super(DateUtils.nowDateTime(), actionType, tranId, body);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.caliverse.admin.mongodb.domain;
|
||||
|
||||
import com.caliverse.admin.mongodb.entity.EActionType;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class APILogInfoBase implements apiLog {
|
||||
private String timestamp;
|
||||
private EActionType actionType;
|
||||
private String tranId;
|
||||
private Object body;
|
||||
|
||||
public APILogInfoBase(String timestamp,
|
||||
EActionType actionType,
|
||||
String tranId,
|
||||
Object body
|
||||
) {
|
||||
this.timestamp = timestamp;
|
||||
this.actionType = actionType;
|
||||
this.tranId = tranId;
|
||||
this.body = body;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.caliverse.admin.mongodb.domain;
|
||||
|
||||
import com.caliverse.admin.domain.entity.EInitDataType;
|
||||
import com.caliverse.admin.mongodb.entity.DBType;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class DataInitializeHistoryBase {
|
||||
|
||||
private DBType dbType;
|
||||
private EInitDataType initDataType;
|
||||
private String tableName;
|
||||
private boolean isSuccess;
|
||||
private String message;
|
||||
|
||||
public DataInitializeHistoryBase(DBType dbType,
|
||||
EInitDataType initDataType,
|
||||
String tableName,
|
||||
boolean isSuccess,
|
||||
String message
|
||||
) {
|
||||
this.dbType = dbType;
|
||||
this.initDataType = initDataType;
|
||||
this.tableName = tableName;
|
||||
this.isSuccess = isSuccess;
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.caliverse.admin.mongodb.domain;
|
||||
|
||||
import com.caliverse.admin.domain.entity.EInitDataType;
|
||||
import com.caliverse.admin.dynamodb.domain.doc.DynamoDBDocBase;
|
||||
import com.caliverse.admin.mongodb.entity.DBType;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Document(collection = "apiLog")
|
||||
public class DynamodbDataInitializeHistory extends DataInitializeHistoryBase {
|
||||
|
||||
private DynamoDBDocBase data;
|
||||
private String key;
|
||||
|
||||
public DynamodbDataInitializeHistory(EInitDataType initDataType,
|
||||
String tableName,
|
||||
boolean isSuccess,
|
||||
String message,
|
||||
DynamoDBDocBase data,
|
||||
String key) {
|
||||
super(DBType.DYNAMODB, initDataType, tableName, isSuccess, message);
|
||||
|
||||
this.data = data;
|
||||
this.key = key;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.caliverse.admin.mongodb.domain;
|
||||
|
||||
import com.caliverse.admin.domain.adminlog.FieldChange;
|
||||
import com.caliverse.admin.domain.entity.HISTORYTYPEDETAIL;
|
||||
import com.caliverse.admin.dynamodb.domain.doc.DynamoDBDocBase;
|
||||
import com.caliverse.admin.global.common.utils.DateUtils;
|
||||
import com.caliverse.admin.mongodb.entity.DBType;
|
||||
import com.caliverse.admin.mongodb.entity.EDBOperationType;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Document(collection = "historyLog")
|
||||
public class DynamodbHistoryLogInfo extends HistoryLogInfoBase {
|
||||
|
||||
private DynamoDBDocBase data;
|
||||
|
||||
public DynamodbHistoryLogInfo(EDBOperationType operationType, HISTORYTYPEDETAIL historyType, String tableName, String message, String tranId, List<FieldChange> changed, String userId, String userIP, DynamoDBDocBase data) {
|
||||
super(DBType.DYNAMODB, DateUtils.nowDateTime(), operationType, historyType, tableName, message, tranId, changed, userId, userIP);
|
||||
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.caliverse.admin.mongodb.domain;
|
||||
|
||||
import com.caliverse.admin.domain.adminlog.FieldChange;
|
||||
import com.caliverse.admin.domain.entity.HISTORYTYPEDETAIL;
|
||||
import com.caliverse.admin.mongodb.entity.DBType;
|
||||
import com.caliverse.admin.mongodb.entity.EDBOperationType;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
public class HistoryLogInfoBase implements historyLog {
|
||||
|
||||
private DBType dbType;
|
||||
private String timestamp;
|
||||
private EDBOperationType operationType;
|
||||
private HISTORYTYPEDETAIL historyType;
|
||||
private String tableName;
|
||||
private String message;
|
||||
private String tranId;
|
||||
private List<FieldChange> changed;
|
||||
private String userId;
|
||||
private String userIP;
|
||||
|
||||
public HistoryLogInfoBase(DBType dbType,
|
||||
String timestamp,
|
||||
EDBOperationType operationType,
|
||||
HISTORYTYPEDETAIL historyType,
|
||||
String tableName,
|
||||
String message,
|
||||
String tranId,
|
||||
List<FieldChange> changed,
|
||||
String userId,
|
||||
String userIP
|
||||
) {
|
||||
this.dbType = dbType;
|
||||
this.timestamp = timestamp;
|
||||
this.operationType = operationType;
|
||||
this.historyType = historyType;
|
||||
this.tableName = tableName;
|
||||
this.message = message;
|
||||
this.tranId = tranId;
|
||||
this.changed = changed;
|
||||
this.userId = userId;
|
||||
this.userIP = userIP;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.caliverse.admin.mongodb.domain;
|
||||
|
||||
import com.caliverse.admin.domain.entity.EInitDataType;
|
||||
import com.caliverse.admin.mongodb.entity.DBType;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Document(collection = "apiLog")
|
||||
public class MysqlDataInitializeHistory extends DataInitializeHistoryBase {
|
||||
|
||||
private Object data;
|
||||
|
||||
public MysqlDataInitializeHistory(EInitDataType initDataType,
|
||||
String tableName,
|
||||
boolean isSuccess,
|
||||
String message,
|
||||
Object data) {
|
||||
super(DBType.MYSQL, initDataType, tableName, isSuccess, message);
|
||||
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.caliverse.admin.mongodb.domain;
|
||||
|
||||
import com.caliverse.admin.domain.adminlog.FieldChange;
|
||||
import com.caliverse.admin.domain.entity.HISTORYTYPEDETAIL;
|
||||
import com.caliverse.admin.global.common.utils.DateUtils;
|
||||
import com.caliverse.admin.mongodb.entity.DBType;
|
||||
import com.caliverse.admin.mongodb.entity.EDBOperationType;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Document(collection = "historyLog")
|
||||
public class MysqlHistoryLogInfo extends HistoryLogInfoBase {
|
||||
|
||||
private Object data;
|
||||
|
||||
public MysqlHistoryLogInfo(EDBOperationType operationType, HISTORYTYPEDETAIL historyType, String tableName, String message, String tranId, List<FieldChange> changed, String userId, String userIP, Object data) {
|
||||
super(DBType.MYSQL, DateUtils.nowDateTime(), operationType, historyType, tableName, message, tranId, changed, userId, userIP);
|
||||
|
||||
this.data = data;
|
||||
// this.data = deepCopy(data);
|
||||
}
|
||||
|
||||
// private Object deepCopy(Object source) {
|
||||
// try {
|
||||
// if (source == null) return null;
|
||||
//
|
||||
// ObjectMapper mapper = new ObjectMapper()
|
||||
// .setSerializationInclusion(JsonInclude.Include.NON_NULL)
|
||||
// .registerModule(new JavaTimeModule());
|
||||
//
|
||||
// String json = mapper.writeValueAsString(source);
|
||||
// return mapper.readValue(json, Object.class);
|
||||
// } catch (Exception e) {
|
||||
// return source;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.caliverse.admin.mongodb.domain;
|
||||
|
||||
public interface apiLog {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.caliverse.admin.mongodb.domain;
|
||||
|
||||
public interface historyLog {
|
||||
|
||||
}
|
||||
18
src/main/java/com/caliverse/admin/mongodb/entity/DBType.java
Normal file
18
src/main/java/com/caliverse/admin/mongodb/entity/DBType.java
Normal file
@@ -0,0 +1,18 @@
|
||||
package com.caliverse.admin.mongodb.entity;
|
||||
|
||||
public enum DBType {
|
||||
|
||||
DYNAMODB,
|
||||
MYSQL,
|
||||
MONGODB
|
||||
;
|
||||
|
||||
public static DBType getHistoryType(String type) {
|
||||
for (DBType historyType : DBType.values()) {
|
||||
if (historyType.name().equals(type)) {
|
||||
return historyType;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.caliverse.admin.mongodb.entity;
|
||||
|
||||
public enum EActionType {
|
||||
|
||||
SCHEDULE("스케줄"),
|
||||
DATA_INIT("데이터 초기화"),
|
||||
MAIL("우편"),
|
||||
EVENT("이벤트");
|
||||
|
||||
private String actionType;
|
||||
EActionType(String type) {
|
||||
this.actionType = type;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.caliverse.admin.mongodb.entity;
|
||||
|
||||
public enum EDBOperationType {
|
||||
|
||||
INSERT("등록"),
|
||||
UPDATE("수정"),
|
||||
DELETE("삭제");
|
||||
|
||||
private String operationType;
|
||||
EDBOperationType(String type) {
|
||||
this.operationType = type;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.caliverse.admin.mongodb.repository;
|
||||
|
||||
|
||||
import com.caliverse.admin.mongodb.domain.APILogInfo;
|
||||
import org.springframework.data.mongodb.repository.MongoRepository;
|
||||
|
||||
public interface APILogRepository extends MongoRepository<APILogInfo, String> {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.caliverse.admin.mongodb.repository;
|
||||
|
||||
import com.caliverse.admin.mongodb.domain.DynamodbDataInitializeHistory;
|
||||
import org.springframework.data.mongodb.repository.MongoRepository;
|
||||
|
||||
public interface DynamodbDataInitializeHistoryRepository extends MongoRepository<DynamodbDataInitializeHistory, String> {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.caliverse.admin.mongodb.repository;
|
||||
|
||||
import com.caliverse.admin.mongodb.domain.DynamodbHistoryLogInfo;
|
||||
import org.springframework.data.mongodb.repository.MongoRepository;
|
||||
|
||||
public interface DynamodbHistoryLogRepository extends MongoRepository<DynamodbHistoryLogInfo, String> {
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.caliverse.admin.mongodb.repository;
|
||||
|
||||
|
||||
|
||||
public interface MongoAdminRepository {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.caliverse.admin.mongodb.repository;
|
||||
|
||||
import com.caliverse.admin.mongodb.domain.MysqlDataInitializeHistory;
|
||||
import org.springframework.data.mongodb.repository.MongoRepository;
|
||||
|
||||
public interface MysqlDataInitializeHistoryRepository extends MongoRepository<MysqlDataInitializeHistory, String> {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.caliverse.admin.mongodb.repository;
|
||||
|
||||
import com.caliverse.admin.mongodb.domain.MysqlHistoryLogInfo;
|
||||
import org.springframework.data.mongodb.repository.MongoRepository;
|
||||
|
||||
public interface MysqlHistoryLogRepository extends MongoRepository<MysqlHistoryLogInfo, String> {
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
package com.caliverse.admin.mongodb.service;
|
||||
|
||||
import com.caliverse.admin.domain.entity.EInitDataType;
|
||||
import com.caliverse.admin.domain.request.LogGenericRequest;
|
||||
import com.caliverse.admin.dynamodb.domain.doc.DynamoDBDocBase;
|
||||
import com.caliverse.admin.global.common.constants.AdminConstants;
|
||||
import com.caliverse.admin.global.component.transaction.TransactionIdManager;
|
||||
import com.caliverse.admin.mongodb.domain.APILogInfo;
|
||||
import com.caliverse.admin.mongodb.domain.DynamodbDataInitializeHistory;
|
||||
import com.caliverse.admin.mongodb.domain.MysqlDataInitializeHistory;
|
||||
import com.caliverse.admin.mongodb.entity.EActionType;
|
||||
import com.caliverse.admin.mongodb.repository.APILogRepository;
|
||||
import com.caliverse.admin.mongodb.repository.DynamodbDataInitializeHistoryRepository;
|
||||
import com.caliverse.admin.mongodb.repository.MysqlDataInitializeHistoryRepository;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.bson.Document;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.aggregation.Aggregation;
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
|
||||
import org.springframework.data.mongodb.core.query.Criteria;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class DataInitializeHistoryService {
|
||||
|
||||
private final MysqlDataInitializeHistoryRepository mysqlDataInitializeHistoryRepository;
|
||||
private final DynamodbDataInitializeHistoryRepository dynamodbDataInitializeHistoryRepository;
|
||||
private final APILogRepository apiLogRepository;
|
||||
private final ObjectMapper objectMapper;
|
||||
private final TransactionIdManager transactionIdManager;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("mongoIndicatorTemplate")
|
||||
private MongoTemplate mongoTemplate;
|
||||
|
||||
@Value("${amazon.dynamodb.metaTable}")
|
||||
private String dynamodbTableName;
|
||||
|
||||
public <T> List<T> loadHistoryData(LogGenericRequest logGenericRequest, Class<T> class1) {
|
||||
String startTime = logGenericRequest.getStartDt().toString().substring(0, 10);
|
||||
String endTime = logGenericRequest.getEndDt().toString().substring(0, 10);
|
||||
String tranId = logGenericRequest.getTranId();
|
||||
|
||||
Criteria criteria = makeCriteria(startTime, endTime);
|
||||
List<AggregationOperation> operations = new ArrayList<>();
|
||||
|
||||
operations.add(Aggregation.match(criteria));
|
||||
|
||||
if(tranId != null && !tranId.isEmpty()) {
|
||||
operations.add(context ->
|
||||
new Document("$match",
|
||||
new Document(AdminConstants.MONGO_DB_KEY_TRAN_ID, tranId)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// 최종 출력 형식
|
||||
operations.add(context ->
|
||||
new Document("$sort",
|
||||
new Document(AdminConstants.MONGO_DB_KEY_TIMESTAMP, -1)
|
||||
)
|
||||
);
|
||||
|
||||
Aggregation aggregation = Aggregation.newAggregation(operations);
|
||||
log.info("loadHistoryData Query: {}", aggregation);
|
||||
|
||||
AggregationResults<T> results = mongoTemplate.aggregate(aggregation, AdminConstants.MONGO_DB_COLLECTION_API_LOG, class1);
|
||||
return results.getMappedResults();
|
||||
}
|
||||
|
||||
protected Criteria makeCriteria(String startTime, String endTime) {
|
||||
return new Criteria()
|
||||
.andOperator(
|
||||
Criteria.where(AdminConstants.MONGO_DB_KEY_TIMESTAMP).gte(startTime).lt(endTime)
|
||||
,Criteria.where(String.format("%s.%s",AdminConstants.MONGO_DB_KEY_BODY, AdminConstants.MONGO_DB_KEY_DB_TYPE)).is("DYNAMODB")
|
||||
);
|
||||
}
|
||||
|
||||
public <T> void mysqlDataInitHistory(EInitDataType dataType,
|
||||
String tableName,
|
||||
boolean isSuccess,
|
||||
String message,
|
||||
T data
|
||||
){
|
||||
|
||||
try {
|
||||
MysqlDataInitializeHistory history = new MysqlDataInitializeHistory(
|
||||
dataType,
|
||||
tableName,
|
||||
isSuccess,
|
||||
message,
|
||||
data
|
||||
);
|
||||
APILogInfo info = new APILogInfo(
|
||||
EActionType.DATA_INIT,
|
||||
transactionIdManager.getCurrentTransactionId(),
|
||||
history
|
||||
);
|
||||
|
||||
apiLogRepository.save(info);
|
||||
// mysqlDataInitializeHistoryRepository.save(history);
|
||||
|
||||
}catch(Exception e){
|
||||
log.error("dataInit history Save Error", e);
|
||||
}
|
||||
}
|
||||
|
||||
public <T> void dynamodbDataInitHistory(EInitDataType dataType,
|
||||
boolean isSuccess,
|
||||
String message,
|
||||
DynamoDBDocBase data,
|
||||
Object key
|
||||
){
|
||||
|
||||
try {
|
||||
DynamodbDataInitializeHistory history = new DynamodbDataInitializeHistory(
|
||||
dataType,
|
||||
dynamodbTableName,
|
||||
isSuccess,
|
||||
message,
|
||||
data,
|
||||
objectMapper.writeValueAsString(key)
|
||||
);
|
||||
|
||||
APILogInfo info = new APILogInfo(
|
||||
EActionType.DATA_INIT,
|
||||
transactionIdManager.getCurrentTransactionId(),
|
||||
history
|
||||
);
|
||||
// dynamodbDataInitializeHistoryRepository.save(history);
|
||||
apiLogRepository.save(info);
|
||||
|
||||
}catch(Exception e){
|
||||
log.error("dataInit history Save Error", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
package com.caliverse.admin.mongodb.service;
|
||||
|
||||
import com.caliverse.admin.domain.adminlog.FieldChange;
|
||||
import com.caliverse.admin.domain.entity.HISTORYTYPEDETAIL;
|
||||
import com.caliverse.admin.dynamodb.domain.doc.DynamoDBDocBase;
|
||||
import com.caliverse.admin.global.common.constants.CommonConstants;
|
||||
import com.caliverse.admin.global.common.utils.CommonUtils;
|
||||
import com.caliverse.admin.global.component.transaction.TransactionIdManager;
|
||||
import com.caliverse.admin.mongodb.ChangeDetector;
|
||||
import com.caliverse.admin.mongodb.domain.DynamodbHistoryLogInfo;
|
||||
import com.caliverse.admin.mongodb.entity.EDBOperationType;
|
||||
import com.caliverse.admin.mongodb.repository.DynamodbHistoryLogRepository;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class DynamodbHistoryLogService {
|
||||
@Value("${amazon.dynamodb.metaTable}")
|
||||
private String tableName;
|
||||
|
||||
private final TransactionIdManager transactionIdManager;
|
||||
private final DynamodbHistoryLogRepository dynamodbHistoryLogRepository;
|
||||
|
||||
public void insertHistoryLog(HISTORYTYPEDETAIL historyType,
|
||||
String message,
|
||||
DynamoDBDocBase metadata
|
||||
){
|
||||
|
||||
List<FieldChange> changes = ChangeDetector.detectInsertChanges(metadata);
|
||||
|
||||
if(!changes.isEmpty()) {
|
||||
DynamodbHistoryLogInfo historyLog = new DynamodbHistoryLogInfo(
|
||||
EDBOperationType.INSERT,
|
||||
historyType,
|
||||
tableName,
|
||||
message,
|
||||
transactionIdManager.getCurrentTransactionId(),
|
||||
changes,
|
||||
CommonUtils.getAdmin() == null ? CommonConstants.SYSTEM : CommonUtils.getAdmin().getEmail(),
|
||||
CommonUtils.getClientIp() == null ? CommonConstants.SYSTEM : CommonUtils.getClientIp(),
|
||||
metadata
|
||||
);
|
||||
|
||||
dynamodbHistoryLogRepository.save(historyLog);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateHistoryLog(HISTORYTYPEDETAIL historyType,
|
||||
String message,
|
||||
DynamoDBDocBase beforeMetadata,
|
||||
DynamoDBDocBase afterMetadata
|
||||
){
|
||||
List<FieldChange> changes = ChangeDetector.detectChanges(
|
||||
beforeMetadata,
|
||||
afterMetadata
|
||||
);
|
||||
|
||||
if(!changes.isEmpty()) {
|
||||
DynamodbHistoryLogInfo historyLog = new DynamodbHistoryLogInfo(
|
||||
EDBOperationType.UPDATE,
|
||||
historyType,
|
||||
tableName,
|
||||
message,
|
||||
transactionIdManager.getCurrentTransactionId(),
|
||||
changes,
|
||||
CommonUtils.getAdmin() == null ? CommonConstants.SYSTEM : CommonUtils.getAdmin().getEmail(),
|
||||
CommonUtils.getClientIp() == null ? CommonConstants.SYSTEM : CommonUtils.getClientIp(),
|
||||
afterMetadata
|
||||
);
|
||||
|
||||
dynamodbHistoryLogRepository.save(historyLog);
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteHistoryLog(HISTORYTYPEDETAIL historyType,
|
||||
String message,
|
||||
DynamoDBDocBase metadata
|
||||
){
|
||||
|
||||
List<FieldChange> changes = ChangeDetector.detectDeleteChanges(metadata);
|
||||
|
||||
if(!changes.isEmpty()) {
|
||||
DynamodbHistoryLogInfo historyLog = new DynamodbHistoryLogInfo(
|
||||
EDBOperationType.DELETE,
|
||||
historyType,
|
||||
tableName,
|
||||
message,
|
||||
transactionIdManager.getCurrentTransactionId(),
|
||||
changes,
|
||||
CommonUtils.getAdmin() == null ? CommonConstants.SYSTEM : CommonUtils.getAdmin().getEmail(),
|
||||
CommonUtils.getClientIp() == null ? CommonConstants.SYSTEM : CommonUtils.getClientIp(),
|
||||
metadata
|
||||
);
|
||||
|
||||
dynamodbHistoryLogRepository.save(historyLog);
|
||||
}
|
||||
}
|
||||
|
||||
public List<DynamodbHistoryLogInfo> getAllHistoryLogs() {
|
||||
return dynamodbHistoryLogRepository.findAll();
|
||||
}
|
||||
|
||||
public Optional<DynamodbHistoryLogInfo> getHistoryLogById(String id) {
|
||||
return dynamodbHistoryLogRepository.findById(id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
package com.caliverse.admin.mongodb.service;
|
||||
|
||||
import com.caliverse.admin.domain.entity.HISTORYTYPEDETAIL;
|
||||
import com.caliverse.admin.domain.request.HistoryRequest;
|
||||
import com.caliverse.admin.global.common.constants.AdminConstants;
|
||||
import com.caliverse.admin.mongodb.entity.DBType;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.bson.Document;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.aggregation.Aggregation;
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
|
||||
import org.springframework.data.mongodb.core.query.Criteria;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
@Slf4j
|
||||
public class HistoryLogService {
|
||||
@Autowired
|
||||
@Qualifier("mongoIndicatorTemplate")
|
||||
private MongoTemplate mongoTemplate;
|
||||
|
||||
public <T> List<T> loadHistoryData(HistoryRequest historyRequest, Class<T> class1) {
|
||||
String startTime = historyRequest.getStartDt() != null ? historyRequest.getStartDt().toString() : "";
|
||||
String endTime = historyRequest.getEndDt() != null ? historyRequest.getEndDt().toString() : "";
|
||||
HISTORYTYPEDETAIL historyType = historyRequest.getHistoryType() != null ? historyRequest.getHistoryType() : null;
|
||||
String user = historyRequest.getUserMail() != null ? historyRequest.getUserMail() : "";
|
||||
DBType dbType = historyRequest.getDbType() != null ? historyRequest.getDbType() : null;
|
||||
|
||||
List<AggregationOperation> operations = new ArrayList<>();
|
||||
Criteria criteria = null;
|
||||
|
||||
if(!startTime.isEmpty() && !endTime.isEmpty()) {
|
||||
criteria = makeCriteria(startTime, endTime);
|
||||
operations.add(Aggregation.match(criteria));
|
||||
}
|
||||
|
||||
if(historyType != null) {
|
||||
operations.add(context ->
|
||||
new Document("$match",
|
||||
new Document(AdminConstants.MONGO_DB_KEY_HISTORY_TYPE, historyType)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if(!user.isEmpty()) {
|
||||
operations.add(context ->
|
||||
new Document("$match",
|
||||
new Document(AdminConstants.MONGO_DB_KEY_USER_ID, user)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if(dbType != null){
|
||||
operations.add(context ->
|
||||
new Document("$match",
|
||||
new Document(AdminConstants.MONGO_DB_KEY_DB_TYPE, dbType)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if(historyRequest.getTableName() != null && !historyRequest.getTableName().isEmpty()){
|
||||
operations.add(context ->
|
||||
new Document("$match",
|
||||
new Document()
|
||||
.append(AdminConstants.MONGO_DB_KEY_TABLE_NAME, historyRequest.getTableName())
|
||||
.append("data._id", historyRequest.getSqlId())
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// 최종 출력 형식
|
||||
operations.add(context ->
|
||||
new Document("$sort",
|
||||
new Document(AdminConstants.MONGO_DB_KEY_TIMESTAMP, -1)
|
||||
)
|
||||
);
|
||||
|
||||
Aggregation aggregation = Aggregation.newAggregation(operations);
|
||||
log.info("loadHistoryData Query: {}", aggregation);
|
||||
|
||||
AggregationResults<T> results = mongoTemplate.aggregate(aggregation, AdminConstants.MONGO_DB_COLLECTION_HISTORY_LOG, class1);
|
||||
return results.getMappedResults();
|
||||
}
|
||||
|
||||
protected Criteria makeCriteria(String startTime, String endTime) {
|
||||
return new Criteria()
|
||||
.andOperator(
|
||||
Criteria.where(AdminConstants.MONGO_DB_KEY_TIMESTAMP).gte(startTime).lt(endTime)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
package com.caliverse.admin.mongodb.service;
|
||||
|
||||
import com.caliverse.admin.domain.adminlog.FieldChange;
|
||||
import com.caliverse.admin.domain.entity.HISTORYTYPEDETAIL;
|
||||
import com.caliverse.admin.global.common.code.CommonCode;
|
||||
import com.caliverse.admin.global.common.code.ErrorCode;
|
||||
import com.caliverse.admin.global.common.constants.CommonConstants;
|
||||
import com.caliverse.admin.global.common.exception.RestApiException;
|
||||
import com.caliverse.admin.global.common.utils.CommonUtils;
|
||||
import com.caliverse.admin.global.component.transaction.TransactionIdManager;
|
||||
import com.caliverse.admin.mongodb.ChangeDetector;
|
||||
import com.caliverse.admin.mongodb.domain.MysqlHistoryLogInfo;
|
||||
import com.caliverse.admin.mongodb.entity.EDBOperationType;
|
||||
import com.caliverse.admin.mongodb.repository.MysqlHistoryLogRepository;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class MysqlHistoryLogService {
|
||||
|
||||
private final TransactionIdManager transactionIdManager;
|
||||
private final MysqlHistoryLogRepository mysqlHistoryLogRepository;
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
public <T> void insertHistoryLog(HISTORYTYPEDETAIL historyType,
|
||||
String tableName,
|
||||
String message,
|
||||
T data
|
||||
){
|
||||
try {
|
||||
List<FieldChange> changes = ChangeDetector.detectInsertChanges(data);
|
||||
|
||||
if(!changes.isEmpty()) {
|
||||
MysqlHistoryLogInfo historyLog = new MysqlHistoryLogInfo(
|
||||
EDBOperationType.INSERT,
|
||||
historyType,
|
||||
tableName,
|
||||
message,
|
||||
transactionIdManager.getCurrentTransactionId(),
|
||||
changes,
|
||||
CommonUtils.getAdmin() == null ? CommonConstants.SYSTEM : CommonUtils.getAdmin().getEmail(),
|
||||
CommonUtils.getClientIp() == null ? CommonConstants.SYSTEM : CommonUtils.getClientIp(),
|
||||
data
|
||||
);
|
||||
|
||||
mysqlHistoryLogRepository.save(historyLog);
|
||||
}
|
||||
}catch(Exception e){
|
||||
log.error("Insert historyLog Save Error", e);
|
||||
throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.ERROR_HISTORY_SAVE.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public <T> void updateHistoryLog(HISTORYTYPEDETAIL historyType,
|
||||
String tableName,
|
||||
String message,
|
||||
T beforeData,
|
||||
T afterData
|
||||
){
|
||||
try {
|
||||
List<FieldChange> changes = ChangeDetector.detectChanges(
|
||||
beforeData,
|
||||
afterData
|
||||
);
|
||||
if(!changes.isEmpty()) {
|
||||
MysqlHistoryLogInfo historyLog = new MysqlHistoryLogInfo(
|
||||
EDBOperationType.UPDATE,
|
||||
historyType,
|
||||
tableName,
|
||||
message,
|
||||
transactionIdManager.getCurrentTransactionId(),
|
||||
changes,
|
||||
CommonUtils.getAdmin() == null ? CommonConstants.SYSTEM : CommonUtils.getAdmin().getEmail(),
|
||||
CommonUtils.getClientIp() == null ? CommonConstants.SYSTEM : CommonUtils.getClientIp(),
|
||||
afterData
|
||||
);
|
||||
|
||||
mysqlHistoryLogRepository.save(historyLog);
|
||||
}
|
||||
}catch(Exception e){
|
||||
log.error("Update historyLog Save Error", e);
|
||||
throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.ERROR_HISTORY_SAVE.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public <T> void deleteHistoryLog(HISTORYTYPEDETAIL historyType,
|
||||
String tableName,
|
||||
String message,
|
||||
T data
|
||||
){
|
||||
|
||||
// List<FieldChange> changes = ChangeDetector.detectDeleteChanges(data);
|
||||
try {
|
||||
List<FieldChange> changes;
|
||||
if (data instanceof Collection && !((Collection<?>) data).isEmpty()) {
|
||||
changes = ChangeDetector.detectCollectionChanges((Collection<?>) data, tableName);
|
||||
} else {
|
||||
changes = ChangeDetector.detectDeleteChanges(data);
|
||||
}
|
||||
if(!changes.isEmpty()){
|
||||
MysqlHistoryLogInfo historyLog = new MysqlHistoryLogInfo(
|
||||
EDBOperationType.DELETE,
|
||||
historyType,
|
||||
tableName,
|
||||
message,
|
||||
transactionIdManager.getCurrentTransactionId(),
|
||||
changes,
|
||||
CommonUtils.getAdmin() == null ? CommonConstants.SYSTEM : CommonUtils.getAdmin().getEmail(),
|
||||
CommonUtils.getClientIp() == null ? CommonConstants.SYSTEM : CommonUtils.getClientIp(),
|
||||
data
|
||||
);
|
||||
|
||||
mysqlHistoryLogRepository.save(historyLog);
|
||||
}
|
||||
}catch(Exception e){
|
||||
log.error("Delete historyLog Save Error", e);
|
||||
throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.ERROR_HISTORY_SAVE.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public List<MysqlHistoryLogInfo> getAllHistoryLogs() {
|
||||
return mysqlHistoryLogRepository.findAll();
|
||||
}
|
||||
|
||||
public Optional<MysqlHistoryLogInfo> getHistoryLogById(String id) {
|
||||
return mysqlHistoryLogRepository.findById(id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,258 @@
|
||||
package com.caliverse.admin.mongodb.service;
|
||||
|
||||
import com.caliverse.admin.global.common.constants.AdminConstants;
|
||||
import com.caliverse.admin.logs.logservice.businesslogservice.IBusinessLogService;
|
||||
import lombok.Getter;
|
||||
import org.bson.Document;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.aggregation.Aggregation;
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
|
||||
import org.springframework.data.mongodb.core.aggregation.ProjectionOperation;
|
||||
import org.springframework.data.mongodb.core.query.Criteria;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@Getter
|
||||
public abstract class historyLogServiceBase implements IBusinessLogService {
|
||||
|
||||
private MongoTemplate mongoTemplate;
|
||||
|
||||
public historyLogServiceBase(MongoTemplate mongoTemplate){
|
||||
this.mongoTemplate = mongoTemplate;
|
||||
}
|
||||
|
||||
//protected abstract Criteria makeCriteria(String startTime, String endTime);
|
||||
|
||||
|
||||
protected AggregationOperation getDefaultProjectOperationRegex(){
|
||||
AggregationOperation projectOperation1 = context ->
|
||||
new Document("$project",
|
||||
new Document(AdminConstants.MONGO_DB_KEY_LANGUAGE_TYPE,
|
||||
new Document("$regexFind",
|
||||
new Document("input", "$message")
|
||||
.append("regex", "\"LanguageType\":\"([^\"]+)\"")
|
||||
)
|
||||
)
|
||||
.append(AdminConstants.MONGO_DB_KEY_MESSAGE, "$message")
|
||||
.append(AdminConstants.MONGO_DB_KEY_LOGTIME, "$logTime")
|
||||
.append(AdminConstants.MONGO_DB_KEY_USER_GUID,
|
||||
new Document("$regexFind",
|
||||
new Document("input", "$message")
|
||||
.append("regex", "\"UserGuid\":\"([^\"]+)\"")
|
||||
)
|
||||
)
|
||||
.append(AdminConstants.MONGO_DB_KEY_USER_NICKNAME,
|
||||
new Document("$regexFind",
|
||||
new Document("input", "$message")
|
||||
.append("regex", "\"UserNickname\":\"([^\"]+)\"")
|
||||
)
|
||||
)
|
||||
.append(AdminConstants.MONGO_DB_KEY_ACCOUNT_ID,
|
||||
new Document("$regexFind",
|
||||
new Document("input", "$message")
|
||||
.append("regex", "\"AccountId\":\"([^\"]+)\"")
|
||||
)
|
||||
)
|
||||
.append(AdminConstants.MONGO_DB_KEY_LOGIN_TIME,
|
||||
new Document("$regexFind",
|
||||
new Document("input", "$message")
|
||||
.append("regex", "\"LoginTime\":\"([^\"]+)\"")
|
||||
)
|
||||
)
|
||||
.append(AdminConstants.MONGO_DB_KEY_LOGOUT_TIME,
|
||||
new Document("$regexFind",
|
||||
new Document("input", "$message")
|
||||
.append("regex", "\"LogoutTime\":\"([^\"]+)\"")
|
||||
)
|
||||
)
|
||||
.append(AdminConstants.MONGO_DB_KEY_TRAN_ID,
|
||||
new Document("$regexFind",
|
||||
new Document("input", "$message")
|
||||
.append("regex", "\"TranId\":\"([^\"]+)\"")
|
||||
)
|
||||
)
|
||||
.append(AdminConstants.MONGO_DB_KEY_ACTION,
|
||||
new Document("$regexFind",
|
||||
new Document("input", "$message")
|
||||
.append("regex", "\"Action\":\"([^\"]+)\"")
|
||||
)
|
||||
)
|
||||
.append(AdminConstants.MONGO_DB_KEY_DOMAIN,
|
||||
new Document("$regexFind",
|
||||
new Document("input", "$message")
|
||||
.append("regex", "\"Domain\":\"([^\"]+)\"")
|
||||
)
|
||||
)
|
||||
.append(AdminConstants.MONGO_DB_KEY_SERVER_TYPE,
|
||||
new Document("$regexFind",
|
||||
new Document("input", "$message")
|
||||
.append("regex", "\"ServerType\":\"([^\"]+)\"")
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
return projectOperation1;
|
||||
}
|
||||
|
||||
|
||||
protected AggregationOperation getDefaultProjectOperationCapture(){
|
||||
AggregationOperation projectOperation2 = context ->
|
||||
new Document("$project",
|
||||
new Document(AdminConstants.MONGO_DB_KEY_LANGUAGE_TYPE,
|
||||
new Document("$ifNull", List.of(
|
||||
new Document("$toString",
|
||||
new Document("$arrayElemAt", List.of("$languageType.captures", 0))
|
||||
),
|
||||
"Ko"
|
||||
)
|
||||
)
|
||||
)
|
||||
.append(AdminConstants.MONGO_DB_KEY_USER_GUID,
|
||||
new Document()
|
||||
.append("$ifNull", List.of(
|
||||
new Document("$toString",
|
||||
new Document("$arrayElemAt", List.of("$userGuid.captures", 0))
|
||||
),
|
||||
"None"
|
||||
)
|
||||
)
|
||||
)
|
||||
.append(AdminConstants.MONGO_DB_KEY_USER_NICKNAME,
|
||||
new Document()
|
||||
.append("$ifNull", List.of(
|
||||
new Document("$toString",
|
||||
new Document("$arrayElemAt", List.of("$userNickname.captures", 0))
|
||||
),
|
||||
"None"
|
||||
)
|
||||
)
|
||||
)
|
||||
.append(AdminConstants.MONGO_DB_KEY_ACCOUNT_ID,
|
||||
new Document()
|
||||
.append("$ifNull", List.of(
|
||||
new Document("$toString",
|
||||
new Document("$arrayElemAt", List.of("$accountId.captures", 0))
|
||||
),
|
||||
"None"
|
||||
)
|
||||
)
|
||||
)
|
||||
.append(AdminConstants.MONGO_DB_KEY_LOGIN_TIME,
|
||||
new Document()
|
||||
.append("$ifNull", List.of(
|
||||
new Document("$toString",
|
||||
new Document("$arrayElemAt", List.of("$loginTime.captures", 0))
|
||||
),
|
||||
""
|
||||
)
|
||||
)
|
||||
)
|
||||
.append(AdminConstants.MONGO_DB_KEY_LOGOUT_TIME,
|
||||
new Document()
|
||||
.append("$ifNull", List.of(
|
||||
new Document("$toString",
|
||||
new Document("$arrayElemAt", List.of("$logoutTime.captures", 0))
|
||||
),
|
||||
""
|
||||
)
|
||||
)
|
||||
)
|
||||
.append(AdminConstants.MONGO_DB_KEY_TRAN_ID,
|
||||
new Document()
|
||||
.append("$ifNull", List.of(
|
||||
new Document("$toString",
|
||||
new Document("$arrayElemAt", List.of("$tranId.captures", 0))
|
||||
),
|
||||
""
|
||||
)
|
||||
)
|
||||
)
|
||||
.append(AdminConstants.MONGO_DB_KEY_ACTION,
|
||||
new Document()
|
||||
.append("$ifNull", List.of(
|
||||
new Document("$toString",
|
||||
new Document("$arrayElemAt", List.of("$action.captures", 0))
|
||||
),
|
||||
""
|
||||
)
|
||||
)
|
||||
)
|
||||
.append(AdminConstants.MONGO_DB_KEY_DOMAIN,
|
||||
new Document()
|
||||
.append("$ifNull", List.of(
|
||||
new Document("$toString",
|
||||
new Document("$arrayElemAt", List.of("$domain.captures", 0))
|
||||
),
|
||||
""
|
||||
)
|
||||
)
|
||||
)
|
||||
.append(AdminConstants.MONGO_DB_KEY_SERVER_TYPE,
|
||||
new Document()
|
||||
.append("$ifNull", List.of(
|
||||
new Document("$toString",
|
||||
new Document("$arrayElemAt", List.of("$serverType.captures", 0))
|
||||
),
|
||||
""
|
||||
)
|
||||
)
|
||||
)
|
||||
.append(AdminConstants.MONGO_DB_KEY_LOGTIME, "$logTime")
|
||||
.append(AdminConstants.MONGO_DB_KEY_LOGMONTH,
|
||||
new Document("$substr" , List.of("$logTime", 0, 7)) //0000-00
|
||||
)
|
||||
.append(AdminConstants.MONGO_DB_KEY_LOGDAY,
|
||||
new Document("$substr" , List.of("$logTime", 0, 10)) //0000-00-00
|
||||
)
|
||||
.append(AdminConstants.MONGO_DB_KEY_LOGHOUR,
|
||||
new Document("$substr" , List.of("$logTime", 0, 13))
|
||||
)
|
||||
.append(AdminConstants.MONGO_DB_KEY_LOGMINUTE,
|
||||
new Document("$substr" , List.of("$logTime", 0, 16))
|
||||
)
|
||||
.append("message", "$message")
|
||||
);
|
||||
|
||||
return projectOperation2;
|
||||
}
|
||||
private AggregationOperation getDefaultProjectOperationName(){
|
||||
ProjectionOperation projectOperation = Aggregation.project()
|
||||
.and(AdminConstants.MONGO_DB_KEY_LOGTIME).as(AdminConstants.MONGO_DB_KEY_LOGTIME)
|
||||
.and(AdminConstants.MONGO_DB_KEY_LOGMONTH).as(AdminConstants.MONGO_DB_KEY_LOGMONTH)
|
||||
.and(AdminConstants.MONGO_DB_KEY_LOGDAY).as(AdminConstants.MONGO_DB_KEY_LOGDAY)
|
||||
.and(AdminConstants.MONGO_DB_KEY_LOGHOUR).as(AdminConstants.MONGO_DB_KEY_LOGHOUR)
|
||||
.and(AdminConstants.MONGO_DB_KEY_LOGMINUTE).as(AdminConstants.MONGO_DB_KEY_LOGMINUTE)
|
||||
.and(AdminConstants.MONGO_DB_KEY_MESSAGE).as(AdminConstants.MONGO_DB_KEY_MESSAGE)
|
||||
.and(AdminConstants.MONGO_DB_KEY_LANGUAGE_TYPE).as(AdminConstants.MONGO_DB_KEY_LANGUAGE_TYPE)
|
||||
.and(AdminConstants.MONGO_DB_KEY_USER_GUID).as(AdminConstants.MONGO_DB_KEY_USER_GUID)
|
||||
.and(AdminConstants.MONGO_DB_KEY_USER_NICKNAME).as(AdminConstants.MONGO_DB_KEY_USER_NICKNAME)
|
||||
.and(AdminConstants.MONGO_DB_KEY_ACCOUNT_ID).as(AdminConstants.MONGO_DB_KEY_ACCOUNT_ID)
|
||||
.and(AdminConstants.MONGO_DB_KEY_LOGIN_TIME).as(AdminConstants.MONGO_DB_KEY_LOGIN_TIME)
|
||||
.and(AdminConstants.MONGO_DB_KEY_LOGOUT_TIME).as(AdminConstants.MONGO_DB_KEY_LOGOUT_TIME)
|
||||
.and(AdminConstants.MONGO_DB_KEY_TRAN_ID).as(AdminConstants.MONGO_DB_KEY_TRAN_ID)
|
||||
.and(AdminConstants.MONGO_DB_KEY_ACTION).as(AdminConstants.MONGO_DB_KEY_ACTION)
|
||||
.and(AdminConstants.MONGO_DB_KEY_DOMAIN).as(AdminConstants.MONGO_DB_KEY_DOMAIN)
|
||||
.and(AdminConstants.MONGO_DB_KEY_SERVER_TYPE).as(AdminConstants.MONGO_DB_KEY_SERVER_TYPE)
|
||||
.and("message").as("message")
|
||||
;
|
||||
return projectOperation;
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected List<AggregationOperation> setDefaultOperation(Criteria criteria){
|
||||
|
||||
List<AggregationOperation> operations = new ArrayList<>();
|
||||
|
||||
operations.add(Aggregation.match(criteria));
|
||||
operations.add(getDefaultProjectOperationRegex());
|
||||
operations.add(getDefaultProjectOperationCapture());
|
||||
operations.add(getDefaultProjectOperationName());
|
||||
|
||||
return operations;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user