Typed 서킷브레이커 추가

This commit is contained in:
curry772
2026-03-30 15:57:26 +09:00
parent 16386d20ff
commit 1f24dc24b5
6 changed files with 779 additions and 0 deletions
@@ -0,0 +1,61 @@
package com.eactive.eai.agent.circuitBreaker.type;
import com.eactive.eai.agent.command.Command;
import com.eactive.eai.agent.command.CommandException;
import com.eactive.eai.common.util.Logger;
import com.eactive.eai.common.circuitBreaker.type.TypedCircuitBreakerManager;
public class ReloadTypedCircuitBreakerCommand extends Command {
private static final long serialVersionUID = 1L;
public ReloadTypedCircuitBreakerCommand() {
super("ReloadInflowInterfaceControlCommand");
}
public Object execute() throws CommandException {
Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
if (logger.isInfo()) {
logger.info(this.name + " is executed");
}
String keyName;
if (!(this.args instanceof String)) {
keyName = "RECEAIMCM001";
String msg = this.makeException(keyName, (Throwable) null);
if (logger.isError()) {
logger.error(msg);
}
throw new CommandException(msg);
} else {
keyName = (String) this.args;
try {
TypedCircuitBreakerManager manager = TypedCircuitBreakerManager.getInstance();
if (keyName != null) {
if ("ALL".equals(keyName)) {
manager.reload();
if (logger.isWarn()) {
logger.warn(this.name + "] all rule Reload.");
}
} else {
manager.reload(keyName);
if (logger.isWarn()) {
logger.warn(this.name + "] " + keyName + " Reload.");
}
}
}
return "success";
} catch (Exception var6) {
String rspErrorCode = "RECEAIMCM002";
String msg = this.makeException(rspErrorCode, var6);
if (logger.isError()) {
logger.error(msg, var6);
}
throw new CommandException(msg);
}
}
}
}
@@ -0,0 +1,66 @@
package com.eactive.eai.common.circuitBreaker.type;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.eactive.eai.common.circuitbreak.loader.CircuitBreakerConfigLoader;
import com.eactive.eai.common.dao.BaseDAO;
import com.eactive.eai.common.dao.DAOException;
import com.eactive.eai.common.exception.ExceptionUtil;
import com.eactive.eai.common.util.Logger;
import com.eactive.eai.data.entity.onl.circuitbreaker.CircuitBreakerConfig;
@Service
@Transactional
public class TypedCircuitBreakerDAO extends BaseDAO {
private static Logger logger;
@Autowired
private CircuitBreakerConfigLoader loader;
@Autowired
private TypedCircuitBreakerMapper mapper;
public List<TypedCircuitBreakerVO> getList() throws DAOException {
try {
Iterable<CircuitBreakerConfig> rows = this.loader.findAll();
List<TypedCircuitBreakerVO> result = new ArrayList<>();
logger.info("[ @@ Load UrlCircuitBreaker Configuration - starting >>>>>>>>>>>>>>>>> ]");
for ( CircuitBreakerConfig row : rows ) {
result.add(this.mapper.toVo(row));
}
logger.info("[>> Load UrlCircuitBreaker Configuration - ended ]");
return result;
} catch (Exception var5) {
throw new DAOException(ExceptionUtil.getErrorCode(var5, "RECEAICMM101"));
}
}
public TypedCircuitBreakerVO get(String key) throws DAOException {
TypedCircuitBreakerVO var3;
try {
logger.info("[ @@ Load UrlCircuitBreaker Configuration - starting >>>>>>>>>>>>>>>>> " + key + "]");
Optional<CircuitBreakerConfig> optionalRow = this.loader.findById(key);
if (!optionalRow.isPresent()) {
var3 = null;
return var3;
}
var3 = this.mapper.toVo((CircuitBreakerConfig) optionalRow.get());
} catch (Exception var7) {
throw new DAOException(ExceptionUtil.getErrorCode(var7, "RECEAICMM101"));
} finally {
logger.info("[>> Load UrlCircuitBreaker Configuration - ended " + key + "]");
}
return var3;
}
static {
logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
}
}
@@ -0,0 +1,562 @@
package com.eactive.eai.common.circuitBreaker.type;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.eactive.eai.common.exception.ExceptionUtil;
import com.eactive.eai.common.lifecycle.Lifecycle;
import com.eactive.eai.common.lifecycle.LifecycleException;
import com.eactive.eai.common.lifecycle.LifecycleListener;
import com.eactive.eai.common.lifecycle.LifecycleSupport;
import com.eactive.eai.common.property.PropManager;
import com.eactive.eai.common.util.ApplicationContextProvider;
import com.eactive.eai.common.util.Logger;
import com.eactive.eai.custom.alarm.AlarmStateManager;
import com.eactive.eai.custom.alarm.condition.AlarmCondition;
import com.eactive.eai.custom.alarm.event.AlarmEvent;
import com.eactive.eai.custom.alarm.key.CoreAlarmKey;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.github.resilience4j.circuitbreaker.CircuitBreaker;
import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig;
import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig.SlidingWindowType;
import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry;
import io.github.resilience4j.circuitbreaker.event.CircuitBreakerEvent;
import io.github.resilience4j.circuitbreaker.event.CircuitBreakerOnStateTransitionEvent;
import io.github.resilience4j.core.EventConsumer;
import io.github.resilience4j.micrometer.tagged.TaggedCircuitBreakerMetrics;
import io.micrometer.prometheus.PrometheusConfig;
import io.micrometer.prometheus.PrometheusMeterRegistry;
import io.vavr.collection.Seq;
@Component
public class TypedCircuitBreakerManager implements Lifecycle {
static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
private static final String DEFAULT_CIRCUITBREAKER_NAME = "default";
PrometheusMeterRegistry meterRegistry;
CircuitBreakerRegistry circuitBreakerRegistry;
TypedCircuitBreakerVO defaultConfigVo;
HashMap<String, TypedCircuitBreakerVO> apiIdCBConfigMap = new HashMap<>();
HashMap<String, TypedCircuitBreakerVO> urlCBConfigMap = new HashMap<>();
private boolean started;
@Autowired
private TypedCircuitBreakerDAO dao;
private LifecycleSupport lifecycle = new LifecycleSupport(this);
public static synchronized TypedCircuitBreakerManager getInstance() {
return (TypedCircuitBreakerManager) ApplicationContextProvider.getContext()
.getBean(TypedCircuitBreakerManager.class);
}
public void addLifecycleListener(LifecycleListener listener) {
this.lifecycle.addLifecycleListener(listener);
}
public LifecycleListener[] findLifecycleListeners() {
return this.lifecycle.findLifecycleListeners();
}
public void removeLifecycleListener(LifecycleListener listener) {
this.lifecycle.removeLifecycleListener(listener);
}
private void init() throws Exception {
this.meterRegistry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);
int failureRateThreshold = NumberUtils
.toInt(PropManager.getInstance().getProperty("CircuitBreaker", "failureRateThreshold"), 50);
int slidingWindowSize = NumberUtils
.toInt(PropManager.getInstance().getProperty("CircuitBreaker", "slidingWindowSize"), 100);
int minimumNumberOfCalls = NumberUtils
.toInt(PropManager.getInstance().getProperty("CircuitBreaker", "minimumNumberOfCalls"), 100);
int waitDurationInOpenState = NumberUtils
.toInt(PropManager.getInstance().getProperty("CircuitBreaker", "waitDurationInOpenState"), 60);
int permittedNumberOfCallsInHalfOpenState = NumberUtils.toInt(
PropManager.getInstance().getProperty("CircuitBreaker", "permittedNumberOfCallsInHalfOpenState"), 10);
int slowCallRateThreshold = NumberUtils
.toInt(PropManager.getInstance().getProperty("CircuitBreaker", "slowCallRateThreshold"), 100);
int slowCallDurationThreshold = NumberUtils
.toInt(PropManager.getInstance().getProperty("CircuitBreaker", "slowCallDurationThreshold"), 5);
String useYn = PropManager.getInstance().getProperty("CircuitBreaker", "useYn", "N");
useYn = normalizeUseYn(useYn);
CircuitBreakerConfig defaultConfig = CircuitBreakerConfig.custom()
.failureRateThreshold((float) failureRateThreshold).slidingWindowSize(slidingWindowSize)
.minimumNumberOfCalls(minimumNumberOfCalls)
.waitDurationInOpenState(Duration.ofSeconds((long) waitDurationInOpenState))
.permittedNumberOfCallsInHalfOpenState(permittedNumberOfCallsInHalfOpenState)
.slidingWindowType(SlidingWindowType.COUNT_BASED).slowCallRateThreshold((float) slowCallRateThreshold)
.slowCallDurationThreshold(Duration.ofSeconds((long) slowCallDurationThreshold)).build();
this.defaultConfigVo = TypedCircuitBreakerVO.builder().name(DEFAULT_CIRCUITBREAKER_NAME).failureRateThreshold(failureRateThreshold)
.slidingWindowSize(slidingWindowSize).minimumNumberOfCalls(minimumNumberOfCalls)
.waitDurationInOpenState(waitDurationInOpenState)
.permittedNumberOfCallsInHalfOpenState(permittedNumberOfCallsInHalfOpenState)
.slowCallRateThreshold(slowCallRateThreshold).slowCallDurationThreshold(slowCallDurationThreshold)
.useYn(useYn).circuitBreakerConfig(defaultConfig).build();
this.circuitBreakerRegistry = CircuitBreakerRegistry.of(defaultConfig);
CircuitBreakerConfig defaultCircuitBreakerConfig = this.createCircuitBreakerConfig(this.defaultConfigVo);
this.defaultConfigVo.setCircuitBreakerConfig(defaultCircuitBreakerConfig);
this.apiIdCBConfigMap.put(DEFAULT_CIRCUITBREAKER_NAME, this.defaultConfigVo);
List<TypedCircuitBreakerVO> circuitBreakerList = this.dao.getList();
for (TypedCircuitBreakerVO vo : circuitBreakerList) {
if (!StringUtils.equalsIgnoreCase(vo.useYn, "1")) {
this.apiIdCBConfigMap.remove(vo.getName());
logger.info("init skip (useYn) - " + vo);
} else {
CircuitBreakerConfig circuitBreakerConfig = this.createCircuitBreakerConfig(vo);
vo.setCircuitBreakerConfig(circuitBreakerConfig);
this.apiIdCBConfigMap.put(vo.getName(), vo);
}
}
logger.info("init map - " + this.apiIdCBConfigMap);
TaggedCircuitBreakerMetrics.ofCircuitBreakerRegistry(this.circuitBreakerRegistry).bindTo(this.meterRegistry);
logger.info("init default - " + this.defaultConfigVo);
for (TypedCircuitBreakerVO vo : circuitBreakerList) {
CircuitBreaker cbreaker = this.getCircuitBreaker(vo.getName());
this.printCircuitBreakerInfo(vo.getName(), cbreaker);
}
CircuitBreaker cbreaker = this.getCircuitBreaker(DEFAULT_CIRCUITBREAKER_NAME);
this.printCircuitBreakerInfo(DEFAULT_CIRCUITBREAKER_NAME, cbreaker);
this.addListenerAll();
}
private String normalizeUseYn(String useYn) {
if(StringUtils.equalsAnyIgnoreCase(useYn, "Y", "1"))
useYn = "1";//사용
else
useYn = "0";
return useYn;
}
private CircuitBreakerConfig createCircuitBreakerConfig(TypedCircuitBreakerVO vo) {
return CircuitBreakerConfig.custom().failureRateThreshold((float) vo.failureRateThreshold)
.slidingWindowSize(vo.slidingWindowSize).minimumNumberOfCalls(vo.minimumNumberOfCalls)
.waitDurationInOpenState(Duration.ofSeconds((long) vo.waitDurationInOpenState))
.permittedNumberOfCallsInHalfOpenState(vo.permittedNumberOfCallsInHalfOpenState)
.slidingWindowType(SlidingWindowType.COUNT_BASED)
.slowCallRateThreshold((float) vo.slowCallRateThreshold)
.slowCallDurationThreshold(Duration.ofSeconds((long) vo.slowCallDurationThreshold)).build();
}
public void reload() throws Exception {
this.init();
}
@SuppressWarnings("deprecation")
public void reload(String key) throws Exception {
logger.info("reload start.");
TypedCircuitBreakerVO vo = this.dao.get(key);
if (StringUtils.equalsIgnoreCase(vo.useYn, "0")) {
this.apiIdCBConfigMap.remove(vo.getName());
this.circuitBreakerRegistry.remove(vo.getName());
logger.info("removed. - " + vo);
} else {
CircuitBreakerConfig circuitBreakerConfig = this.createCircuitBreakerConfig(vo);
vo.setCircuitBreakerConfig(circuitBreakerConfig);
this.apiIdCBConfigMap.put(vo.getName(), vo);
CircuitBreaker oldBreaker = this.circuitBreakerRegistry.circuitBreaker(vo.getName());
if(oldBreaker != null)
logger.info("oldBreaker={}, waitDurationInOpenState={}", new Object[]{oldBreaker.getCircuitBreakerConfig(),
oldBreaker.getCircuitBreakerConfig().getWaitDurationInOpenState()});
this.circuitBreakerRegistry.remove(vo.getName());
this.circuitBreakerRegistry.circuitBreaker(vo.getName(), vo.getCircuitBreakerConfig());
this.addListener(vo.getName());
CircuitBreaker newBreaker = this.circuitBreakerRegistry.circuitBreaker(vo.getName());
logger.info("newBreaker={}, waitDurationInOpenState={}", new Object[]{newBreaker.getCircuitBreakerConfig(),
newBreaker.getCircuitBreakerConfig().getWaitDurationInOpenState()});
logger.info("reload end." + vo);
}
}
public PrometheusMeterRegistry getMeterRegistry() {
return this.meterRegistry;
}
public void start() throws LifecycleException {
this.lifecycle.fireLifecycleEvent("starting", this);
try {
this.init();
} catch (Exception var2) {
throw new LifecycleException(ExceptionUtil.getErrorCode(var2, "RECEAICMM202"));
}
this.started = true;
this.lifecycle.fireLifecycleEvent("started", this);
}
public void stop() throws LifecycleException {
if (!this.started) {
throw new LifecycleException("RECEAICRT203");
} else {
this.lifecycle.fireLifecycleEvent("stoping", this);
this.started = false;
this.circuitBreakerRegistry = null;
this.lifecycle.fireLifecycleEvent("stopped", this);
}
}
public boolean isStarted() {
return this.started;
}
public CircuitBreaker getCircuitBreaker(String apiId) {
CircuitBreaker circuitBreaker = this.getCircuitBreakerInternal(apiId);
if (circuitBreaker != null) {
return circuitBreaker;
} else {
return this.getCircuitBreakerInternal(DEFAULT_CIRCUITBREAKER_NAME);
}
}
private CircuitBreaker getCircuitBreakerInternal(String url) {
TypedCircuitBreakerVO vo = (TypedCircuitBreakerVO) this.apiIdCBConfigMap.get(url);
if (vo == null) {
return null;
} else {
return StringUtils.equals(vo.getUseYn(), "0")
? null
: this.circuitBreakerRegistry.circuitBreaker(url, vo.getCircuitBreakerConfig());
}
}
// public CircuitBreaker getUrlCircuitBreaker(String url) {
// CircuitBreaker circuitBreaker = this.getUrlCircuitBreakerInternal(url);
// if (circuitBreaker != null) {
// return circuitBreaker;
// } else {
// URI uri = null;
//
// try {
// uri = URLUtils.createURI(url);
// } catch (Exception var6) {
// logger.error("malformed url : " + url);
// return null;
// }
//
// String tmpUrl = URLUtils.getURLWithoutQuery(uri);
// circuitBreaker = this.getUrlCircuitBreakerInternal(tmpUrl);
// if (circuitBreaker != null) {
// return circuitBreaker;
// } else {
// String host = URLUtils.getHost(uri);
// circuitBreaker = this.getUrlCircuitBreakerInternal(host);
// return circuitBreaker != null ? circuitBreaker : this.getUrlCircuitBreakerInternal(DEFAULT_CIRCUITBREAKER_NAME);
// }
// }
// }
//
// private CircuitBreaker getUrlCircuitBreakerInternal(String url) {
// TypedCircuitBreakerVO vo = (TypedCircuitBreakerVO) this.urlCBConfigMap.get(url);
// if (vo == null) {
// return null;
// } else {
// return StringUtils.equals(vo.getUseYn(), "0")
// ? null
// : this.circuitBreakerRegistry.circuitBreaker(url, vo.getCircuitBreakerConfig());
// }
// }
public String printCircuitBreakerInfo(String prefix, CircuitBreaker circuitBreaker) {
if (circuitBreaker == null) {
logger.info("CircuitBreaker state : " + prefix + " - null");
return "null";
} else {
ObjectMapper objectMapper = new ObjectMapper();
ObjectNode combinedNode = objectMapper.createObjectNode();
combinedNode.put("state", circuitBreaker.getState().toString());
combinedNode.put("config", circuitBreaker.getCircuitBreakerConfig().toString());
combinedNode.set("metrics", objectMapper.valueToTree(circuitBreaker.getMetrics()));
logger.info("CircuitBreaker state : " + prefix + " - " + combinedNode.toString());
return combinedNode.toString();
}
}
public void addListenerAll() {
if (this.circuitBreakerRegistry != null) {
Seq<CircuitBreaker> circuitBreakers = this.circuitBreakerRegistry.getAllCircuitBreakers();
for (CircuitBreaker cBreaker : circuitBreakers) {
TypedCircuitBreakerVO vo = (TypedCircuitBreakerVO) this.apiIdCBConfigMap.get(cBreaker.getName());
cBreaker.getEventPublisher().onEvent(new CustomCircuitBreakerEventConsumer(vo));
logger.info("Added Listener.[{}]", new Object[]{cBreaker.getName()});
}
logger.info("Added all Listener.");
} else {
logger.error("CircuitBreakerRegistry not initialized.");
}
}
public void addListener(String cBreakerName) {
if (this.circuitBreakerRegistry != null) {
CircuitBreaker cBreaker = this.circuitBreakerRegistry.circuitBreaker(cBreakerName);
if (cBreaker != null) {
TypedCircuitBreakerVO vo = (TypedCircuitBreakerVO) this.apiIdCBConfigMap.get(cBreakerName);
cBreaker.getEventPublisher().onEvent(new CustomCircuitBreakerEventConsumer(vo));
logger.info("Added Listener.");
} else {
logger.error("CircuitBreaker[{}] not exist.", new Object[]{cBreakerName});
}
} else {
logger.error("CircuitBreakerRegistry not initialized.");
}
}
public static class CustomCircuitBreakerEventConsumer implements EventConsumer<CircuitBreakerEvent> {
TypedCircuitBreakerVO vo;
// private static final int MAX_THREADS = 5;
// private static final ExecutorService ALERT_EXECUTOR;
public CustomCircuitBreakerEventConsumer(TypedCircuitBreakerVO vo) {
this.vo = vo;
}
public void consumeEvent(CircuitBreakerEvent event) {
switch (event.getEventType()) {
case ERROR :
TypedCircuitBreakerManager.logger
.error("CirbuitBreaker ERROR event occurred. CircuitBreakerEvent={}" + event);
break;
case STATE_TRANSITION :
if (event instanceof CircuitBreakerOnStateTransitionEvent) {
CircuitBreakerOnStateTransitionEvent stateTransitionEvent = (CircuitBreakerOnStateTransitionEvent) event;
CircuitBreaker.StateTransition stateTransition = stateTransitionEvent.getStateTransition();
CircuitBreaker.State toState = stateTransition.getToState();
CircuitBreaker.State fromState = stateTransition.getFromState();
TypedCircuitBreakerManager.logger.error(
"CirbuitBreaker STATE_TRANSITION event occurred. {} : {} -> {}. CircuitBreakerEvent={}, UrlCircuitBreakerVO={}",
new Object[]{event.getCircuitBreakerName(), fromState, toState, event, this.vo});
// if (!toState.equals(State.OPEN) && !toState.equals(State.HALF_OPEN)
// && !toState.equals(State.CLOSED)) {
// TypedCircuitBreakerManager.logger.debug(
// "CirbuitBreaker STATE_TRANSITION event alert 대상 아님. CircuitBreakerEvent={}, UrlCircuitBreakerVO={}",
// new Object[]{event, this.vo});
// } else {
// this.sendAlert(stateTransitionEvent);
// }
AlarmEvent alarmEvent = AlarmEvent.builder().key(CoreAlarmKey.CircuitBreaker)
.condition(AlarmCondition.builder().build())
.message(String.format("CircuitBreaker state changed. apiId=%s, %s -> %s", event.getCircuitBreakerName(), fromState, toState))
.build();
AlarmStateManager.getAlarmStateManager().onEvnet(alarmEvent);
logger.warn("CircuitBreaker state changed. apiId={}, {} -> {}", event.getCircuitBreakerName(), fromState, toState);
} else {
TypedCircuitBreakerManager.logger.error(
"CirbuitBreaker STATE_TRANSITION event occurred. CircuitBreakerEvent={}, UrlCircuitBreakerVO={}",
new Object[]{event, this.vo});
}
break;
case NOT_PERMITTED :
TypedCircuitBreakerManager.logger
.warn("CirbuitBreaker NOT_PERMITTED event occurred. CircuitBreakerEvent={}" + event);
break;
default :
TypedCircuitBreakerManager.logger
.info("CirbuitBreaker event occurred. CircuitBreakerEvent={}" + event);
}
}
// private void sendAlert(final CircuitBreakerOnStateTransitionEvent event) {
// this.runAsync(new Runnable() {
// public void run() {
// try {
// String alertUrl = PropManager.getInstance().getProperty("CircuitBreaker", "alert.url");
// if (StringUtils.isEmpty(alertUrl)) {
// TypedCircuitBreakerManager.logger.warn("alert skip - alertUrl not set. - {}",
// new Object[]{event});
// return;
// }
//
// String sendEventType = PropManager.getInstance().getProperty("CircuitBreaker",
// "alert.message.send.event.type", "OPEN,HALF_OPEN,CLOSED");
// String[] sendEventTypeArr = sendEventType.split(",");
// CircuitBreaker.StateTransition stateTransition = event.getStateTransition();
// CircuitBreaker.State toState = stateTransition.getToState();
// boolean bSend = false;
// String[] var7 = sendEventTypeArr;
// int var8 = sendEventTypeArr.length;
//
// for (int var9 = 0; var9 < var8; ++var9) {
// String eventType = var7[var9];
// if (State.valueOf(eventType).equals(toState)) {
// bSend = true;
// break;
// }
// }
//
// if (bSend) {
// String json = CustomCircuitBreakerEventConsumer.this.createAlertMessage(event);
// TypedCircuitBreakerManager.logger.info("alert request - {}", new Object[]{json});
// String result = CustomCircuitBreakerEventConsumer.this.httpPost(alertUrl, json);
// TypedCircuitBreakerManager.logger.info("alert result - {}", new Object[]{result});
// } else {
// TypedCircuitBreakerManager.logger.info("alert 전송대상 아님 - {}", new Object[]{event});
// }
// } catch (Exception var11) {
// TypedCircuitBreakerManager.logger.error("alert 전송 처리 실패 - {}", event, var11);
// }
//
// }
// });
// }
//
// private void runAsync(Runnable task) {
// try {
// ALERT_EXECUTOR.execute(task);
// } catch (RejectedExecutionException var3) {
// TypedCircuitBreakerManager.logger.error("alert 작업 제출 중 예외", var3);
// }
//
// }
//
// private String createAlertMessage(CircuitBreakerOnStateTransitionEvent event) {
// String alertMessageTemplate = PropManager.getInstance().getProperty("CircuitBreaker",
// "alert.message.template", "CircuitBreaker({url},{desc}){from}->{to}");
// String alertMsg = alertMessageTemplate.replace("{url}", this.vo.getName());
// alertMsg = alertMsg.replace("{desc}", this.vo.getDesc() + "");
// CircuitBreaker.StateTransition stateTransition = event.getStateTransition();
// alertMsg = alertMsg.replace("{from}", stateTransition.getFromState() + "");
// alertMsg = alertMsg.replace("{to}", stateTransition.getToState() + "");
// JSONObject reqJson = new JSONObject();
// reqJson.put("alertType", "C");
// reqJson.put("alertMsg", alertMsg);
// return reqJson.toJSONString();
// }
//
// private String httpPost(String url, String json) {
// String resultMsg = "";
// StringBuilder result = new StringBuilder();
//
// try {
// URL urlObject = new URL(url);
// HttpURLConnection conn = (HttpURLConnection) urlObject.openConnection();
// conn.setDoOutput(true);
// conn.setDoInput(true);
// conn.setRequestProperty("Content-Type", "application/json");
// conn.setRequestMethod("POST");
// OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
// Throwable var8 = null;
//
// try {
// if (StringUtils.isNotEmpty(json)) {
// wr.write(json.toString());
// wr.flush();
// }
// } catch (Throwable var55) {
// var8 = var55;
// throw var55;
// } finally {
// if (wr != null) {
// if (var8 != null) {
// try {
// wr.close();
// } catch (Throwable var54) {
// var8.addSuppressed(var54);
// }
// } else {
// wr.close();
// }
// }
//
// }
//
// int resStatusCode = conn.getResponseCode();
// Throwable var9;
// String line;
// BufferedReader normalBr;
// if (resStatusCode != 201 && resStatusCode != 200) {
// TypedCircuitBreakerManager.logger.debug("httpPost call response http code : {}" + resStatusCode);
// TypedCircuitBreakerManager.logger
// .debug("httpPost call response errror message : {}" + conn.getResponseMessage());
// normalBr = new BufferedReader(new InputStreamReader(conn.getErrorStream(), "utf-8"));
// var9 = null;
//
// try {
// line = "";
//
// while ((line = normalBr.readLine()) != null) {
// result.append(line);
// }
// } catch (Throwable var58) {
// var9 = var58;
// throw var58;
// } finally {
// if (normalBr != null) {
// if (var9 != null) {
// try {
// normalBr.close();
// } catch (Throwable var53) {
// var9.addSuppressed(var53);
// }
// } else {
// normalBr.close();
// }
// }
//
// }
// }
//
// normalBr = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
// var9 = null;
//
// try {
// line = "";
//
// while ((line = normalBr.readLine()) != null) {
// result.append(line);
// }
// } catch (Throwable var56) {
// var9 = var56;
// throw var56;
// } finally {
// if (normalBr != null) {
// if (var9 != null) {
// try {
// normalBr.close();
// } catch (Throwable var52) {
// var9.addSuppressed(var52);
// }
// } else {
// normalBr.close();
// }
// }
//
// }
//
// resultMsg = result.toString();
// } catch (Exception var61) {
// TypedCircuitBreakerManager.logger.error("url : para data => {} : {}" + url + " : " + json);
// TypedCircuitBreakerManager.logger.error("http client error : {}" + var61.getMessage(), var61);
// resultMsg = result.toString();
// }
//
// return resultMsg;
// }
//
// static {
// ALERT_EXECUTOR = new ThreadPoolExecutor(5, 5, 0L, TimeUnit.MICROSECONDS, new SynchronousQueue(),
// Executors.defaultThreadFactory(), new RejectedExecutionHandler() {
// public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
// TypedCircuitBreakerManager.logger.error("alert 작업 거부됨. 쓰레드 모두 사용중입니다.");
// }
// });
// }
}
}
@@ -0,0 +1,22 @@
package com.eactive.eai.common.circuitBreaker.type;
import com.eactive.eai.data.entity.onl.circuitbreaker.CircuitBreakerConfig;
import com.eactive.eai.data.mapper.GenericMapper;
import org.mapstruct.InheritInverseConfiguration;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.ReportingPolicy;
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface TypedCircuitBreakerMapper extends GenericMapper<TypedCircuitBreakerVO, CircuitBreakerConfig> {
@Mappings({
@Mapping(source = "cbreakerName", target = "name"),
@Mapping(source = "cbreakerDesc", target = "desc"),
@Mapping(source = "cbreakerType", target = "type"),
})
TypedCircuitBreakerVO toVo(CircuitBreakerConfig var1);
@InheritInverseConfiguration
CircuitBreakerConfig toEntity(TypedCircuitBreakerVO var1);
}
@@ -0,0 +1,22 @@
package com.eactive.eai.common.circuitBreaker.type;
import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class TypedCircuitBreakerVO {
String type;
String name;
String desc;
int failureRateThreshold;
int slidingWindowSize;
int minimumNumberOfCalls;
int waitDurationInOpenState;
int permittedNumberOfCallsInHalfOpenState;
int slowCallRateThreshold;
int slowCallDurationThreshold;
String useYn;
CircuitBreakerConfig circuitBreakerConfig;
}
@@ -0,0 +1,46 @@
package com.eactive.eai.common.circuitBreaker.type;
import java.net.URI;
public class URLUtils {
public static URI createURI(String uri) {
return URI.create(uri);
}
public static String getURLWithoutQuery(URI uri) {
String result = uri.getScheme() + "://" + uri.getHost();
if (uri.getPort() != -1) {
result = result + ":" + uri.getPort();
}
result = result + uri.getPath();
return result;
}
public static String getHost(URI uri) {
return uri.getHost();
}
public static void main(String[] args) throws Exception {
URI uri = URI.create("http://localhost:8001/path?query=a");
System.out.println(uri.getHost());
System.out.println(uri.getPath());
System.out.println(uri.toString());
System.out.println(uri.getRawPath());
System.out.println(uri.toURL());
System.out.println(getURLWithoutQuery(uri));
System.out.println(getHost(uri));
uri = URI.create("http://localhost/path?query=a");
System.out.println(getURLWithoutQuery(uri));
System.out.println(getHost(uri));
uri = URI.create("http://localhost/path?query=a");
System.out.println(getURLWithoutQuery(uri));
System.out.println(getHost(uri));
uri = URI.create("http://127.0.0.1/path?query=a");
System.out.println(getURLWithoutQuery(uri));
System.out.println(getHost(uri));
uri = URI.create("http://www.example.com:8080/test/path?query=a");
System.out.println(getURLWithoutQuery(uri));
System.out.println(getHost(uri));
}
}