buckets; @Value("${common.service.sla.db}") private String SL"> buckets; @Value("${common.service.sla.db}") private String SL"> buckets; @Value("${common.service.sla.db}") private String SL">
public class ServiceFactory implements InitializingBean {
public static Map<String, AdmSvcDply> jwtMap;
private static Map<String, AdmSvcDply> basicMap;
private static Map<String, AdmSvcDply> apiKeyMap;
private static Map<String, AdmSvcDply> mtlsMap;
private static Map<String, Set<String>> apiAutMap;
private static Map<String, Sla> slaMap;
private static Map<String, LocalBucket> bucketMap;
private static LocalDateTime lastModifiedDate = null;
private static Map<String, Map<String,String>> athnMap;
private static Map<String, Pattern> ipAlwIpMap;
private static Map<String, Pattern> ipBlkIpMap;
@Autowired
private PortalService portalService;
@Autowired
private AdmSvcService admSvcService;
private final String BASIC = "Basic";
private final String API_KEY = "ApiKey";
private final String JWT = "JWT";
private final String MTLS = "MTLS";
@Autowired(required = false)
private ProxyManager<String> buckets;
@Value("${common.service.sla.db}")
private String SLA_DB;
private final String LOCAL = "LOCAL";
private final String REDIS = "REDIS";
private final String MONGODB = "MONGODB";
@Scheduled(fixedDelayString = "${common.service.schedule.dbSync}", timeUnit = TimeUnit.SECONDS)
public void synchronizeDB() {
List<AdmSvcDply> dbSvcList = null;
// 마지막 동기화 시점 시간을 비교하여 데이터 동기화 처리
LocalDateTime nowTime = LocalDateTime.now();
if (lastModifiedDate == null) {
dbSvcList = admSvcService.getAdmSvcList("DPLY");
} else {
dbSvcList = admSvcService.getAdmSvcList(lastModifiedDate);
}
if(dbSvcList != null && dbSvcList.size() > 0) {
// System 정보를 ENTITY MAP에 현행화
for (AdmSvcDply admSvc : dbSvcList) {
if("DPLY".equals(admSvc.getDplyType())){
if (BASIC.equals(admSvc.getAthnType())) insertBasicMap(admSvc);
else if(JWT.equals(admSvc.getAthnType())) insertJwtMap(admSvc);
else if(API_KEY.equals(admSvc.getAthnType())) insertApiKeyMap(admSvc);
else if(MTLS.equals(admSvc.getAthnType())) insertMTLSMap(admSvc);
insertApiAutMap(admSvc);
insertBucketMap(admSvc);
insertIpAcesAutMap(admSvc);
log.info("ServiceFactory.synchronizeDB - Load : " + admSvc.toString());
}else{
String svcId = admSvc.getSvcId();
if(athnMap.containsKey(svcId)){
if (admSvc.getAthnType().equals(BASIC)) {
basicMap.remove(athnMap.get(svcId).get(BASIC));
}
else if(admSvc.getAthnType().equals(JWT)){
jwtMap.remove(athnMap.get(svcId).get(JWT));
}
else if(admSvc.getAthnType().equals(API_KEY)) {
apiKeyMap.remove(athnMap.get(svcId).get(API_KEY));
}else if(admSvc.getAthnType().equals(MTLS)) {
mtlsMap.remove(athnMap.get(svcId).get(MTLS));
}
}
athnMap.remove(svcId);
apiAutMap.remove(svcId);
if(slaMap.containsKey(svcId)){
slaMap.remove(svcId);
if(SLA_DB.equals(REDIS)){
buckets.removeProxy(svcId);
}
}
if(bucketMap.containsKey(svcId)){
bucketMap.remove(svcId);
}
if(ipAlwIpMap.containsKey(svcId)){
ipAlwIpMap.remove(svcId);
}
if(ipBlkIpMap.containsKey(svcId)){
ipBlkIpMap.remove(svcId);
}
log.info("ServiceFactory.synchronizeDB - Remove : " + admSvc.toString());
}
// // 마지막 동기화 시간 현행화
// if (lastModifiedDate == null || (admSvc.getDplyDt() != null && admSvc.getDplyDt().isAfter(lastModifiedDate))) {
// lastModifiedDate = nowTime;
// }
}
// 마지막 동기화 시간 현행화
AdmSvcDply lastSvc = dbSvcList.stream().max((o1, o2) -> o1.getDplyDt().compareTo(o2.getDplyDt())).get();
lastModifiedDate = lastSvc.getDplyDt();
}
}
@Override
public void afterPropertiesSet() throws InternalException {
log.info("ServiceFactory.afterPropertiesSet - Start");
basicMap = new ConcurrentHashMap<String, AdmSvcDply>();
jwtMap = new ConcurrentHashMap<String, AdmSvcDply>();
apiKeyMap = new ConcurrentHashMap<String, AdmSvcDply>();
mtlsMap = new ConcurrentHashMap<String, AdmSvcDply>();
apiAutMap = new ConcurrentHashMap<String, Set<String>>();
athnMap = new ConcurrentHashMap<String, Map<String,String>>();
slaMap = new ConcurrentHashMap<String, Sla>();
bucketMap = new ConcurrentHashMap<String, LocalBucket>();
ipAlwIpMap = new ConcurrentHashMap<String, Pattern>();
ipBlkIpMap = new ConcurrentHashMap<String, Pattern>();
List<AdmSvcDply> portalServiceList = portalService.getService();
for(AdmSvcDply portalSvc:portalServiceList){
if("DPLY".equals(portalSvc.getDplyType())){
if (BASIC.equals(portalSvc.getAthnType())) insertBasicMap(portalSvc);
else if(JWT.equals(portalSvc.getAthnType())) insertJwtMap(portalSvc);
else if(API_KEY.equals(portalSvc.getAthnType())) insertApiKeyMap(portalSvc);
else if(MTLS.equals(portalSvc.getAthnType())) insertMTLSMap(portalSvc);
insertApiAutMap(portalSvc);
insertBucketMap(portalSvc);
insertIpAcesAutMap(portalSvc);
if(portalSvc.getSvcStDt()==null){
portalSvc.setSvcStDt(LocalDateTime.MIN);
}
if(portalSvc.getSvcEndDt()==null){
portalSvc.setSvcEndDt(LocalDateTime.MAX);
}
log.info("Portal Service synchronization : " + portalSvc.toString());
}
}
synchronizeDB();
log.info("ServiceFactory.afterPropertiesSet - End");
}
}
public static AdmSvcDply getBasic(String key) { return basicMap.get(key); }
public static AdmSvcDply getJwt(String key) { return jwtMap.get(key); }
public static AdmSvcDply getApiKey(String key) { return apiKeyMap.get(key); }
public static AdmSvcDply getMTLS(String key) { return mtlsMap.get(key); }
public static Set<String> getApiAut(String key) { return apiAutMap.get(key); }
public static Sla getSla(String key) { return slaMap.get(key); }
public static Bucket getBucket(String key) { return bucketMap.get(key); }
public static Pattern getIpAlwRegEx(String key) { return ipAlwIpMap.get(key); }
public static Pattern getIpBlkRegEx(String key) { return ipBlkIpMap.get(key); }
private void insertApiAutMap(AdmSvcDply admSvc) {
String svcId = admSvc.getSvcId();
Set<String> apiAutSet = new HashSet<>();
for(String admApi : admSvc.getApiAut()){
apiAutSet.add(admApi);
}
apiAutMap.put(svcId, apiAutSet);
}
private void insertJwtMap(AdmSvcDply admSvc) {
// jwtMap = new ConcurrentHashMap<String, AdmSvcDply>();
Jwt jwt = admSvc.getAthn().getJwt();
String issAndAud = jwt.getIss().concat(".").concat(jwt.getAud());
removeExistedAthnData(admSvc,issAndAud);
jwtMap.put(issAndAud, admSvc);
athnMap.put(admSvc.getSvcId(), new HashMap<String, String>() {{put(admSvc.getAthnType(), issAndAud);}});
}
private void insertBasicMap(AdmSvcDply admSvc) {
String basicId = admSvc.getAthn().getBasic().getId();
String basicPw = admSvc.getAthn().getBasic().getPw();
String originalInput = basicId+":"+basicPw;
String encodedString = Base64.getEncoder().encodeToString(originalInput.getBytes()).replace("=","");
// admSvc.setLongSvcStDt(admSvc.getSvcStDt().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
// admSvc.setLongSvcEndDt(admSvc.getSvcEndDt().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
removeExistedAthnData(admSvc,encodedString);
basicMap.put(encodedString, admSvc);
athnMap.put(admSvc.getSvcId(), new HashMap<String,String>(){{put(admSvc.getAthnType(),encodedString);}});
}
private void insertMTLSMap(AdmSvcDply admSvc) {
String commNm = admSvc.getAthn().getMtls().getCn();
// String[] splitCN = commNm.split("=");
// String inputKey = (splitCN.length > 1)? splitCN[1] : commNm;
removeExistedAthnData(admSvc, commNm);
mtlsMap.put(commNm, admSvc);
athnMap.put(admSvc.getSvcId(), new HashMap<String, String>(){{put(admSvc.getAthnType(), commNm);}});
}
private void insertApiKeyMap(AdmSvcDply admSvc) {
String apiKey = admSvc.getAthn().getApiKey().getKey();
if(apiKey != null) {
// admSvc.setLongSvcStDt(admSvc.getSvcStDt().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
// admSvc.setLongSvcEndDt(admSvc.getSvcEndDt().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
removeExistedAthnData(admSvc,apiKey);
apiKeyMap.put(apiKey, admSvc);
athnMap.put(admSvc.getSvcId(), new HashMap<String,String>(){{put(admSvc.getAthnType(),apiKey);}});
}
}
private void insertIpAcesAutMap(AdmSvcDply admSvc) {
String svcId = admSvc.getSvcId();
if(admSvc.getIpAcesAut()!=null){
Pattern alwIpRegEx = convertRegExToIp(admSvc.getIpAcesAut().getAlwdIp());
Pattern blckIpRegEx = convertRegExToIp(admSvc.getIpAcesAut().getBlckIp());
ipAlwIpMap.put(svcId, alwIpRegEx);
ipBlkIpMap.put(svcId, blckIpRegEx);
}
}
private Pattern convertRegExToIp(List<String> ipList) {
List<Pattern> regExList = new ArrayList<>();
for(String ip : ipList) {
String[] ipSplit = ip.split("\\.");
StringBuilder regEx = new StringBuilder("^");
for(int i = 0; i<ipSplit.length; i++) {
String ipPart = ipSplit[i].trim().replace("[", "").replace("]", "");
if("*".equals(ipPart)) {
regEx.append("([1-9]?[0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])");
} else if(ipSplit[i].contains("~")) {
//범위 정규식 변환 처리
String[] ipPartSplit = ipPart.split("~");
int start = Integer.min(Integer.parseInt(ipPartSplit[0]), Integer.parseInt(ipPartSplit[1]));
int end = Integer.max(Integer.parseInt(ipPartSplit[0]), Integer.parseInt(ipPartSplit[1]));
int sQuot = Math.floorDiv(start,10);
int sRemain = Math.floorMod(start,10);
int eQuot = Math.floorDiv(end,10);
int eRemain = Math.floorMod(end,10);
regEx.append("(");
if(sQuot == eQuot) {
if(sQuot != 0) regEx.append(sQuot);
regEx.append("[").append(sRemain).append("-").append(eRemain).append("]");
} else {
if(sQuot != 0) regEx.append(sQuot);
regEx.append("[").append(sRemain).append("-9]|");
for(int num = sQuot+1; num<eQuot; num++) {
regEx.append(num).append("[0-9]|");
}
regEx.append(eQuot).append("[0-").append(eRemain).append("]");
}
regEx.append(")");
} else if(ipSplit[i].matches("^\\d*$")) {
regEx.append("(").append(Integer.parseInt(ipSplit[i])).append(")");
}
if(i < ipSplit.length-1) regEx.append("\\.");
}
regEx.append("$");
try {
Pattern pattern = Pattern.compile(regEx.toString());
regExList.add(pattern);
} catch(PatternSyntaxException e) {
log.info("RegEx Syntax Error");
}
}
Pattern totalRegEx = null;
StringBuilder totalregexStr = new StringBuilder();
if(!regExList.isEmpty()) {
for (Pattern patt : regExList) {
totalregexStr.append(patt).append("|");
}
totalregexStr.delete(totalregexStr.lastIndexOf("|"), totalregexStr.lastIndexOf("|") + 1);
totalRegEx = Pattern.compile(totalregexStr.toString());
return totalRegEx;
}
return Pattern.compile("");
}
private void removeExistedAthnData(AdmSvcDply admSvc,String key) {
String svcId = admSvc.getSvcId();
if(athnMap.containsKey(svcId)){
String apiKey = athnMap.get(svcId).get(API_KEY);
String jwt = athnMap.get(svcId).get(JWT);
String basic = athnMap.get(svcId).get(BASIC);
if(BASIC.equals(admSvc.getAthnType())){
if(StringUtils.hasText(apiKey)){
apiKeyMap.remove(apiKey);
}else if(StringUtils.hasText(jwt)){
jwtMap.remove(jwt);
}
if(StringUtils.hasText(basic)){
if(!key.equals(basic)){
basicMap.remove(basic);
}
}
}
else if(API_KEY.equals(admSvc.getAthnType())){
if(StringUtils.hasText(basic)){
basicMap.remove(basic);
} else if(StringUtils.hasText(jwt)){
jwtMap.remove(jwt);
}
if(StringUtils.hasText(apiKey)){
if(!key.equals(apiKey)){
apiKeyMap.remove(apiKey);
}
}
}
else if(JWT.equals(admSvc.getAthnType())) {
if(StringUtils.hasText(apiKey)){
apiKeyMap.remove(apiKey);
} else if(StringUtils.hasText(basic)) {
basicMap.remove(basic);
}
if(StringUtils.hasText(jwt)){
if(!key.equals(jwt)){
jwtMap.remove(jwt);
}
}
}
athnMap.remove(svcId);
}
}
private void insertBucketMap(AdmSvcDply admSvc) {
Sla sla = admSvc.getSla();
String svcId = admSvc.getSvcId();
Sla lastSla = slaMap.get(svcId);
if(sla!=null && !sla.isEmpty()){
// sla 정책 변동 여부 확인 : 변동이 있으면 변경해서 적용, 변동 x -> skip
if(sla.equals(lastSla)){
return;
}
if(SLA_DB.equals(LOCAL)){
List<Bandwidth> bandwidths = sla.extractBandwidth(1);
BucketConfiguration bucketConfiguration = new BucketConfiguration(bandwidths);
LocalBucket bucket = Bucket.builder().addLimit(Bandwidth.simple(1000000, Duration.ofSeconds(1))).build();
bucket.replaceConfiguration(bucketConfiguration, TokensInheritanceStrategy.RESET);
bucketMap.put(svcId, bucket);
}
slaMap.put(svcId, sla);
log.info("ServiceFactory.insertBucketMap - Load bucket : " + sla.toString());
}else{
// sla 정책이 없어질 시 map 에서 제거
if(lastSla!=null){
slaMap.remove(svcId);
if(SLA_DB.equals(REDIS)){
buckets.removeProxy(svcId);
}
if(SLA_DB.equals(LOCAL)){
bucketMap.remove(svcId);
}
log.info("ServiceFactory.insertBucketMap - remove bucket : " + lastSla.toString());
}
}
}
@ReadOperation
public Map<String, Object> serviceFeatures() {
Map<String, Object> serviceInfoMap = new HashMap<>();
serviceInfoMap.put("jwtMap", jwtMap);
serviceInfoMap.put("basicMap", basicMap);
serviceInfoMap.put("apiKeyMap", apiKeyMap);
serviceInfoMap.put("apiAutMap", apiAutMap);
serviceInfoMap.put("slaMap", slaMap);
serviceInfoMap.put("ipAlwIpMap", ipAlwIpMap);
serviceInfoMap.put("ipBlkIpMap", ipBlkIpMap);
return serviceInfoMap;
}