filter(ServerWebExchange exchange, GatewayFilterChain chain) { long startTime = System.currentTimeMillis(); // 요청 헤더의 주요정보 추출"> filter(ServerWebExchange exchange, GatewayFilterChain chain) { long startTime = System.currentTimeMillis(); // 요청 헤더의 주요정보 추출"> filter(ServerWebExchange exchange, GatewayFilterChain chain) { long startTime = System.currentTimeMillis(); // 요청 헤더의 주요정보 추출">
@Component
@Slf4j
public class PreFilter implements GlobalFilter, Ordered, InitializingBean{
	@Value("${spring.application.name}")
	private String appName;

	private static String hostNm = null;
	private static String hostIp = null;

	@Autowired
	private ModifyRequestBodyGatewayFilterFactory modifyRequestBodyFilter;
	@Autowired
	private GetExchangeRequest getExchangeRequest;

//	@Autowired(required = false)
//	private LicenseCheck licenseCheck;

	@Value("${common.license.necessary}")
	private boolean lChknecessary;

	@Value("${common.header.txid}")
	private String txidForHeadNm;

	@Value("${common.header.clientip}")
	private String clientIpForHeadNm;

	@Override
	public void afterPropertiesSet() throws Exception {
		hostNm = InetAddress.getLocalHost().getHostName();
		hostIp = InetAddress.getLocalHost().getHostAddress();
	}

	@Override
	public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
		long startTime = System.currentTimeMillis();

		
		// 요청 헤더의 주요정보 추출
		String txId = getHeaderF(exchange.getRequest().getHeaders(), txidForHeadNm);
		String clientIp = getHeaderF(exchange.getRequest().getHeaders(), clientIpForHeadNm);

		if(!StringUtils.hasText(clientIp)){
			clientIp = exchange.getRequest().getRemoteAddress().getAddress().getHostAddress();
		}
		// TODO 실 Client IP 추출 로직으로 검증시 확인 필요
		// XForwardedRemoteAddressResolver resolver = XForwardedRemoteAddressResolver.maxTrustedIndex(1);
        // InetSocketAddress inetSocketAddress = resolver.resolve(exchange);
		// String clientIp = inetSocketAddress.getAddress().getHostAddress();

		// 트랜잭션 ID 추출 및 생성
		if(!StringUtils.hasText(txId)) {
			txId = UUID.randomUUID().toString();
		}
		
		// 쓰레드명을 Txid로 변경
		//Thread.currentThread().setName(txId);

		log.info("PreFilter.filter - Start");
		

		// 요청 정보 추출
		String reqMthd = exchange.getRequest().getMethod().name();
		String reqUri = exchange.getRequest().getURI().getPath();

		//COMPLETED: SI api 식별 방식을 해당 방식과 동일하게 적용해도 되는지 확인 필요
		// API 식별
//		AdmApiDply api = ApiFactory.getApi(reqMthd, reqUri);
		AdmApiDply api = null;
		if(exchange.getAttributes().containsKey("api")) {
			api = exchange.getAttribute("api");
		}

		// System 식별
		AdmSys system = null;
		Edpt systemEdpt = null;
		String out = null;
		if(api!=null){
			system = SystemFactory.getSystem(api.getSysId());
			if(system!=null){
				systemEdpt = system.getEdpt();
			}
			out = api.getOut();
		}
		
		// 트랜젝션 객체 생성
		TransactionDto transaction = TransactionDto.builder()
				.comn(ComnonDto.builder()
						.applId(appName)
						.hostNm(hostNm)
						.hostIp(hostIp)
						.txId(txId)
						.api(api!=null?AdmApiDply.copy(api):null)
						.build())
				.req(RequestDto.builder()
						.stTm(startTime)
						.svcIp(clientIp)
						.meth(reqMthd)
						.in(reqUri)
						.out(out)
						.edpt(systemEdpt)
						.build())
				.store(StoreDto.builder()
						.cstmLog(new HashMap<String, String>())
						.data(new HashMap<String, Object>())
						.build()
				)	
				.build();

		// 트랜젝션 객체 저장
		exchange.getAttributes().put(TransactionDto.TRANSACTION, transaction);

		//license check
		// if(lChknecessary){
		// 	if(!licenseCheck.isLicensed()){
		// 		transaction.setError(AgwErrorDto.UNAUTHORIZED);
		// 		return Mono.error(new AuthenticationException(AgwErrorDto.UNAUTHORIZED.getErrMsg()));
		// 	}
		// }

		log.info("PreFilter.filter - End");
		// 헤더 추출
		RequestMethod.extractHeaderAndQueryParams(exchange, transaction);
		if(api!=null){
			if(HandlerFactory.isHandlerGroupBodyRef(api.getReqHndlr())) {
				// ModifyRequestBodyGatewayFilterFactory를 사용하여 requestbody추출 -> transaction객체 저장
				return modifyRequestBodyFilter
						.apply(
								new ModifyRequestBodyGatewayFilterFactory.Config()
										.setRewriteFunction(byte[].class, byte[].class, getExchangeRequest)) // extractRequestBody -> extractRequest : header, body, querystring
						.filter(exchange, chain);

			}
		}

		log.info("Transaction : " + transaction.toString());
		return  chain.filter(exchange);
	}

	@Override
	public int getOrder() {
		return 1;
	}

	// 헤더 값 추출
	private String getHeaderF(HttpHeaders header, String key){
		if(header.containsKey(key)) {
			return header.getFirst(key);
		}
		return "";
	}

}