package com.eactive.eai.rms.ext.mmi;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.ServletInputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.View;

import com.eactive.eai.agent.command.CommonCommand;
import com.eactive.eai.common.util.NullControl;
import com.eactive.eai.common.util.SystemUtil;
import com.eactive.eai.rms.common.base.OnlBaseAnnotationController;
import com.eactive.eai.rms.common.context.MonitoringContext;
import com.eactive.eai.rms.common.datasource.DataSourceContextHolder;
import com.eactive.eai.rms.common.datasource.DataSourceType;
import com.eactive.eai.rms.common.datasource.DataSourceTypeManager;
import com.eactive.eai.rms.common.interceptor.InterceptorSkipController;
import com.eactive.eai.rms.common.logging.UserAccessLogger;
import com.eactive.eai.rms.common.mmilog.MMILogDao;
import com.eactive.eai.rms.common.util.StringUtils;
import com.eactive.eai.rms.onl.common.util.DateUtil;

@Controller
public class MMISyncController extends OnlBaseAnnotationController implements InterceptorSkipController {

    private static final Logger logger = Logger.getLogger(MMISyncController.class);

    @Autowired
    @Qualifier("mmiSyncService")
    private MMISyncService service;
    
    @Autowired
    private MonitoringContext monitoringContext;
    
    @Autowired
    @Qualifier("mmiLogDao")
    private MMILogDao mmiLogDao;

	

    /**
     * 통합인터페이스 시스템(MMI)에서 전문 레이아웃에 대한 INSERT, DELETE 요청
     * *
     * @param request
     * @param response
     * @param schema
     * @return
     * @throws Exception
     */
    @RequestMapping(value= "/mmiSync.file", method=RequestMethod.POST)
    public View parseMessage(HttpServletRequest request, HttpServletResponse response) throws Exception {
    	
        UserAccessLogger.log(request, "Message", "L", "cmd=Message");
		HashMap<String,String> map = new HashMap<String,String>();
		StringBuilder sb = new StringBuilder();
		StringBuilder frame = new StringBuilder();
		
		logger.debug("parseMessage content-Type="+request.getContentType());
		
		String mmiIfId       = "";
		String ver           = "";
		String eaiSvcName    = "";
		String eaiSevrDstcd  = "";
		String cnvsnNames    = "";
		String loutNames     = "";
		String userId        = "";
		
		HashMap<String,Object> mmiLogMap = new HashMap<String,Object>();
		StringBuffer buffer = new StringBuffer();
        try{
        	if (!SystemUtil.isDevServer()){
        		throw new Exception("개발 서버에서만 동작 합니다. ");
        	}
			for (String key : request.getParameterMap().keySet()){
				String [] datas= request.getParameterValues(key);
				StringBuffer resultS = new StringBuffer();
				for(String data : datas){
					resultS.append(data);
				}
				if (key.startsWith("E_") || key.startsWith("G_") || key.startsWith("FD") || key.startsWith("FM") ){
					buffer.append(resultS.toString()).append("\n");
				}
				if (key.startsWith("FM") ){
					cnvsnNames += ","+key;
				}
				if (key.startsWith("FD")){
					loutNames += ","+key;
				}
				
				logger.info("receive Data "+key+"="+resultS.toString());
				map.put(key, resultS.toString());
			}
		
			HashMap<String,Object> inter = null;
			HashMap<String,Object> info = null;
			
			
			for(String key : map.keySet()){
				if (key.startsWith("E_") || key.startsWith("G_")){
					info = MMIParser.parseInfo(map.get(key));
				}
			}
	        if (info == null){
	        	throw new Exception("인터페이스 정보가 존재하지 않습니다.");
	        }
			       eaiSvcName    = (String)info.get(MMIParserKey.EAI_SVC_NAME);//EAI서비스코드
			String eaiBzwkDstcd  = (String)info.get(MMIParserKey.APP_CD);  //EAI업무구분코드
			       eaiSevrDstcd  = (String)info.get(MMIParserKey.EAI_SYS_DSTCD); //EAI서버구분코드
			String interfaceType = (String)info.get(MMIParserKey.INTERFACE_TYPE); //인터페이스유형
			       mmiIfId       = (String)info.get(MMIParserKey.MMI_IF_ID); //
			       ver           = (String)info.get(MMIParserKey.VER); // 버전번호
			
			String srcSysId      = (String)info.get(MMIParserKey.SRC_SYS_ID); //소스 시스템ID
			String tgtSysId      = (String)info.get(MMIParserKey.TRG_SYS_ID); //타겟 시스템ID
			String resSrcSysId   = (String)info.get(MMIParserKey.RES_SRC_SYS_ID); //응답 소스 시스템ID
			
			String srcSysType    = (String)info.get(MMIParserKey.SRC_SYS_TYPE); //소스 시스템 type
			String tgtSysType    = (String)info.get(MMIParserKey.TRG_SYS_TYPE); //타겟 시스템 type
			
			       userId        = (String)info.get(MMIParserKey.DEPLOY_ID); //사용자ID
			String stdErrMpng    = (String)info.get(MMIParserKey.STD_ERR_MPNG); //표준 에러코드 사용여부
			
			///////////////////////////////////////////////
			//서버구분코드로 DataSourceType 변경
			// 1 : 내부(NSG) , 2 : 대외(DSG), 3 : 공동망(GSG), 4 : DMZ(ZSG), 5 : 오픈뱅킹(ASG)
			// 개발은 1,2,3 은 DSG 로  4는 ZSG로 처리 한다.
			///////////////////////////////////////////////
			String serverType = monitoringContext.getStringProperty(MonitoringContext.MMI_SYNC_SERVERTYPE, "1=DSG,2=DSG,3=DSG,4=ZSG,5=DSG");
			HashMap<String,String> serverDstcdMap = new HashMap<String,String>();
			Matcher matcher = Pattern.compile("[ ]*([0-9]+)[ ]*=[ ]*([A-Z]+)[ ]*").matcher(serverType);
			while(matcher.find()) {
			    String key = matcher.group(1).trim();
			    String value = matcher.group(2).trim();
			    serverDstcdMap.put(key, value);
			} 
			if (serverDstcdMap.containsKey(eaiSevrDstcd)){
				String dataSourceType = serverDstcdMap.get(eaiSevrDstcd);
				DataSourceContextHolder.setDataSourceType(DataSourceTypeManager.getDataSourceType(dataSourceType));
			}else{
				throw new Exception("지원 하지 않는 서버구분코드 입니다."+eaiSevrDstcd);
			}

			//interface 업무구분코드 valication
			boolean isApp = service.selecAppIsYn(new HashMap(){{put("eaiBzwkDstcd",eaiBzwkDstcd);}});
			if (!isApp){
				throw new Exception("인터페이스 에서 지원 하지 않는 APP CD 입니다." + eaiBzwkDstcd);
			}
			//변환 업무구분코드 validation
			String[] cnvsnNameList = cnvsnNames.split(",");
			for(String cnvsnName : cnvsnNameList){
				if (!StringUtils.isBlank(cnvsnName) && cnvsnName.length() > 5 ){
					String appcode = cnvsnName.substring(2,5);
					isApp = service.selecAppIsYn(new HashMap(){{put("eaiBzwkDstcd",appcode);}});
					if (!isApp){
						throw new Exception("변환 에서 지원 하지 않는 APP CD 입니다. " + appcode);
					}
					
				}
			}
			//layout 업무구분코드 validation
			String[] layoutNameList = loutNames.split(",");
			for(String layoutName : layoutNameList){
				if (!StringUtils.isBlank(layoutName) && layoutName.length() > 5 ){
					String appcode = layoutName.substring(2,5);
					isApp = service.selecAppIsYn(new HashMap(){{put("eaiBzwkDstcd",appcode);}});
					if (!isApp){
						throw new Exception("레이아웃 에서 지원 하지 않는 APP CD 입니다. " + appcode);
					}
				}
			}
			
			//adapter validation
			if ("A".equals(srcSysType) && "S".equals(tgtSysType) && "S".equals(interfaceType)){
				if (StringUtils.isEmpty(srcSysId)){
					throw new Exception("소스 어댑터를 선택하지 않았습니다.");
				}	
				if (StringUtils.isEmpty(tgtSysId)){
					throw new Exception("타겟 어댑터를 선택하지 않았습니다.");
				}
				if (StringUtils.isEmpty(resSrcSysId)){
					throw new Exception("소스 응답 어댑터를 선택하지 않았습니다.");
				}
			}else if ("A".equals(srcSysType) && "S".equals(tgtSysType) && "R".equals(interfaceType)){
				if (StringUtils.isEmpty(srcSysId)){
					throw new Exception("소스 어댑터를 선택하지 않았습니다.");
				}		
			}else{
				if (StringUtils.isEmpty(srcSysId)){
					throw new Exception("소스 어댑터를 선택하지 않았습니다.");
				}	
				if (StringUtils.isEmpty(tgtSysId)){
					throw new Exception("타겟 어댑터를 선택하지 않았습니다.");
				}
			}
			
			// adapter 파서 
			Map<String, Map<String, String>> adapters = service.selectAdapterForNickName(srcSysId,tgtSysId,resSrcSysId);
			String adptrMsgDstcd = adapters.get(MMIParserKey.SRC).get("ADPTRMSGDSTCD");
			// interface 파서 
			for(String key : map.keySet()){
				if (key.startsWith("E_") || key.startsWith("G_")){
					inter = MMIParser.parseInterface(map.get(key),adapters);
					logger.info("interface parsing " +inter);
				}
			}
			// layout 파서 
			List<HashMap<String,Object>> layouts = new ArrayList<HashMap<String,Object>>();
			for(String key : map.keySet()){
				if (key.startsWith("FD")){
					if (key.startsWith("FDEAI_") && key.endsWith("_ERR")){
						continue;
					}
					MMIParser.layoutDupValidation(map.get(key));
					HashMap<String,Object> layout = MMIParser.parseLayout(map.get(key),eaiSevrDstcd);
					layouts.add( layout);
					logger.info("layout parsing " + layout);
				}
			}
			//변환 파서
			List<HashMap<String,Object>> transforms = new ArrayList<HashMap<String,Object>>();
			for(String key : map.keySet()){
				if (key.startsWith("FM")){
					HashMap<String,Object> transform = MMIParser.parseTransform(map.get(key), eaiBzwkDstcd, eaiSevrDstcd);
					transforms.add( transform );
					logger.info("transform parsing " + transform);
				}
			}
			
			MMIParser.validation(srcSysType, tgtSysType, interfaceType,adapters, transforms, layouts, eaiSevrDstcd);
			
			
			// 변환 을 EAI서비스 코드에 셋팅하는 로직
			
			List<HashMap<String,Object>> he02s =  (List<HashMap<String,Object>>)inter.get("he02");
			if (he02s != null){
				HashMap<String,Object> he02 = (HashMap<String, Object>) he02s.get(0);
				if (he02 != null){
					//async-async 요청인데 RES로 되어 있는거 보강로직
					if ("A".equals(srcSysType) && "A".equals(tgtSysType) && transforms.size()==1) {
						String cnvsnName =(String)transforms.get(0).get("cnvsnName");
						he02.put("chngEonot"                , "1"        ); // 변환유무             
						he02.put("chngMsgIDName"            , cnvsnName  ); // 변환메시지ID명         
					}else{
						for(String key : map.keySet()){
							if (key.startsWith("FM")){
						        //data sample 변경
						        // FMEAI_TST0200100EAI_REQ
								String cnvsnName = "TRANSFORM_"+ key.substring(2);
								if (key.endsWith("_REQ")){
									he02.put("chngEonot"                , "1"        ); // 변환유무             
									he02.put("chngMsgIDName"            , cnvsnName  ); // 변환메시지ID명         
								}else if (key.endsWith("_RES")){
									if ("A".equals(srcSysType) && "A".equals(tgtSysType) && "R".equals(interfaceType)  ){//Async Async 패턴 응답이 경우
										he02.put("chngEonot"                , "1"        ); // 변환유무             
										he02.put("chngMsgIDName"            , cnvsnName  ); // 변환메시지ID명     								
									} else {
										he02.put("bascRspnsChngEonot"       , "1"        ); // 기본응답변환유무             
										he02.put("bascRspnsChngMsgIDName"   , cnvsnName  ); // 기본응답변환메시지ID명         
									}
								}else if (key.endsWith("_ERR")){
									he02.put("errRspnsChngEonot"        , "1"        ); // 오류응답변환유무   
									he02.put("errRspnsChngMsgIDName"    , cnvsnName  ); // 오류응답변환메시지ID명
								}
							}
						}
					}
					//표준에러매핑 관련
					if ("Y".equals(stdErrMpng)){
						
						//에러변환이 있는경우 표준에러 매핑을 셋팅할수 없음.
						if ("1".equals(he02.get("errRspnsChngEonot"))){
							throw new Exception("에러 변환을 셋팅한 상태에서는 표준 오류 매핑 사용을 Y 로 셋팅 할수 없습니다.");
						}
						if ("A".equals(srcSysType) && "S".equals(tgtSysType) && "R".equals(interfaceType)){
							throw new Exception("표준에러매핑을 셋팅할수 없는 패턴입니다. 거래패턴 :"+srcSysType +"-" +tgtSysType +" 송수신타입 : "+interfaceType );
						}
						String srcKesaUseYn = adapters.get(MMIParserKey.SRC).get("KESAUSEYN");
						String tgtKesaUseYn = adapters.get(MMIParserKey.TGT).get("KESAUSEYN");
						String srcMsgDstcd = adapters.get(MMIParserKey.SRC).get("ADPTRMSGDSTCD");
						String tgtMsgDstcd = adapters.get(MMIParserKey.TGT).get("ADPTRMSGDSTCD");
						if (!"0".equals(srcKesaUseYn) && !"0".equals(tgtKesaUseYn)){
							//Async - Async 응답에서만 셋팅
							//Sync  - Async 요청에서만셋팅
							//Sync  - Sync  요청만 있음 
							//Async - Sync  요청만 있음
							String cnvsnName = "";
							if ("A".equals(srcSysType) && "A".equals(tgtSysType) && "R".equals(interfaceType)){
								cnvsnName = "TRANSFORM_EAI_" + srcMsgDstcd +"TO" + tgtMsgDstcd + "_ERR";
								he02.put("errRspnsChngEonot"        , "1"        ); // 오류응답변환유무   
								he02.put("errRspnsChngMsgIDName"    , cnvsnName  ); // 오류응답변환메시지ID명
							}else if ("S".equals(srcSysType) && "A".equals(tgtSysType) && "S".equals(interfaceType)){
								cnvsnName = "TRANSFORM_EAI_" + tgtMsgDstcd +"TO" + srcMsgDstcd + "_ERR";
								he02.put("errRspnsChngEonot"        , "1"        ); // 오류응답변환유무   
								he02.put("errRspnsChngMsgIDName"    , cnvsnName  ); // 오류응답변환메시지ID명
							}else if ( "S".equals(tgtSysType) ){
								cnvsnName = "TRANSFORM_EAI_" + tgtMsgDstcd +"TO" + srcMsgDstcd + "_ERR";
								he02.put("errRspnsChngEonot"        , "1"        ); // 오류응답변환유무   
								he02.put("errRspnsChngMsgIDName"    , cnvsnName  ); // 오류응답변환메시지ID명
							}else{
								throw new Exception("표준에러매핑을 셋팅할수 없는 패턴입니다. 거래패턴 :"+srcSysType +"-" +tgtSysType +" 송수신타입 : "+interfaceType );
							}
						}else{
							throw new Exception("소스("+srcKesaUseYn+")와 타겟("+tgtKesaUseYn+")이 두개다 kesa가 아닐경우 표준 오류 매핑 사용을 Y 로 셋팅 할수 없습니다.");
						}
					
					}
				}
				logger.info("he02 setting " + he02);
			}
			///////////////////////
			// TR , AK
			//////////////////////
			List<HashMap<String,Object>> tracekeys = new ArrayList<HashMap<String,Object>>();
			
			// tr , ak  파서 
			List<String> parseKeys = new ArrayList<String>();
			for(String key : map.keySet()){
				if (key.startsWith("E_") || key.startsWith("G_")){
					parseKeys = MMIParser.parseKey(map.get(key));
					logger.info("tr ,ak  parsing " +parseKeys);
				}
			}
			//tr ,ak validation
			for(String parseKey : parseKeys){
				String[] keys = parseKey.split(",");
				String keyType = keys[0];
				String keyIndex = keys[1];
				String layoutFullPath = keys[2];
				String layout = layoutFullPath.split("\\.")[0];
				if (map.containsKey(layout)){
					if (MMIParser.parseKeyValidation(map.get(layout),layoutFullPath)){
						tracekeys.add(MMIParser.parseKey2(eaiSvcName, keyType, keyIndex, adptrMsgDstcd,layoutFullPath, eaiSevrDstcd));
					}else{
						throw new Exception("필드추출정보 혹은 로그조회키 의 Key 패스가 존재하지 않습니다."+layoutFullPath);
					}
				}else{
					throw new Exception("필드추출정보 혹은 로그조회키 의 Key 패스("+layoutFullPath+")가 사용하는 레이아웃이 존재하지 않습니다.전체 배포된  레이아웃("+loutNames+") 목록" );
					//tracekeys.add(MMIParser.parseKey2(eaiSvcName, keyType, keyIndex, adptrMsgDstcd,layoutFullPath, eaiSevrDstcd));
				}
			}
			//참조메시지에 대한 정의-20200527 jun's
			//1.변환매핑이 없고 로그키(필드추출정보)가 없을 경우 참조메시지ID를 셋팅한다.
			//2.저장시에도 아래의 조건 만족하는경우에만 DB에서 DELETE & INSERT 한다.
			//  => 조건이 안맞을시에는 ms02가 생성이 안되고 ASIS 마이그레이션 데이터가 있더라도 삭제 하지 않는다.
			if (transforms.size() == 0 && tracekeys.size() == 0 ){
				String refMessage ="";
				for(String key : map.keySet()){
					if (key.startsWith("FD")){
						refMessage = key;
						break;
					}
				}

				List<HashMap<String,Object>> ms02s =  new ArrayList<HashMap<String,Object>>();
				if (!StringUtils.isBlank(refMessage)){
					// interface 에 ms02 설정
					HashMap<String,Object> ms02 =  new HashMap<String,Object>();
					ms02.put("EAISVCNAME", eaiSvcName);
					ms02.put("SVCPRCSSNO", "1");
					ms02.put("REFMSGIDNO", "1");
					ms02.put("REFMSGIDNAME", refMessage.substring(2));
					ms02s.add(ms02);
				}
				inter.put("ms02", ms02s);	
				
			}

			// merge 로직 시작
			//boolean isMessageKeySame = service.transactionMMISync(inter, layouts, transforms, tracekeys, userId);  
			service.transactionMMISync(inter, layouts, transforms, tracekeys, userId); 
			
			CommonCommand command = null;
			
			//layout동기화
			for(HashMap<String,Object> layout : layouts){
				String loutName = (String) layout.get("loutName");
				command = new CommonCommand("com.eactive.eai.agent.transformer.ReloadLayoutCommand",loutName);
				if (!validate(agentUtilService.broadcast(command))){
					throw new Exception("레이아웃 동기화 오류 "+loutName);
				}
			}
			
			//변환등기화
			for(HashMap<String,Object> transform : transforms){
				String cnvsnName = (String)transform.get("cnvsnName");
				command = new CommonCommand("com.eactive.eai.agent.transformer.ReloadTransformCommand",cnvsnName);
				if (!validate(agentUtilService.broadcast(command))){
					throw new Exception("변환 동기화 오류 "+cnvsnName);
				}
			}
			
			//인터페이스 동기화
			if (!StringUtils.isEmpty(eaiSvcName)){
	    		command = new CommonCommand("com.eactive.eai.agent.eaimessage.ReloadEAIMessageCommand",eaiSvcName);
				if (!validate(agentUtilService.broadcast(command))){
					throw new Exception("인터페이스 동기화 오류 "+eaiSvcName);
				}
	    	}
			
			//추출키 동기화
			if (!StringUtils.isEmpty(eaiSvcName)){
				command = new CommonCommand("com.eactive.eai.agent.bizkey.ReloadBizKeyCommand",eaiSvcName+",TR");
				if (!validate(agentUtilService.broadcast(command))){
					throw new Exception("추출키 동기화 오류 "+eaiSvcName);
				} 
				command = new CommonCommand("com.eactive.eai.agent.bizkey.ReloadBizKeyCommand",eaiSvcName+",AK");
				if (!validate(agentUtilService.broadcast(command))){
					throw new Exception("추출키 동기화 오류 "+eaiSvcName);
				} 
				
			}
			//내부표준전문 동기화
			if (!StringUtils.isEmpty(eaiSvcName)){
				ArrayList<HashMap<String, Object>> hs04s = (ArrayList<HashMap<String, Object>>)inter.get("hs04");
		        if (hs04s != null){
		        	for(HashMap<String,Object> hs04 : hs04s){
		        		String bzwkSvcKeyName = (String)hs04.get("bzwkSvcKeyName");
		        		command = new CommonCommand("com.eactive.eai.agent.kbmessage.ReloadKBMessageCommand",bzwkSvcKeyName);
		        		if (!validate(agentUtilService.broadcast(command))){
		        			throw new Exception("내부표준전문 동기화 오류 "+bzwkSvcKeyName);
		        		} 
		        	}
		        }
			}
			//juns 어댑터 메시지키 동기화 삭제
//			//어댑터 메시지키 동기화
//			if (!isMessageKeySame){
//		        List<HashMap<String,Object>> fr04s = (List<HashMap<String,Object>>)inter.get("fr04");
//		        if (fr04s != null && fr04s.size()>0){
//	        		String adptrBzwkGroupName = (String)fr04s.get(0).get("adptrBzwkGroupName");
//	        		String key = adptrBzwkGroupName +",I";
//	        		command = new CommonCommand("com.eactive.eai.agent.messagekey.ReloadMessageKeyCommand",key);
//	        		if (!validate(agentUtilService.broadcast(command))){
//	        			throw new Exception("어댑터 메시지키 동기화 오류 "+adptrBzwkGroupName);
//	        		} 
//		        }
//			}
			
			sb.append(resultInterface(mmiIfId, ver, "SUCCESS", ""));
        } catch(Exception e){
        	logger.error("MMISyncController error="+e.getMessage(),e);
        	sb.append(resultInterface(mmiIfId, ver, "FAIL",e.getMessage()));
        } 

        frame.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
        frame.append("<Deploy>");
        frame.append(sb.toString());
        frame.append("</Deploy>");
        
        
        
        
        
        //MMI Log data  //취약점소스 수정 2020.08.26
        DataSourceType dt = DataSourceTypeManager.getDataSourceType(DataSourceTypeManager.MONITORING);
        String schemaId = "";
		
		if(dt != null){
			DataSourceContextHolder.setDataSourceType(dt);
			schemaId =dt.getSchema();
		}else{
			logger.error("DataSourceType is null");
			return null;
		}
		//HashMap paramMap = new HashMap();
		 
		mmiLogMap.put("schemaId"     , schemaId);
		mmiLogMap.put("msgDpstHMS"   , DateUtil.getDateTimeMilliSecound());
		mmiLogMap.put("eaiSvcName"   , NullControl.addSpace(eaiSvcName));
		mmiLogMap.put("eaiSevrDstcd" , NullControl.addSpace(eaiSevrDstcd));
		mmiLogMap.put("cnvsnName"    , NullControl.addSpace(cnvsnNames));
		mmiLogMap.put("loutName"     , NullControl.addSpace(loutNames));
		mmiLogMap.put("reqDstcd"     , NullControl.addSpace(buffer.toString()));
		mmiLogMap.put("resDstcd"     , NullControl.addSpace(frame.toString()));
		mmiLogMap.put("interfaceId"  , NullControl.addSpace(mmiIfId));
		mmiLogMap.put("deployId"     , NullControl.addSpace(userId));
		
		try{
			mmiLogDao.insert(mmiLogMap);
		}catch(Exception e){
			logger.error("db insert error : " + mmiLogMap.toString(),e);
		}
        
        
		ServletOutputStream sos = null;
    	try {
    		sos = response.getOutputStream();
    		sos.write(frame.toString().getBytes());
    	} catch( Exception e ) {
    		//취약점소스 수정 2020.08.24
    		logger.error(" error", e); 
    	} finally {
    		if( sos != null ) sos.close();
    	}
    	return null;
    }
    @RequestMapping(value= "/mmiSync.do",params = "cmd=delete", method=RequestMethod.POST)
    public View messageDelete(HttpServletRequest request, HttpServletResponse response) throws Exception {
    	if (true){
    		throw new Exception("지원 하지 않는 메소드 입니다." );
    	}
    	
    	ServletInputStream sis = null;
		StringBuilder sb = new StringBuilder();
		StringBuilder frame = new StringBuilder();
    	try{
	    	sis = request.getInputStream();
	    	String data = streamToString(sis);
	    	HashMap<String,Object> map = MMIParser.parseDelete(data);
	    	if (map == null){
	    		throw new Exception ("parsing error");
	    	}
	    	//서버구분코드 필요
	    	String eaiSevrDstcd = "2";
			///////////////////////////////////////////////
			//서버구분코드로 DataSourceType 변경
			// 1 : 내부(NSG) , 2 : 대외(DSG), 3 : 공동망(GSG), 4 : DMZ(ZSG), 5 : 오픈뱅킹(ASG)
			// 개발은 1,2,3 은 DSG 로  4는 ZSG로 처리 한다.
			///////////////////////////////////////////////
			String serverType = monitoringContext.getStringProperty(MonitoringContext.MMI_SYNC_SERVERTYPE, "1=DSG,2=DSG,3=DSG,4=ZSG,5=DSG");
			HashMap<String,String> serverDstcdMap = new HashMap<String,String>();
			Matcher matcher = Pattern.compile("[ ]*([0-9]+)[ ]*=[ ]*([A-Z]+)[ ]*").matcher(serverType);
			while(matcher.find()) {
			    String key = matcher.group(1).trim();
			    String value = matcher.group(2).trim();
			    serverDstcdMap.put(key, value);
			} 
			if (serverDstcdMap.containsKey(eaiSevrDstcd)){
				String dataSourceType = serverDstcdMap.get(eaiSevrDstcd);
				DataSourceContextHolder.setDataSourceType(DataSourceTypeManager.getDataSourceType(dataSourceType));
			}else{
				throw new Exception("지원하지 않는 서버 구분코드 입니다."+eaiSevrDstcd);
			}

	    	HashMap<String,Object> inter = (HashMap<String,Object>)map.get("interface");
	    	List<HashMap<String,Object>> layouts = (List<HashMap<String,Object>>)map.get("formats");
	
	    	if (inter != null ){
    			//변환 목록 가져오기      - 인터페이스 기준
    			inter.put("transform", service.selectTransformListForEaiSvcName(inter));
    			//내부표준 목록 가져오기 - 인터페이스 기준
    			inter.put("bzwkSvcKeyName", service.selectBzwkSvcKeyNameForEaiSvcName(inter));
	    	}
	    	
	    	CommonCommand command = null;
	    	try{
				service.deleteInterface(inter);
				String eaiSvcName = (String)inter.get("eaiSvcName");
				if (!StringUtils.isEmpty(eaiSvcName)){
					//인터페이스 동기화
		    		command = new CommonCommand("com.eactive.eai.agent.eaimessage.RemoveEAIMessageCommand",eaiSvcName);
					if (!validate(agentUtilService.broadcast(command))){
						throw new Exception("인터페이스 동기화 오류 "+eaiSvcName);
					}
					//추출키 동기화
					command = new CommonCommand("com.eactive.eai.agent.bizkey.RemoveBizKeyCommand",eaiSvcName+",TR");
					if (!validate(agentUtilService.broadcast(command))){
						throw new Exception("추출키 동기화 오류 "+eaiSvcName);
					} 
					command = new CommonCommand("com.eactive.eai.agent.bizkey.RemoveBizKeyCommand",eaiSvcName+",AK");
					if (!validate(agentUtilService.broadcast(command))){
						throw new Exception("추출키 동기화 오류 "+eaiSvcName);
					} 
					//내부표준전문 삭제 동기화
					List<String> bzwkSvcKeyNames = (List<String>)inter.get("bzwkSvcKeyName");
					if (bzwkSvcKeyNames != null){
			        	for(String bzwkSvcKeyName : bzwkSvcKeyNames){
			        		command = new CommonCommand("com.eactive.eai.agent.kbmessage.RemoveKBMessageCommand",bzwkSvcKeyName);
			        		if (!validate(agentUtilService.broadcast(command))){
			        			throw new Exception("내부표준전문 동기화 오류 "+bzwkSvcKeyName);
			        		} 
			        	}
					}
					//변환 동기화
					List<String> transforms = (List<String>)inter.get("transform");
					if (transforms != null){
						for(String  cnvsnName : transforms){
							command = new CommonCommand("com.eactive.eai.agent.transformer.RemoveTransformCommand",cnvsnName);
							if (!validate(agentUtilService.broadcast(command))){
								throw new Exception("변환 동기화 오류 "+cnvsnName);
							}
						}
					}
		    	}
				sb.append(resultInterfaceDelete((String)inter.get("mmiIfId"),(String)inter.get("eaiSvcName"),"SUCCESS",""));
	    	}catch(Exception e){
	    		logger.error("MMISycnControl delete error="+e.getMessage(),e);
	    		sb.append(resultInterfaceDelete((String)inter.get("mmiIfId"),(String)inter.get("eaiSvcName"),"FAIL",e.getMessage()));
	    	}
	    	
	    	
	    	for(HashMap<String,Object> layout : layouts){
	    		String loutName = (String)layout.get("loutName");
				try{
					service.deleteLayout(layout);
					command = new CommonCommand("com.eactive.eai.agent.transformer.RemoveLayoutCommand",loutName);
					if (!validate(agentUtilService.broadcast(command))){
						throw new Exception("레이아웃 동기화 오류 "+loutName);
					}
					sb.append(resultFormatDelete((String)inter.get("mmiIfId"),(String)inter.get("eaiSvcName"),"SUCCESS",""));
				}catch(Exception e){
		    		logger.error("MMISycnControl delete error="+e.getMessage(),e);
					sb.append(resultFormatDelete((String)inter.get("mmiIfId"),(String)inter.get("eaiSvcName"),"FAIL",e.getMessage()));
				}
	    	}
    	}catch(Exception e){
    		logger.error(e.getMessage(),e);
    		sb.append("<error msg=\""+e.getMessage()+"\"/>");
    	}finally{
    		if (sis != null) try{sis.close();}catch(Exception e){}
    	}

    	
    	
        frame.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
        frame.append("<Deploy>");
        frame.append(sb.toString());
        frame.append("</Deploy>");
        
		ServletOutputStream sos = null;
    	try {
    		sos = response.getOutputStream();
    		sos.write(frame.toString().getBytes());
    	} catch( Exception e ) {
    		logger.error(e.getMessage(),e);
    	} finally {
    		if( sos != null ) sos.close();
    	}
    	return null;
    }
    private boolean validate(HashMap<String,Object> map ){
    	for(String key : map.keySet()){
    		Object o = map.get(key);
    		if (o instanceof String){
    			if("success".equals((String)o)){
    				;
    			}else{
    				return false;
    			}
    		}else{
    			return false;
    		}
    	}
    	return true;
    }

    private String resultInterface(String mmiIfId, String ver, String returnCode, String returnMessage){
    	return "<Interface mmi_if_id=\""+mmiIfId+"\" ver=\""+ver+"\" return_code=\""+returnCode+"\" return_message=\""+returnMessage+"\" />";
    }
    private String resultInterfaceDelete(String mmiIfId, String id, String returnCode, String returnMessage){
    	return "<Interface mmi_if_id=\""+mmiIfId+"\" id=\""+id+"\" return_code=\""+returnCode+"\" return_message=\""+returnMessage+"\" />";
    }
    private String resultFormatDelete(String mmiIoId, String id, String returnCode, String returnMessage){
    	return "<Format mmi_io_id=\""+mmiIoId+"\" id=\""+id+"\" return_code=\""+returnCode+"\" return_message=\""+returnMessage+"\" />";
    }
	private static String streamToString(InputStream is){
		ByteArrayOutputStream buffer = new ByteArrayOutputStream();
		int r;
		byte[] data = new byte[1024];
		try {
			while((r = is.read(data)) != -1){
				buffer.write(data,0,r);
				
			}
			buffer.flush();
		} catch (IOException e) {
			logger.error(e.getMessage(),e);
			return "";
		}
		String s = new String(buffer.toByteArray());

		return s;
	}

}
