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.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> idCBConfigMap = new HashMap<>();
	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());
				this.idCBConfigMap.remove(vo.getId());
				logger.info("init skip (useYn)  - " + vo);
			} else {
				CircuitBreakerConfig circuitBreakerConfig = this.createCircuitBreakerConfig(vo);
				vo.setCircuitBreakerConfig(circuitBreakerConfig);
				this.apiIdCBConfigMap.put(vo.getName(), vo);
				this.idCBConfigMap.put(vo.getId(), 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(vo == null) {
			vo = this.idCBConfigMap.get(key);
			if(vo != null) {
				this.idCBConfigMap.remove(key);
				this.apiIdCBConfigMap.remove(vo.getName());
				this.circuitBreakerRegistry.remove(vo.getName());
				logger.info("removed.  - " + vo);
			} else {
				logger.info("not exist in memory.  - " + key);
			}
		} else 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("CircuitBreaker 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(
								"CircuitBreaker 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);
	
						TypedCircuitBreakerManager.logger.warn("CircuitBreaker state changed. apiId={}, {} -> {}", event.getCircuitBreakerName(), fromState, toState);

					} else {
						TypedCircuitBreakerManager.logger.error(
								"CircuitBreaker 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 작업 거부됨. 쓰레드 모두 사용중입니다.");
//						}
//					});
//		}
	}
}