package com.github.bjuvensjo.rsimulator.recorder; import groovy.lang.Binding; import groovy.util.GroovyScriptEngine; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.http.HttpServletRequest; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Map; public class RecorderScriptRunner { private static final String GLOBAL_REQUEST = "RecorderRequest.groovy"; private static final String GLOBAL_RESPONSE = "RecorderResponse.groovy"; private Logger log = LoggerFactory.getLogger(RecorderScriptRunner.class); private Config config; public RecorderScriptRunner(Config config) { this.config = config; } public void runRequestScript(RecorderServletRequestWrapper recorderRequest, RecorderServletResponseWrapper recorderResponse, String encoding) throws IOException { Map<String, Object> vars = buildVars(recorderRequest, recorderResponse); vars.put(RecorderScriptVars.REQUEST_BODY_TO_RECORD, recorderRequest.getRequestBody(encoding)); applyScript(GLOBAL_REQUEST, vars); recorderRequest.setAttribute(Constants.RELATIVE_RECORD_PATH, vars.get(RecorderScriptVars.RELATIVE_RECORD_PATH)); recorderRequest.setAttribute(Constants.FILE_PREFIX, vars.get(RecorderScriptVars.FILE_PREFIX)); recorderRequest.setAttribute(Constants.BASE_PATH, vars.get(RecorderScriptVars.BASE_PATH)); recorderRequest.setAttribute(Constants.REQUEST_BODY_TO_RECORD, requestBodyToRecord(recorderRequest, vars)); } public void runResponseScript(RecorderServletRequestWrapper recorderRequest, RecorderServletResponseWrapper recorderResponse, String encoding) throws IOException { Map<String, Object> vars = buildVars(recorderRequest, recorderResponse); vars.put(RecorderScriptVars.RESPONSE_BODY_TO_RECORD, recorderResponse.getResponseAsString(encoding)); applyScript(GLOBAL_RESPONSE, vars); recorderRequest.setAttribute(Constants.RESPONSE_BODY_TO_RECORD, vars.get(RecorderScriptVars.RESPONSE_BODY_TO_RECORD)); } private String requestBodyToRecord(RecorderServletRequestWrapper recorderRequest, Map vars) throws IOException { String dataToRecord = (String)vars.get(RecorderScriptVars.REQUEST_BODY_TO_RECORD); if(dataToRecord.length() > 0) { return dataToRecord; } else { return copyQueryString(recorderRequest); } } private String copyQueryString(HttpServletRequest request) { return request.getQueryString() != null ? request.getQueryString() : ""; } private Map<String, Object> buildVars(RecorderServletRequestWrapper recorderRequest, RecorderServletResponseWrapper recorderResponse) { Map<String, Object> vars = new HashMap<String, Object>(); vars.put(RecorderScriptVars.REQUEST, recorderRequest); vars.put(RecorderScriptVars.RESPONSE, recorderResponse); vars.put(RecorderScriptVars.RELATIVE_RECORD_PATH, requestedUriWithoutContext(recorderRequest)); vars.put(RecorderScriptVars.BASE_PATH, basePath()); vars.put(RecorderScriptVars.FILE_PREFIX, buildFilePrefix()); return vars; } private void applyScript(String script, Map vars) { try { File file = new File((new StringBuilder()).append(basePath()).append(File.separator).append(script).toString()); if(file.exists()) { log.debug("Applying script {} with vars: {}", new Object[] {file, vars}); String roots[] = {basePath()}; GroovyScriptEngine gse = new GroovyScriptEngine(roots); Binding binding = new Binding(); binding.setVariable("vars", vars); gse.run(script, binding); log.debug("Applied script {} and updated vars are: {}", new Object[] {file, vars }); } else { log.debug("When applying script path {} is not an existing file", basePath()); } } catch(Exception e) { log.error("Script error.", e); } } private String basePath() { String basePath = config.get(Config.BASE_DIRECTORY); return basePath == null ? "" : basePath; } private String buildFilePrefix() { return (new SimpleDateFormat("yyyyMMddHHmmssSS")).format(new Date()); } private String requestedUriWithoutContext(HttpServletRequest httpServletRequest) { return httpServletRequest.getRequestURI().substring(httpServletRequest.getContextPath().length() + 1); } }