package com.dxm.anymock.core.biz.service.impl; import com.dxm.anymock.common.base.enums.ResultCode; import com.dxm.anymock.common.base.exception.BizException; import com.dxm.anymock.common.base.exception.SysException; import com.dxm.anymock.common.dal.model.HttpInterfaceBO; import com.dxm.anymock.common.dal.model.enums.ConfigMode; import com.dxm.anymock.core.biz.Delayer; import com.dxm.anymock.core.biz.service.GroovyService; import com.dxm.anymock.core.biz.service.HttpAsyncMockService; import com.dxm.anymock.core.biz.HttpMockContext; import groovy.lang.Binding; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpMethod; import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletRequest; import java.io.OutputStream; import java.lang.reflect.Field; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; import java.nio.charset.StandardCharsets; import static com.dxm.anymock.common.dal.model.enums.ConfigMode.GROOVY; import static com.dxm.anymock.common.dal.model.enums.ConfigMode.GROOVY_TEMPLATE_SWITCH_CASE; import static com.dxm.anymock.common.dal.model.enums.ConfigMode.TEXT; @Service public class HttpAsyncMockServiceImpl implements HttpAsyncMockService { private static final Logger logger = LoggerFactory.getLogger(HttpAsyncMockServiceImpl.class); @Autowired private GroovyService groovyService; private Binding buildBindig(HttpServletRequest request, HttpURLConnection httpURLConnection) { Binding binding = new Binding(); binding.setProperty("request", request); binding.setProperty("httpURLConnection", httpURLConnection); return binding; } @Override public void mock(HttpMockContext context, HttpServletRequest request) throws Exception { HttpInterfaceBO httpInterfaceBO = context.getHttpInterfaceBO(); // 异步延迟 Delayer.delay(httpInterfaceBO.getAsyncDelay()); logger.info("Async delay finished"); // 初始化HttpUrlConnection URL url = new URL(httpInterfaceBO.getCallbackRequestUrl()); HttpURLConnection httpURLConnection = (HttpURLConnection)url.openConnection(); httpURLConnection.setDoInput(true); httpURLConnection.setRequestMethod(httpInterfaceBO.getCallbackRequestMethod()); httpInterfaceBO.getCallbackRequestHeaderList().forEach(httpHeader -> httpURLConnection.setRequestProperty(httpHeader.getName(), httpHeader.getValue())); ConfigMode configMode = httpInterfaceBO.getConfigMode(); String requestContent; if (configMode == TEXT) { requestContent = httpInterfaceBO.getCallbackRequestBody(); } else if (configMode == GROOVY) { requestContent = groovyService.exec( buildBindig(request, httpURLConnection), httpInterfaceBO.getAsyncScript()); } else if (configMode == GROOVY_TEMPLATE_SWITCH_CASE) { requestContent = groovyService.exec( buildBindig(request, httpURLConnection), context.getHttpInterfaceBranchBO().getAsyncScript()); } else { throw new SysException("Unknown ConfigMode"); } logger.info("RequestContent = {}", requestContent); if (StringUtils.isNotBlank(requestContent)) { if (HttpMethod.GET.matches(httpInterfaceBO.getCallbackRequestMethod())) { // rewrite url try { Field field = URLConnection.class.getDeclaredField("url"); field.setAccessible(true); field.set(httpURLConnection, new URL(String.format("%s?%s", httpInterfaceBO.getCallbackRequestUrl(), requestContent))); } catch (NoSuchFieldException | IllegalAccessException e) { throw new BizException(ResultCode.UNEXPECTED_ERROR); } } else { httpURLConnection.setDoOutput(true); OutputStream outputStream = httpURLConnection.getOutputStream(); outputStream.write(requestContent.getBytes()); outputStream.flush(); outputStream.close(); } }else { logger.info("Async RequestContent 为空"); return; } int responseCode = httpURLConnection.getResponseCode(); logger.info("ResponseCode = {}", responseCode); String responseContent = IOUtils.toString(httpURLConnection.getInputStream(), StandardCharsets.UTF_8); logger.info("ResponseContent = {}", responseContent); } }