All Downloads are FREE. Search and download functionalities are using the official Maven repository.

nl.nn.adapterframework.testtool.TestTool Maven / Gradle / Ivy

There is a newer version: 7.9.5
Show newest version
/*
   Copyright 2014-2019 Nationale-Nederlanden, 2020-2022 WeAreFrank!

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
 */
package nl.nn.adapterframework.testtool;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.TreeSet;
import java.util.concurrent.atomic.AtomicLong;
import java.util.regex.Pattern;
import java.util.zip.ZipInputStream;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.Logger;
import org.custommonkey.xmlunit.Diff;
import org.custommonkey.xmlunit.XMLUnit;

import nl.nn.adapterframework.configuration.ConfigurationException;
import nl.nn.adapterframework.configuration.IbisContext;
import nl.nn.adapterframework.core.ISender;
import nl.nn.adapterframework.core.ListenerException;
import nl.nn.adapterframework.core.PipeLineSession;
import nl.nn.adapterframework.core.SenderException;
import nl.nn.adapterframework.core.TimeoutException;
import nl.nn.adapterframework.jdbc.FixedQuerySender;
import nl.nn.adapterframework.jms.JmsSender;
import nl.nn.adapterframework.jms.PullingJmsListener;
import nl.nn.adapterframework.lifecycle.IbisApplicationServlet;
import nl.nn.adapterframework.parameters.Parameter;
import nl.nn.adapterframework.senders.DelaySender;
import nl.nn.adapterframework.stream.FileMessage;
import nl.nn.adapterframework.stream.Message;
import nl.nn.adapterframework.testtool.queues.QueueCreator;
import nl.nn.adapterframework.testtool.queues.QueueWrapper;
import nl.nn.adapterframework.util.AppConstants;
import nl.nn.adapterframework.util.CaseInsensitiveComparator;
import nl.nn.adapterframework.util.DomBuilderException;
import nl.nn.adapterframework.util.FileUtils;
import nl.nn.adapterframework.util.LogUtil;
import nl.nn.adapterframework.util.Misc;
import nl.nn.adapterframework.util.ProcessUtil;
import nl.nn.adapterframework.util.StreamUtil;
import nl.nn.adapterframework.util.StringResolver;
import nl.nn.adapterframework.util.XmlUtils;

/**
 * @author Jaco de Groot
 */
public class TestTool {
	private static Logger logger = LogUtil.getLogger(TestTool.class);
	public static final String LOG_LEVEL_ORDER = "[debug], [pipeline messages prepared for diff], [pipeline messages], [wrong pipeline messages prepared for diff], [wrong pipeline messages], [step passed/failed], [scenario passed/failed], [scenario failed], [totals], [error]";
	private static final String STEP_SYNCHRONIZER = "Step synchronizer";
	protected static final String TESTTOOL_CORRELATIONID = "Test Tool correlation id";
	protected static final int DEFAULT_TIMEOUT = AppConstants.getInstance().getInt("larva.timeout", 30000);
	protected static final String TESTTOOL_BIFNAME = "Test Tool bif name";
	public static final nl.nn.adapterframework.stream.Message TESTTOOL_DUMMY_MESSAGE = new nl.nn.adapterframework.stream.Message("Dummy message");
	protected static final String TESTTOOL_CLEAN_UP_REPLY = "Clean up reply";
	private static final int RESULT_ERROR = 0;
	private static final int RESULT_OK = 1;
	private static final int RESULT_AUTOSAVED = 2;
	// dirty solution by Marco de Reus:
	private static String zeefVijlNeem = "";
	private static Writer silentOut = null;
	private static boolean autoSaveDiffs = false;
	private static AtomicLong correlationIdSuffixCounter = new AtomicLong(1);

	/*
	 * if allowReadlineSteps is set to true, actual results can be compared in line by using .readline steps.
	 * Those results cannot be saved to the inline expected value, however.
	 */
	private static final boolean allowReadlineSteps = false;
	protected static int globalTimeout=DEFAULT_TIMEOUT;

	private static final String TR_STARTING_TAG="";
	private static final String TR_CLOSING_TAG="";
	private static final String TD_STARTING_TAG="";
	private static final String TD_CLOSING_TAG="";
	private static final String TABLE_CLOSING_TAG="";

	public static void setTimeout(int newTimeout) {
		globalTimeout=newTimeout;
	}

	private static IbisContext getIbisContext(ServletContext application) {
		return IbisApplicationServlet.getIbisContext(application);
	}

	public static void runScenarios(ServletContext application, HttpServletRequest request, Writer out) {
		runScenarios(application, request, out, false);
	}

	public static void runScenarios(ServletContext application, HttpServletRequest request, Writer out, boolean silent) {
		String paramLogLevel = request.getParameter("loglevel");
		String paramAutoScroll = request.getParameter("autoscroll");
		String paramExecute = request.getParameter("execute");
		String paramWaitBeforeCleanUp = request.getParameter("waitbeforecleanup");
		String paramGlobalTimeout = request.getParameter("timeout");
		int timeout=globalTimeout;
		if(paramGlobalTimeout != null) {
			try {
				timeout = Integer.parseInt(paramGlobalTimeout);
			} catch(NumberFormatException e) {
			}
		}
		String servletPath = request.getServletPath();
		int i = servletPath.lastIndexOf('/');
		String realPath = application.getRealPath(servletPath.substring(0, i));
		String paramScenariosRootDirectory = request.getParameter("scenariosrootdirectory");
		IbisContext ibisContext = getIbisContext(application);
		runScenarios(ibisContext, paramLogLevel,
				paramAutoScroll, paramExecute, paramWaitBeforeCleanUp, timeout,
				realPath, paramScenariosRootDirectory, out, silent);
	}

	public static final int ERROR_NO_SCENARIO_DIRECTORIES_FOUND=-1;
	/**
	 *
	 * @return negative: error condition
	 * 		   0: all scenarios passed
	 * 		   positive: number of scenarios that failed
	 */
	public static int runScenarios(IbisContext ibisContext, String paramLogLevel,
			String paramAutoScroll, String paramExecute, String paramWaitBeforeCleanUp,
			int timeout, String realPath, String paramScenariosRootDirectory,
			Writer out, boolean silent) {
		AppConstants appConstants = AppConstants.getInstance();
		String logLevel = "wrong pipeline messages";
		String autoScroll = "true";
		if (paramLogLevel != null && LOG_LEVEL_ORDER.indexOf("[" + paramLogLevel + "]") > -1) {
			logLevel = paramLogLevel;
		}
		if (paramAutoScroll == null && paramLogLevel != null) {
			autoScroll = "false";
		}

		Map writers = null;
		if (!silent) {
			writers = new HashMap();
			writers.put("out", out);
			writers.put("htmlbuffer", new StringWriter());
			writers.put("logbuffer", new StringWriter());
			writers.put("loglevel", logLevel);
			writers.put("autoscroll", autoScroll);
			writers.put("usehtmlbuffer", "false");
			writers.put("uselogbuffer", "true");
			writers.put("messagecounter", new Integer(0));
			writers.put("scenariocounter", new Integer(1));
		} else {
			silentOut = out;
		}

		TestTool.debugMessage("Start logging to logbuffer until form is written", writers);
		String asd = appConstants.getResolvedProperty("larva.diffs.autosave");
		if (asd!=null) {
			autoSaveDiffs = Boolean.parseBoolean(asd);
		}
		debugMessage("Initialize scenarios root directories", writers);
		List scenariosRootDirectories = new ArrayList();
		List scenariosRootDescriptions = new ArrayList();
		String currentScenariosRootDirectory = initScenariosRootDirectories(
				realPath,
				paramScenariosRootDirectory, scenariosRootDirectories,
				scenariosRootDescriptions, writers);
		if (scenariosRootDirectories.size() == 0) {
			debugMessage("Stop logging to logbuffer", writers);
			writers.put("uselogbuffer", "stop");
			errorMessage("No scenarios root directories found", writers);
			return ERROR_NO_SCENARIO_DIRECTORIES_FOUND;
		}

		debugMessage("Read scenarios from directory '" + currentScenariosRootDirectory + "'", writers);
		List allScenarioFiles = readScenarioFiles(appConstants, currentScenariosRootDirectory, writers);
		debugMessage("Initialize 'wait before cleanup' variable", writers);
		int waitBeforeCleanUp = 100;
		if (paramWaitBeforeCleanUp != null) {
			try {
				waitBeforeCleanUp = Integer.parseInt(paramWaitBeforeCleanUp);
			} catch(NumberFormatException e) {
			}
		}

		debugMessage("Write html form", writers);
		printHtmlForm(scenariosRootDirectories, scenariosRootDescriptions, currentScenariosRootDirectory, appConstants, allScenarioFiles, waitBeforeCleanUp, timeout, paramExecute, autoScroll, writers);
		debugMessage("Stop logging to logbuffer", writers);
		if (writers!=null) {
			writers.put("uselogbuffer", "stop");
		}
		debugMessage("Start debugging to out", writers);
		debugMessage("Execute scenario(s) if execute parameter present and scenarios root directory did not change", writers);
		int scenariosFailed = 0;
		if (paramExecute != null) {
			String paramExecuteCanonicalPath;
			String scenariosRootDirectoryCanonicalPath;
			try {
				paramExecuteCanonicalPath = new File(paramExecute).getCanonicalPath();
				scenariosRootDirectoryCanonicalPath = new File(currentScenariosRootDirectory).getCanonicalPath();
			} catch(IOException e) {
				paramExecuteCanonicalPath = paramExecute;
				scenariosRootDirectoryCanonicalPath = currentScenariosRootDirectory;
				errorMessage("Could not get canonical path: " + e.getMessage(), e, writers);
			}
			if (paramExecuteCanonicalPath.startsWith(scenariosRootDirectoryCanonicalPath)) {

				debugMessage("Initialize XMLUnit", writers);
				XMLUnit.setIgnoreWhitespace(true);
				debugMessage("Initialize 'scenario files' variable", writers);
				debugMessage("Param execute: " + paramExecute, writers);
				List scenarioFiles;
				if (paramExecute.endsWith(".properties")) {
					debugMessage("Read one scenario", writers);
					scenarioFiles = new ArrayList();
					scenarioFiles.add(new File(paramExecute));
				} else {
					debugMessage("Read all scenarios from directory '" + paramExecute + "'", writers);
					scenarioFiles = readScenarioFiles(appConstants, paramExecute, writers);
				}
				boolean evenStep = false;
				debugMessage("Initialize statistics variables", writers);
				int scenariosPassed = 0;
				int scenariosAutosaved = 0;
				long startTime = System.currentTimeMillis();
				debugMessage("Execute scenario('s)", writers);
				Iterator scenarioFilesIterator = scenarioFiles.iterator();
				while (scenarioFilesIterator.hasNext()) {
					// increment suffix for each scenario
					String correlationId = TESTTOOL_CORRELATIONID + "("+ correlationIdSuffixCounter.getAndIncrement() +")";
					int scenarioPassed = RESULT_ERROR;
					File scenarioFile = scenarioFilesIterator.next();

					String scenarioDirectory = scenarioFile.getParentFile().getAbsolutePath() + File.separator;
					String longName = scenarioFile.getAbsolutePath();
					String shortName = longName.substring(currentScenariosRootDirectory.length() - 1, longName.length() - ".properties".length());

					if (writers!=null) {
						if (LOG_LEVEL_ORDER.indexOf("[" + (String)writers.get("loglevel") + "]") < LOG_LEVEL_ORDER.indexOf("[scenario passed/failed]")) {
							writeHtml("
", writers, false); writeHtml("
", writers, false); writeHtml("
", writers, false); } } debugMessage("Read property file " + scenarioFile.getName(), writers); Properties properties = readProperties(appConstants, scenarioFile, writers); List steps = null; if (properties != null) { debugMessage("Read steps from property file", writers); steps = getSteps(properties, writers); if (steps != null) { synchronized(STEP_SYNCHRONIZER) { debugMessage("Open queues", writers); Map> queues = QueueCreator.openQueues(scenarioDirectory, properties, ibisContext, writers, timeout, correlationId); if (queues != null) { debugMessage("Execute steps", writers); boolean allStepsPassed = true; boolean autoSaved = false; Iterator iterator = steps.iterator(); while (allStepsPassed && iterator.hasNext()) { if (evenStep) { writeHtml("
", writers, false); evenStep = false; } else { writeHtml("
", writers, false); evenStep = true; } String step = (String)iterator.next(); String stepDisplayName = shortName + " - " + step + " - " + properties.get(step); debugMessage("Execute step '" + stepDisplayName + "'", writers); int stepPassed = executeStep(step, properties, stepDisplayName, queues, writers, timeout, correlationId); if (stepPassed==RESULT_OK) { stepPassedMessage("Step '" + stepDisplayName + "' passed", writers); } else if (stepPassed==RESULT_AUTOSAVED) { stepAutosavedMessage("Step '" + stepDisplayName + "' passed after autosave", writers); autoSaved = true; } else { stepFailedMessage("Step '" + stepDisplayName + "' failed", writers); allStepsPassed = false; } writeHtml("
", writers, false); } if (allStepsPassed) { if (autoSaved) { scenarioPassed = RESULT_AUTOSAVED; } else { scenarioPassed = RESULT_OK; } } debugMessage("Wait " + waitBeforeCleanUp + " ms before clean up", writers); try { Thread.sleep(waitBeforeCleanUp); } catch(InterruptedException e) { } debugMessage("Close queues", writers); boolean remainingMessagesFound = closeQueues(queues, properties, writers, correlationId); if (remainingMessagesFound) { stepFailedMessage("Found one or more messages on queues or in database after scenario executed", writers); scenarioPassed = RESULT_ERROR; } } } } } if (scenarioPassed==RESULT_OK) { scenariosPassed++; scenarioPassedMessage("Scenario '" + shortName + " - " + properties.getProperty("scenario.description") + "' passed (" + scenariosFailed + "/" + scenariosPassed + "/" + scenarioFiles.size() + ")", writers); if (silent && LOG_LEVEL_ORDER.indexOf("[" + logLevel + "]") <= LOG_LEVEL_ORDER.indexOf("[scenario passed/failed]")) { try { out.write("Scenario '" + shortName + " - " + properties.getProperty("scenario.description") + "' passed"); } catch (IOException e) { } } } else if (scenarioPassed==RESULT_AUTOSAVED) { scenariosAutosaved++; scenarioAutosavedMessage("Scenario '" + shortName + " - " + properties.getProperty("scenario.description") + "' passed after autosave", writers); if (silent) { try { out.write("Scenario '" + shortName + " - " + properties.getProperty("scenario.description") + "' passed after autosave"); } catch (IOException e) { } } } else { scenariosFailed++; scenarioFailedMessage("Scenario '" + shortName + " - " + properties.getProperty("scenario.description") + "' failed (" + scenariosFailed + "/" + scenariosPassed + "/" + scenarioFiles.size() + ")", writers); if (silent) { try { out.write("Scenario '" + shortName + " - " + properties.getProperty("scenario.description") + "' failed"); } catch (IOException e) { } } } writeHtml("
", writers, false); } long executeTime = System.currentTimeMillis() - startTime; debugMessage("Print statistics information", writers); int scenariosTotal = scenariosPassed + scenariosAutosaved + scenariosFailed; if (scenariosTotal == 0) { scenariosTotalMessage("No scenarios found", writers, out, silent); } else { if (writers!=null) { if (LOG_LEVEL_ORDER.indexOf("[" + (String)writers.get("loglevel") + "]") <= LOG_LEVEL_ORDER.indexOf("[scenario passed/failed]")) { writeHtml("
", writers, false); writeHtml("
", writers, false); } } debugMessage("Print statistics information", writers); if (scenariosPassed == scenariosTotal) { if (scenariosTotal == 1) { scenariosPassedTotalMessage("All scenarios passed (1 scenario executed in " + executeTime + " ms)", writers, out, silent); } else { scenariosPassedTotalMessage("All scenarios passed (" + scenariosTotal + " scenarios executed in " + executeTime + " ms)", writers, out, silent); } } else if (scenariosFailed == scenariosTotal) { if (scenariosTotal == 1) { scenariosFailedTotalMessage("All scenarios failed (1 scenario executed in " + executeTime + " ms)", writers, out, silent); } else { scenariosFailedTotalMessage("All scenarios failed (" + scenariosTotal + " scenarios executed in " + executeTime + " ms)", writers, out, silent); } } else { if (scenariosTotal == 1) { scenariosTotalMessage("1 scenario executed in " + executeTime + " ms", writers, out, silent); } else { scenariosTotalMessage(scenariosTotal + " scenarios executed in " + executeTime + " ms", writers, out, silent); } if (scenariosPassed == 1) { scenariosPassedTotalMessage("1 scenario passed", writers, out, silent); } else { scenariosPassedTotalMessage(scenariosPassed + " scenarios passed", writers, out, silent); } if (autoSaveDiffs) { if (scenariosAutosaved == 1) { scenariosAutosavedTotalMessage("1 scenario passed after autosave", writers, out, silent); } else { scenariosAutosavedTotalMessage(scenariosAutosaved + " scenarios passed after autosave", writers, out, silent); } } if (scenariosFailed == 1) { scenariosFailedTotalMessage("1 scenario failed", writers, out, silent); } else { scenariosFailedTotalMessage(scenariosFailed + " scenarios failed", writers, out, silent); } } } debugMessage("Start logging to htmlbuffer until form is written", writers); if (writers!=null) { writers.put("usehtmlbuffer", "start"); } writeHtml("
", writers, false); writeHtml("
", writers, false); printHtmlForm(scenariosRootDirectories, scenariosRootDescriptions, currentScenariosRootDirectory, appConstants, allScenarioFiles, waitBeforeCleanUp, timeout, paramExecute, autoScroll, writers); debugMessage("Stop logging to htmlbuffer", writers); if (writers!=null) { writers.put("usehtmlbuffer", "stop"); } writeHtml("", writers, true); } } return scenariosFailed; } public static void printHtmlForm(List scenariosRootDirectories, List scenariosRootDescriptions, String scenariosRootDirectory, AppConstants appConstants, List scenarioFiles, int waitBeforeCleanUp, int timeout, String paramExecute, String autoScroll, Map writers) { if (writers!=null) { writeHtml("
", writers, false); // scenario root directory drop down writeHtml("", writers, false); writeHtml(TR_STARTING_TAG, writers, false); writeHtml("", writers, false); writeHtml(TR_CLOSING_TAG, writers, false); writeHtml(TR_STARTING_TAG, writers, false); writeHtml(TD_STARTING_TAG, writers, false); writeHtml("", writers, false); writeHtml(TD_CLOSING_TAG, writers, false); writeHtml(TR_CLOSING_TAG, writers, false); writeHtml(TABLE_CLOSING_TAG, writers, false); // Use a span to make IE put table on next line with a smaller window width writeHtml("     ", writers, false); writeHtml("
Scenarios root directory
", writers, false); writeHtml(TR_STARTING_TAG, writers, false); writeHtml("", writers, false); writeHtml(TR_CLOSING_TAG, writers, false); writeHtml(TR_STARTING_TAG, writers, false); writeHtml(TD_STARTING_TAG, writers, false); writeHtml("", writers, false); writeHtml(TD_CLOSING_TAG, writers, false); writeHtml(TR_CLOSING_TAG, writers, false); writeHtml(TABLE_CLOSING_TAG, writers, false); writeHtml("     ", writers, false); // timeout box writeHtml("
Wait before clean up (ms)
", writers, false); writeHtml(TR_STARTING_TAG, writers, false); writeHtml("", writers, false); writeHtml(TR_CLOSING_TAG, writers, false); writeHtml(TR_STARTING_TAG, writers, false); writeHtml(TD_STARTING_TAG, writers, false); writeHtml("", writers, false); writeHtml(TD_CLOSING_TAG, writers, false); writeHtml(TR_CLOSING_TAG, writers, false); writeHtml(TABLE_CLOSING_TAG, writers, false); // log level dropdown writeHtml("     ", writers, false); writeHtml("
Default timeout (ms)
", writers, false); writeHtml(TR_STARTING_TAG, writers, false); writeHtml("", writers, false); writeHtml(TR_CLOSING_TAG, writers, false); writeHtml(TR_STARTING_TAG, writers, false); writeHtml(TD_STARTING_TAG, writers, false); writeHtml("", writers, false); writeHtml(TD_CLOSING_TAG, writers, false); writeHtml(TR_CLOSING_TAG, writers, false); writeHtml(TABLE_CLOSING_TAG, writers, false); // Auto scroll checkbox writeHtml("     ", writers, false); writeHtml("
Log level
", writers, false); writeHtml(TR_STARTING_TAG, writers, false); writeHtml("", writers, false); writeHtml(TR_CLOSING_TAG, writers, false); writeHtml(TR_STARTING_TAG, writers, false); writeHtml(TD_STARTING_TAG, writers, false); writeHtml("", writers, false); writeHtml(TD_CLOSING_TAG, writers, false); writeHtml(TR_CLOSING_TAG, writers, false); writeHtml(TABLE_CLOSING_TAG, writers, false); // Scenario(s) writeHtml("
Auto scroll
", writers, false); writeHtml(TR_STARTING_TAG, writers, false); writeHtml("", writers, false); writeHtml(TR_CLOSING_TAG, writers, false); writeHtml(TR_STARTING_TAG, writers, false); writeHtml(TD_STARTING_TAG, writers, false); writeHtml("", writers, false); writeHtml(TD_CLOSING_TAG, writers, false); writeHtml(TR_CLOSING_TAG, writers, false); writeHtml(TABLE_CLOSING_TAG, writers, false); writeHtml("     ", writers, false); // submit button writeHtml("
Scenario(s)
", writers, false); writeHtml(TR_STARTING_TAG, writers, false); writeHtml("", writers, false); writeHtml(TR_CLOSING_TAG, writers, false); writeHtml(TR_STARTING_TAG, writers, false); writeHtml("
 ", writers, false); writeHtml("", writers, false); writeHtml(TD_CLOSING_TAG, writers, false); writeHtml(TR_CLOSING_TAG, writers, false); writeHtml(TABLE_CLOSING_TAG, writers, false); writeHtml("", writers, false); writeHtml("
", writers, false); } } public static void write(String html, String type, String method, Map writers, boolean scroll) { if (writers!=null) { String useBuffer = (String)writers.get("use" + type + "buffer"); if (useBuffer.equals("start")) { useBuffer = "true"; writers.put("use" + type + "buffer", useBuffer); } else if (useBuffer.equals("stop")) { Writer out = (Writer)writers.get("out"); StringWriter buffer = (StringWriter)writers.get(type + "buffer"); try { out.write(buffer.toString()); } catch(IOException e) { } useBuffer = "false"; writers.put("use" + type + "buffer", useBuffer); } Writer writer; if (useBuffer.equals("true")) { writer = (Writer)writers.get(type + "buffer"); } else { writer = (Writer)writers.get("out"); } if (method == null || LOG_LEVEL_ORDER.indexOf("[" + (String)writers.get("loglevel") + "]") <= LOG_LEVEL_ORDER.indexOf("[" + method + "]")) { try { writer.write(html + "\n"); if (scroll && "true".equals(writers.get("autoscroll"))) { writer.write("\n"); } writer.flush(); } catch(IOException e) { } } } } public static void writeHtml(String html, Map writers, boolean scroll) { write(html, "html", null, writers, scroll); } public static void writeLog(String html, String method, Map writers, boolean scroll) { write(html, "log", method, writers, scroll); } public static void debugMessage(String message, Map writers) { String method = "debug"; logger.debug(message); writeLog(XmlUtils.encodeChars(XmlUtils.replaceNonValidXmlCharacters(message)) + "
", method, writers, false); } public static void debugPipelineMessage(String stepDisplayName, String message, String pipelineMessage, Map writers) { if (writers!=null) { String method = "pipeline messages"; int messageCounter = ((Integer)writers.get("messagecounter")).intValue(); messageCounter ++; writeLog("
", method, writers, false); writeLog("

Step '" + stepDisplayName + "'

", method, writers, false); writeLog(writeCommands("messagebox" + messageCounter, true, null), method, writers, false); writeLog("
" + XmlUtils.encodeChars(message) + "
", method, writers, false); writeLog("", method, writers, false); writeLog("
", method, writers, false); writers.put("messagecounter", new Integer(messageCounter)); } } public static void debugPipelineMessagePreparedForDiff(String stepDisplayName, String message, String pipelineMessage, Map writers) { if (writers!=null) { String method = "pipeline messages prepared for diff"; int messageCounter = ((Integer)writers.get("messagecounter")).intValue(); messageCounter ++; writeLog("
", method, writers, false); writeLog("

Step '" + stepDisplayName + "'

", method, writers, false); writeLog(writeCommands("messagebox" + messageCounter, true, null), method, writers, false); writeLog("
" + XmlUtils.encodeChars(message) + "
", method, writers, false); writeLog("", method, writers, false); writeLog("
", method, writers, false); writers.put("messagecounter", new Integer(messageCounter)); } } public static void wrongPipelineMessage(String message, String pipelineMessage, Map writers) { if (writers!=null) { String method = "wrong pipeline messages"; int messageCounter = ((Integer)writers.get("messagecounter")).intValue(); messageCounter ++; writeLog("
", method, writers, false); writeLog(writeCommands("messagebox" + messageCounter, true, null), method, writers, false); writeLog("
" + XmlUtils.encodeChars(message) + "
", method, writers, false); writeLog("", method, writers, false); writeLog("
", method, writers, false); writers.put("messagecounter", new Integer(messageCounter)); } } public static void wrongPipelineMessage(String stepDisplayName, String message, String pipelineMessage, String pipelineMessageExpected, Map writers) { if (writers!=null) { String method = "wrong pipeline messages"; int scenarioCounter = ((Integer)writers.get("scenariocounter")).intValue(); String formName = "scenario" + scenarioCounter + "Wpm"; String resultBoxId = formName + "ResultBox"; String expectedBoxId = formName + "ExpectedBox"; String diffBoxId = formName + "DiffBox"; writeLog("
", method, writers, false); writeLog("
", method, writers, false); writeLog("", method, writers, false); // http://stackoverflow.com/questions/153527/setting-the-character-encoding-in-form-submit-for-internet-explorer writeLog("

Step '" + stepDisplayName + "'

", method, writers, false); writeLog("
", method, writers, false); writeLog("
", method, writers, false); writeLog(writeCommands(resultBoxId, true, "save"), method, writers, false); writeLog("
Result (raw):
", method, writers, false); writeLog("", method, writers, false); writeLog("
", method, writers, false); writeLog("
", method, writers, false); writeLog(writeCommands(expectedBoxId, true, null), method, writers, true); writeLog("", method, writers, false); writeLog("", method, writers, false); writeLog("
Expected (raw):
", method, writers, false); writeLog("", method, writers, false); writeLog("
", method, writers, false); writeLog("
", method, writers, false); writeLog("
", method, writers, false); String btn1 = "compare"; String btn2 = "windiff"; writeLog(writeCommands(diffBoxId, false, btn1+btn2), method, writers, false); writeLog("
Differences:
", method, writers, false); writeLog("
", method, writers, false);
			writeLog("
", method, writers, false); String scenario_passed_failed = "scenario passed/failed"; if (LOG_LEVEL_ORDER.indexOf( "[" + (String) writers.get("loglevel") + "]") == LOG_LEVEL_ORDER .indexOf("[" + scenario_passed_failed + "]")) { writeLog("", scenario_passed_failed, writers, false); writeLog( "", scenario_passed_failed, writers, true); } else { writeLog("
Difference description:
", method, writers, false); writeLog("

" + XmlUtils.encodeChars(message) + "

", method, writers, true); writeLog("
", method, writers, false); writeLog("
", method, writers, false); } scenarioCounter++; writers.put("scenariocounter", new Integer(scenarioCounter)); } else { if (silentOut!=null) { try { silentOut.write(message); } catch (IOException e) { } } } } public static void wrongPipelineMessagePreparedForDiff(String stepDisplayName, String pipelineMessagePreparedForDiff, String pipelineMessageExpectedPreparedForDiff, Map writers) { if (writers!=null) { String method = "wrong pipeline messages prepared for diff"; int scenarioCounter = ((Integer)writers.get("scenariocounter")).intValue(); int messageCounter = ((Integer)writers.get("messagecounter")).intValue(); String formName = "scenario" + scenarioCounter + "Wpmpfd"; String resultBoxId = formName + "ResultBox"; String expectedBoxId = formName + "ExpectedBox"; String diffBoxId = formName + "DiffBox"; writeLog("
", method, writers, false); writeLog("
", method, writers, false); writeLog("", method, writers, false); // http://stackoverflow.com/questions/153527/setting-the-character-encoding-in-form-submit-for-internet-explorer writeLog("

Step '" + stepDisplayName + "'

", method, writers, false); messageCounter ++; writeLog("
", method, writers, false); writeLog("
", method, writers, false); writeLog(writeCommands(resultBoxId, true, null), method, writers, false); writeLog("
Result (prepared for diff):
", method, writers, false); writeLog("", method, writers, false); writeLog("
", method, writers, false); messageCounter++; writeLog("
", method, writers, false); writeLog(writeCommands(expectedBoxId, true, null), method, writers, false); writeLog("", method, writers, false); writeLog("", method, writers, false); writeLog("
Expected (prepared for diff):
", method, writers, false); writeLog("", method, writers, false); writeLog("
", method, writers, false); writeLog("
", method, writers, false); messageCounter++; writeLog("
", method, writers, false); String btn1 = "compare"; String btn2 = "windiff"; writeLog(writeCommands(diffBoxId, false, btn1+btn2), method, writers, false); writeLog("
Differences:
", method, writers, false); writeLog("
", method, writers, false);
			writeLog("
", method, writers, false); writeLog("
", method, writers, false); writeLog("
", method, writers, false); writers.put("messagecounter", new Integer(messageCounter)); } } private static String writeCommands(String target, boolean textArea, String customCommand) { String commands = ""; commands += "
"; commands += "-width+"; commands += "-height+"; if (textArea) { commands += "copy "; commands += "indent"; } if (customCommand != null) { commands += " " + customCommand; } commands += "
"; return commands; } public static void stepPassedMessage(String message, Map writers) { String method = "step passed/failed"; writeLog("

" + XmlUtils.encodeChars(message) + "

", method, writers, true); } public static void stepAutosavedMessage(String message, Map writers) { String method = "step passed/failed"; writeLog("

" + XmlUtils.encodeChars(message) + "

", method, writers, true); } public static void stepFailedMessage(String message, Map writers) { String method = "step passed/failed"; writeLog("

" + XmlUtils.encodeChars(message) + "

", method, writers, true); } public static void scenarioPassedMessage(String message, Map writers) { String method = "scenario passed/failed"; writeLog("

" + XmlUtils.encodeChars(message) + "

", method, writers, true); } public static void scenarioAutosavedMessage(String message, Map writers) { String method = "scenario passed/failed"; writeLog("

" + XmlUtils.encodeChars(message) + "

", method, writers, true); } public static void scenarioFailedMessage(String message, Map writers) { String method = "scenario failed"; writeLog("

" + XmlUtils.encodeChars(message) + "

", method, writers, true); } public static void scenariosTotalMessage(String message, Map writers, Writer out, boolean silent) { if (silent) { try { out.write(message); } catch (IOException e) { } } else { String method = "totals"; writeLog("

" + XmlUtils.encodeChars(message) + "

", method, writers, true); } } public static void scenariosPassedTotalMessage(String message, Map writers, Writer out, boolean silent) { if (silent) { try { out.write(message); } catch (IOException e) { } } else { String method = "totals"; writeLog("

" + XmlUtils.encodeChars(message) + "

", method, writers, true); } } public static void scenariosAutosavedTotalMessage(String message, Map writers, Writer out, boolean silent) { if (silent) { try { out.write(message); } catch (IOException e) { } } else { String method = "totals"; writeLog("

" + XmlUtils.encodeChars(message) + "

", method, writers, true); } } public static void scenariosFailedTotalMessage(String message, Map writers, Writer out, boolean silent) { if (silent) { try { out.write(message); } catch (IOException e) { } } else { String method = "totals"; writeLog("

" + XmlUtils.encodeChars(message) + "

", method, writers, true); } } public static void errorMessage(String message, Map writers) { String method = "error"; writeLog("

" + XmlUtils.encodeChars(message) + "

", method, writers, true); if (silentOut!=null) { try { silentOut.write(message); } catch (IOException e) { } } } public static void errorMessage(String message, Exception exception, Map writers) { errorMessage(message, writers); if (writers!=null) { String method = "error"; Throwable throwable = exception; while (throwable != null) { StringWriter stringWriter = new StringWriter(); PrintWriter printWriter = new PrintWriter(stringWriter); throwable.printStackTrace(printWriter); printWriter.close(); int messageCounter = ((Integer)writers.get("messagecounter")).intValue(); messageCounter++; writeLog("
", method, writers, false); writeLog(writeCommands("messagebox" + messageCounter, true, null), method, writers, false); writeLog("
Stack trace:
", method, writers, false); writeLog("", method, writers, false); writeLog("
", method, writers, false); writers.put("messagecounter", new Integer(messageCounter)); throwable = throwable.getCause(); } } } public static String initScenariosRootDirectories(String realPath, String paramScenariosRootDirectory, List scenariosRootDirectories, List scenariosRootDescriptions, Map writers) { AppConstants appConstants = AppConstants.getInstance(); String currentScenariosRootDirectory = null; if (realPath == null) { errorMessage("Could not read webapp real path", writers); } else { if (!realPath.endsWith(File.separator)) { realPath = realPath + File.separator; } Map scenariosRoots = new HashMap(); Map scenariosRootsBroken = new HashMap(); int j = 1; String directory = appConstants.getResolvedProperty("scenariosroot" + j + ".directory"); String description = appConstants.getResolvedProperty("scenariosroot" + j + ".description"); while (directory != null) { if (description == null) { errorMessage("Could not find description for root directory '" + directory + "'", writers); } else if (scenariosRoots.get(description) != null) { errorMessage("A root directory named '" + description + "' already exist", writers); } else { String parent = realPath; String m2eFileName = appConstants.getResolvedProperty("scenariosroot" + j + ".m2e.pom.properties"); if (m2eFileName != null) { File m2eFile = new File(realPath, m2eFileName); if (m2eFile.exists()) { debugMessage("Read m2e pom.properties: " + m2eFileName, writers); Properties m2eProperties = readProperties(null, m2eFile, false, writers); parent = m2eProperties.getProperty("m2e.projectLocation"); debugMessage("Use m2e parent: " + parent, writers); } } directory = getAbsolutePath(parent, directory, true); if (new File(directory).exists()) { scenariosRoots.put(description, directory); } else { scenariosRootsBroken.put(description, directory); } } j++; directory = appConstants.getResolvedProperty("scenariosroot" + j + ".directory"); description = appConstants.getResolvedProperty("scenariosroot" + j + ".description"); } TreeSet treeSet = new TreeSet(new CaseInsensitiveComparator()); treeSet.addAll(scenariosRoots.keySet()); Iterator iterator = treeSet.iterator(); while (iterator.hasNext()) { description = (String)iterator.next(); scenariosRootDescriptions.add(description); scenariosRootDirectories.add(scenariosRoots.get(description)); } treeSet.clear(); treeSet.addAll(scenariosRootsBroken.keySet()); iterator = treeSet.iterator(); while (iterator.hasNext()) { description = (String)iterator.next(); scenariosRootDescriptions.add("X " + description); scenariosRootDirectories.add(scenariosRootsBroken.get(description)); } debugMessage("Read scenariosrootdirectory parameter", writers); debugMessage("Get current scenarios root directory", writers); if (paramScenariosRootDirectory == null || paramScenariosRootDirectory.equals("")) { String scenariosRootDefault = appConstants.getResolvedProperty("scenariosroot.default"); if (scenariosRootDefault != null) { currentScenariosRootDirectory = scenariosRoots.get(scenariosRootDefault); } if (currentScenariosRootDirectory == null && scenariosRootDirectories.size() > 0) { currentScenariosRootDirectory = (String)scenariosRootDirectories.get(0); } } else { currentScenariosRootDirectory = paramScenariosRootDirectory; } } return currentScenariosRootDirectory; } public static List readScenarioFiles(AppConstants appConstants, String scenariosDirectory, Map writers) { List scenarioFiles = new ArrayList(); debugMessage("List all files in directory '" + scenariosDirectory + "'", writers); File[] files = new File(scenariosDirectory).listFiles(); if (files == null) { debugMessage("Could not read files from directory '" + scenariosDirectory + "'", writers); } else { debugMessage("Sort files", writers); Arrays.sort(files); debugMessage("Filter out property files containing a 'scenario.description' property", writers); for (int i = 0; i < files.length; i++) { File file = files[i]; if (file.getName().endsWith(".properties")) { Properties properties = readProperties(appConstants, file, writers); if (properties != null && properties.get("scenario.description") != null) { String active = properties.getProperty("scenario.active", "true"); String unstable = properties.getProperty("adapter.unstable", "false"); if (active.equalsIgnoreCase("true") && unstable.equalsIgnoreCase("false")) { scenarioFiles.add(file); } } } else if (file.isDirectory() && (!file.getName().equals("CVS"))) { scenarioFiles.addAll(readScenarioFiles(appConstants, file.getAbsolutePath(), writers)); } } } debugMessage(scenarioFiles.size() + " scenario files found", writers); return scenarioFiles; } public static Properties readProperties(AppConstants appConstants, File propertiesFile, Map writers) { return readProperties(appConstants, propertiesFile, true, writers); } public static Properties readProperties(AppConstants appConstants, File propertiesFile, boolean root, Map writers) { String directory = new File(propertiesFile.getAbsolutePath()).getParent(); Properties properties = new Properties(); FileInputStream fileInputStreamPropertiesFile = null; try { fileInputStreamPropertiesFile = new FileInputStream(propertiesFile); properties.load(fileInputStreamPropertiesFile); fileInputStreamPropertiesFile.close(); fileInputStreamPropertiesFile = null; Properties includedProperties = new Properties(); int i = 0; String includeFilename = properties.getProperty("include"); if (includeFilename == null) { i++; includeFilename = properties.getProperty("include" + i); } while (includeFilename != null) { debugMessage("Load include file: " + includeFilename, writers); File includeFile = new File(getAbsolutePath(directory, includeFilename)); Properties includeProperties = readProperties(appConstants, includeFile, false, writers); includedProperties.putAll(includeProperties); i++; includeFilename = properties.getProperty("include" + i); } properties.putAll(includedProperties); if (root) { properties.putAll(appConstants); for (Object key : properties.keySet()) { properties.put(key, StringResolver.substVars((String)properties.get(key), properties)); } addAbsolutePathProperties(directory, properties); } debugMessage(properties.size() + " properties found", writers); } catch(Exception e) { properties = null; errorMessage("Could not read properties file: " + e.getMessage(), e, writers); if (fileInputStreamPropertiesFile != null) { try { fileInputStreamPropertiesFile.close(); } catch(Exception e2) { errorMessage("Could not close file '" + propertiesFile.getAbsolutePath() + "': " + e2.getMessage(), e, writers); } } } return properties; } public static String getAbsolutePath(String parent, String child) { return getAbsolutePath(parent, child, false); } /** * Returns the absolute pathname for the child pathname. The parent pathname * is used as a prefix when the child pathname is an not absolute. * * @param parent the parent pathname to use * @param child the child pathname to convert to a absolute pathname */ public static String getAbsolutePath(String parent, String child, boolean addFileSeparator) { File result; File file = new File(child); if (file.isAbsolute()) { result = file; } else { result = new File(parent, child); } String absPath = FilenameUtils.normalize(result.getAbsolutePath()); if (addFileSeparator) { return absPath + File.separator; } else { return absPath; } } public static void addAbsolutePathProperties(String propertiesDirectory, Properties properties) { Properties absolutePathProperties = new Properties(); Iterator iterator = properties.keySet().iterator(); while (iterator.hasNext()) { String property = (String)iterator.next(); if(property.equalsIgnoreCase("configurations.directory")) continue; if (property.endsWith(".read") || property.endsWith(".write") || property.endsWith(".directory") || property.endsWith(".filename") || property.endsWith(".valuefile") || property.endsWith(".valuefileinputstream")) { String absolutePathProperty = property + ".absolutepath"; String value = getAbsolutePath(propertiesDirectory, (String)properties.get(property)); if (value != null) { absolutePathProperties.put(absolutePathProperty, value); properties.put(property, value); } } } properties.putAll(absolutePathProperties); } public static List getSteps(Properties properties, Map writers) { List steps = new ArrayList(); int i = 1; boolean lastStepFound = false; while (!lastStepFound) { boolean stepFound = false; Enumeration enumeration = properties.propertyNames(); while (enumeration.hasMoreElements()) { String key = (String)enumeration.nextElement(); if (key.startsWith("step" + i + ".") && (key.endsWith(".read") || key.endsWith(".write") || (allowReadlineSteps && key.endsWith(".readline")) || key.endsWith(".writeline"))) { if (!stepFound) { steps.add(key); stepFound = true; debugMessage("Added step '" + key + "'", writers); } else { errorMessage("More than one step" + i + " properties found, already found '" + steps.get(steps.size() - 1) + "' before finding '" + key + "'", writers); } } } if (!stepFound) { lastStepFound = true; } i++; } debugMessage(steps.size() + " steps found", writers); return steps; } public static boolean closeQueues(Map> queues, Properties properties, Map writers, String correlationId) { boolean remainingMessagesFound = false; Iterator iterator; debugMessage("Close jms senders", writers); iterator = queues.keySet().iterator(); while (iterator.hasNext()) { String queueName = (String)iterator.next(); if ("nl.nn.adapterframework.jms.JmsSender".equals(properties.get(queueName + ".className"))) { JmsSender jmsSender = (JmsSender)((Map)queues.get(queueName)).get("jmsSender"); jmsSender.close(); debugMessage("Closed jms sender '" + queueName + "'", writers); } } debugMessage("Close jms listeners", writers); iterator = queues.keySet().iterator(); while (iterator.hasNext()) { String queueName = (String)iterator.next(); if ("nl.nn.adapterframework.jms.JmsListener".equals(properties.get(queueName + ".className"))) { PullingJmsListener pullingJmsListener = (PullingJmsListener)((Map)queues.get(queueName)).get("jmsListener"); if (jmsCleanUp(queueName, pullingJmsListener, writers)) { remainingMessagesFound = true; } pullingJmsListener.close(); debugMessage("Closed jms listener '" + queueName + "'", writers); } } debugMessage("Close jdbc connections", writers); iterator = queues.keySet().iterator(); while (iterator.hasNext()) { String name = (String)iterator.next(); if ("nl.nn.adapterframework.jdbc.FixedQuerySender".equals(properties.get(name + ".className"))) { Map querySendersInfo = (Map)queues.get(name); FixedQuerySender prePostFixedQuerySender = (FixedQuerySender)querySendersInfo.get("prePostQueryFixedQuerySender"); if (prePostFixedQuerySender != null) { try { /* Check if the preResult and postResult are not equal. If so, then there is a * database change that has not been read in the scenario. * So set remainingMessagesFound to true and show the entry. * (see also executeFixedQuerySenderRead() ) */ String preResult = (String)querySendersInfo.get("prePostQueryResult"); PipeLineSession session = new PipeLineSession(); session.put(PipeLineSession.businessCorrelationIdKey, correlationId); String postResult = prePostFixedQuerySender.sendMessage(TESTTOOL_DUMMY_MESSAGE, session).asString(); if (!preResult.equals(postResult)) { String message = null; FixedQuerySender readQueryFixedQuerySender = (FixedQuerySender)querySendersInfo.get("readQueryQueryFixedQuerySender"); try { message = readQueryFixedQuerySender.sendMessage(TESTTOOL_DUMMY_MESSAGE, session).asString(); } catch(TimeoutException e) { errorMessage("Time out on execute query for '" + name + "': " + e.getMessage(), e, writers); } catch(IOException | SenderException e) { errorMessage("Could not execute query for '" + name + "': " + e.getMessage(), e, writers); } if (message != null) { wrongPipelineMessage("Found remaining message on '" + name + "'", message, writers); } remainingMessagesFound = true; } prePostFixedQuerySender.close(); } catch(TimeoutException e) { errorMessage("Time out on close (pre/post) '" + name + "': " + e.getMessage(), e, writers); } catch(IOException | SenderException e) { errorMessage("Could not close (pre/post) '" + name + "': " + e.getMessage(), e, writers); } } FixedQuerySender readQueryFixedQuerySender = (FixedQuerySender)querySendersInfo.get("readQueryQueryFixedQuerySender"); readQueryFixedQuerySender.close(); } } debugMessage("Close autoclosables", writers); for(String queueName : queues.keySet()) { Map value = queues.get(queueName); if(value instanceof QueueWrapper) { QueueWrapper queue = (QueueWrapper) value; SenderThread senderThread = queue.getSenderThread(); if (senderThread != null) { debugMessage("Found remaining SenderThread", writers); SenderException senderException = senderThread.getSenderException(); if (senderException != null) { errorMessage("Found remaining SenderException: " + senderException.getMessage(), senderException, writers); } TimeoutException timeOutException = senderThread.getTimeOutException(); if (timeOutException != null) { errorMessage("Found remaining TimeOutException: " + timeOutException.getMessage(), timeOutException, writers); } String message = senderThread.getResponse(); if (message != null) { wrongPipelineMessage("Found remaining message on '" + queueName + "'", message, writers); } } ListenerMessageHandler listenerMessageHandler = queue.getMessageHandler(); if (listenerMessageHandler != null) { ListenerMessage listenerMessage = listenerMessageHandler.getRequestMessage(); while (listenerMessage != null) { String message = listenerMessage.getMessage(); wrongPipelineMessage("Found remaining request message on '" + queueName + "'", message, writers); remainingMessagesFound = true; listenerMessage = listenerMessageHandler.getRequestMessage(); } listenerMessage = listenerMessageHandler.getResponseMessage(); while (listenerMessage != null) { String message = listenerMessage.getMessage(); wrongPipelineMessage("Found remaining response message on '" + queueName + "'", message, writers); remainingMessagesFound = true; listenerMessage = listenerMessageHandler.getResponseMessage(); } } try { queue.close(); debugMessage("Closed queue '" + queueName + "'", writers); } catch(Exception e) { errorMessage("Could not close '" + queueName + "': " + e.getMessage(), e, writers); } } } debugMessage("Close xslt provider listeners", writers); iterator = queues.keySet().iterator(); while (iterator.hasNext()) { String queueName = (String)iterator.next(); if ("nl.nn.adapterframework.testtool.XsltProviderListener".equals(properties.get(queueName + ".className"))) { XsltProviderListener xsltProviderListener = (XsltProviderListener)((Map)queues.get(queueName)).get("xsltProviderListener"); xsltProviderListenerCleanUp(queues, queueName, writers); debugMessage("Closed xslt provider listener '" + queueName + "'", writers); } } return remainingMessagesFound; } public static boolean jmsCleanUp(String queueName, PullingJmsListener pullingJmsListener, Map writers) { boolean remainingMessagesFound = false; debugMessage("Check for remaining messages on '" + queueName + "'", writers); long oldTimeOut = pullingJmsListener.getTimeOut(); pullingJmsListener.setTimeOut(10); boolean empty = false; while (!empty) { javax.jms.Message rawMessage = null; Message message = null; Map threadContext = null; try { threadContext = pullingJmsListener.openThread(); rawMessage = pullingJmsListener.getRawMessage(threadContext); if (rawMessage != null) { message = pullingJmsListener.extractMessage(rawMessage, threadContext); remainingMessagesFound = true; if (message == null) { errorMessage("Could not translate raw message from jms queue '" + queueName + "'", writers); } else { wrongPipelineMessage("Found remaining message on '" + queueName + "'", message.asString(), writers); } } } catch(ListenerException | IOException e) { errorMessage("ListenerException on jms clean up '" + queueName + "': " + e.getMessage(), e, writers); } finally { if (threadContext != null) { try { pullingJmsListener.closeThread(threadContext); } catch(ListenerException e) { errorMessage("Could not close thread on jms listener '" + queueName + "': " + e.getMessage(), e, writers); } } } if (rawMessage == null) { empty = true; } } pullingJmsListener.setTimeOut((int) oldTimeOut); return remainingMessagesFound; } public static boolean xsltProviderListenerCleanUp(Map> queues, String queueName, Map writers) { boolean remainingMessagesFound = false; Map xsltProviderListenerInfo = (Map)queues.get(queueName); XsltProviderListener xsltProviderListener = (XsltProviderListener)xsltProviderListenerInfo.get("xsltProviderListener"); String message = xsltProviderListener.getResult(); if (message != null) { remainingMessagesFound = true; wrongPipelineMessage("Found remaining message on '" + queueName + "'", message, writers); } return remainingMessagesFound; } private static int executeJmsSenderWrite(String stepDisplayName, Map> queues, Map writers, String queueName, String fileContent, String correlationId) { int result = RESULT_ERROR; Map jmsSenderInfo = (Map)queues.get(queueName); JmsSender jmsSender = (JmsSender)jmsSenderInfo.get("jmsSender"); try { String providedCorrelationId = null; String useCorrelationIdFrom = (String)jmsSenderInfo.get("useCorrelationIdFrom"); if (useCorrelationIdFrom != null) { Map listenerInfo = (Map)queues.get(useCorrelationIdFrom); if (listenerInfo == null) { errorMessage("Could not find listener '" + useCorrelationIdFrom + "' to use correlation id from", writers); } else { providedCorrelationId = (String)listenerInfo.get("correlationId"); if (providedCorrelationId == null) { errorMessage("Could not find correlation id from listener '" + useCorrelationIdFrom + "'", writers); } } } if (providedCorrelationId == null) { providedCorrelationId = (String)jmsSenderInfo.get("jmsCorrelationId"); } if (providedCorrelationId == null) { providedCorrelationId = correlationId; } jmsSender.sendMessage(new nl.nn.adapterframework.stream.Message(fileContent), null); debugPipelineMessage(stepDisplayName, "Successfully written to '" + queueName + "':", fileContent, writers); result = RESULT_OK; } catch(TimeoutException e) { errorMessage("Time out sending jms message to '" + queueName + "': " + e.getMessage(), e, writers); } catch(SenderException e) { errorMessage("Could not send jms message to '" + queueName + "': " + e.getMessage(), e, writers); } return result; } private static int executeSenderWrite(String stepDisplayName, Map> queues, Map writers, String queueName, String senderType, String fileContent, String correlationId) { int result = RESULT_ERROR; Map senderInfo = (Map)queues.get(queueName); ISender sender = (ISender)senderInfo.get(senderType + "Sender"); Boolean convertExceptionToMessage = (Boolean)senderInfo.get("convertExceptionToMessage"); PipeLineSession session = (PipeLineSession)senderInfo.get("session"); SenderThread senderThread = new SenderThread(sender, fileContent, session, convertExceptionToMessage.booleanValue(), correlationId); senderThread.start(); senderInfo.put(senderType + "SenderThread", senderThread); if(senderInfo instanceof QueueWrapper) { ((QueueWrapper) senderInfo).setSenderThread(senderThread); } debugPipelineMessage(stepDisplayName, "Successfully started thread writing to '" + queueName + "':", fileContent, writers); logger.debug("Successfully started thread writing to '" + queueName + "'"); result = RESULT_OK; return result; } private static int executeJavaOrWebServiceListenerWrite(String stepDisplayName, Map> queues, Map writers, String queueName, String fileContent) { int result = RESULT_ERROR; Map listenerInfo = (Map)queues.get(queueName); ListenerMessageHandler listenerMessageHandler = (ListenerMessageHandler)listenerInfo.get("listenerMessageHandler"); if (listenerMessageHandler == null) { errorMessage("No ListenerMessageHandler found", writers); } else { String correlationId = null; Map context = new HashMap(); ListenerMessage requestListenerMessage = (ListenerMessage)listenerInfo.get("listenerMessage"); if (requestListenerMessage != null) { correlationId = requestListenerMessage.getCorrelationId(); context = requestListenerMessage.getContext(); } ListenerMessage listenerMessage = new ListenerMessage(correlationId, fileContent, context); listenerMessageHandler.putResponseMessage(listenerMessage); debugPipelineMessage(stepDisplayName, "Successfully put message on '" + queueName + "':", fileContent, writers); logger.debug("Successfully put message on '" + queueName + "'"); result = RESULT_OK; } return result; } private static int executeFileSenderWrite(String stepDisplayName, Map> queues, Map writers, String queueName, String fileContent) { int result = RESULT_ERROR; Map fileSenderInfo = (Map)queues.get(queueName); FileSender fileSender = (FileSender)fileSenderInfo.get("fileSender"); try { fileSender.sendMessage(fileContent); debugPipelineMessage(stepDisplayName, "Successfully written to '" + queueName + "':", fileContent, writers); result = RESULT_OK; } catch(Exception e) { errorMessage("Exception writing to file: " + e.getMessage(), e, writers); } return result; } private static int executeDelaySenderWrite(String stepDisplayName, Map> queues, Map writers, String queueName, String fileContent) { int result = RESULT_ERROR; Map delaySenderInfo = (Map)queues.get(queueName); DelaySender delaySender = (DelaySender)delaySenderInfo.get("delaySender"); try { delaySender.sendMessage(new nl.nn.adapterframework.stream.Message(fileContent), null); debugPipelineMessage(stepDisplayName, "Successfully written to '" + queueName + "':", fileContent, writers); result = RESULT_OK; } catch(Exception e) { errorMessage("Exception writing to file: " + e.getMessage(), e, writers); } return result; } private static int executeXsltProviderListenerWrite(String step, String stepDisplayName, Map> queues, Map writers, String queueName, String fileName, String fileContent, Properties properties) { int result = RESULT_ERROR; Map xsltProviderListenerInfo = (Map)queues.get(queueName); XsltProviderListener xsltProviderListener = (XsltProviderListener)xsltProviderListenerInfo.get("xsltProviderListener"); String message = xsltProviderListener.getResult(); if (message == null) { if ("".equals(fileName)) { result = RESULT_OK; } else { errorMessage("Could not read result (null returned)", writers); } } else { result = compareResult(step, stepDisplayName, fileName, fileContent, message, properties, writers, queueName); } return result; } private static int executeJmsListenerRead(String step, String stepDisplayName, Properties properties, Map> queues, Map writers, String queueName, String fileName, String fileContent) { int result = RESULT_ERROR; Map jmsListenerInfo = (Map)queues.get(queueName); PullingJmsListener pullingJmsListener = (PullingJmsListener)jmsListenerInfo.get("jmsListener"); Map threadContext = null; Message message = null; try { threadContext = pullingJmsListener.openThread(); javax.jms.Message rawMessage = pullingJmsListener.getRawMessage(threadContext); if (rawMessage != null) { message = pullingJmsListener.extractMessage(rawMessage, threadContext); String correlationId = pullingJmsListener.getIdFromRawMessage(rawMessage, threadContext); jmsListenerInfo.put("correlationId", correlationId); } } catch(ListenerException e) { if (!"".equals(fileName)) { errorMessage("Could not read jms message from '" + queueName + "': " + e.getMessage(), e, writers); } } finally { if (threadContext != null) { try { pullingJmsListener.closeThread(threadContext); } catch(ListenerException e) { errorMessage("Could not close thread on jms listener '" + queueName + "': " + e.getMessage(), e, writers); } } } if (message == null || message.isEmpty()) { if ("".equals(fileName)) { result = RESULT_OK; } else { errorMessage("Could not read jms message (null returned)", writers); } } else { try { result = compareResult(step, stepDisplayName, fileName, fileContent, message.asString(), properties, writers, queueName); } catch (IOException e) { errorMessage("Could not convert jms message from '" + queueName + "' to string: " + e.getMessage(), e, writers); } } return result; } private static int executeSenderRead(String step, String stepDisplayName, Properties properties, Map> queues, Map writers, String queueName, String senderType, String fileName, String fileContent) { int result = RESULT_ERROR; Map senderInfo = (Map)queues.get(queueName); SenderThread senderThread = (SenderThread)senderInfo.remove(senderType + "SenderThread"); if(senderInfo instanceof QueueWrapper) { ((QueueWrapper) senderInfo).removeSenderThread(); } if (senderThread == null) { errorMessage("No SenderThread found, no " + senderType + "Sender.write request?", writers); } else { SenderException senderException = senderThread.getSenderException(); if (senderException == null) { IOException ioException = senderThread.getIOException(); if (ioException == null) { TimeoutException timeOutException = senderThread.getTimeOutException(); if (timeOutException == null) { String message = senderThread.getResponse(); if (message == null) { if ("".equals(fileName)) { result = RESULT_OK; } else { errorMessage("Could not read " + senderType + "Sender message (null returned)", writers); } } else { if ("".equals(fileName)) { debugPipelineMessage(stepDisplayName, "Unexpected message read from '" + queueName + "':", message, writers); } else { result = compareResult(step, stepDisplayName, fileName, fileContent, message, properties, writers, queueName); } } } else { errorMessage("Could not read " + senderType + "Sender message (TimeOutException): " + timeOutException.getMessage(), timeOutException, writers); } } else { errorMessage("Could not read " + senderType + "Sender message (IOException): " + ioException.getMessage(), ioException, writers); } } else { errorMessage("Could not read " + senderType + "Sender message (SenderException): " + senderException.getMessage(), senderException, writers); } } return result; } private static int executeJavaListenerOrWebServiceListenerRead(String step, String stepDisplayName, Properties properties, Map> queues, Map writers, String queueName, String fileName, String fileContent, int parameterTimeout) { int result = RESULT_ERROR; Map listenerInfo = (Map)queues.get(queueName); ListenerMessageHandler listenerMessageHandler = (ListenerMessageHandler)listenerInfo.get("listenerMessageHandler"); if (listenerMessageHandler == null) { errorMessage("No ListenerMessageHandler found", writers); } else { String message = null; ListenerMessage listenerMessage = null; Long timeout = Long.parseLong(""+parameterTimeout); try { timeout = Long.parseLong((String) properties.get(queueName + ".timeout")); debugMessage("Timeout set to '" + timeout + "'", writers); } catch (Exception e) { } try { listenerMessage = listenerMessageHandler.getRequestMessage(timeout); } catch (TimeoutException e) { errorMessage("Could not read listenerMessageHandler message (timeout of ["+parameterTimeout+"] reached)", writers); return RESULT_ERROR; } if (listenerMessage != null) { message = listenerMessage.getMessage(); listenerInfo.put("listenerMessage", listenerMessage); } if (message == null) { if ("".equals(fileName)) { result = RESULT_OK; } else { errorMessage("Could not read listenerMessageHandler message (null returned)", writers); } } else { if ("".equals(fileName)) { debugPipelineMessage(stepDisplayName, "Unexpected message read from '" + queueName + "':", message, writers); } else { result = compareResult(step, stepDisplayName, fileName, fileContent, message, properties, writers, queueName); if (result!=RESULT_OK) { // Send a clean up reply because there is probably a // thread waiting for a reply String correlationId = null; Map context = new HashMap(); listenerMessage = new ListenerMessage(correlationId, TESTTOOL_CLEAN_UP_REPLY, context); listenerMessageHandler.putResponseMessage(listenerMessage); } } } } return result; } private static int executeFixedQuerySenderRead(String step, String stepDisplayName, Properties properties, Map> queues, Map writers, String queueName, String fileName, String fileContent, String correlationId) { int result = RESULT_ERROR; Map querySendersInfo = (Map)queues.get(queueName); Integer waitBeforeRead = (Integer)querySendersInfo.get("readQueryWaitBeforeRead"); if (waitBeforeRead != null) { try { Thread.sleep(waitBeforeRead.intValue()); } catch(InterruptedException e) { } } boolean newRecordFound = true; FixedQuerySender prePostFixedQuerySender = (FixedQuerySender)querySendersInfo.get("prePostQueryFixedQuerySender"); if (prePostFixedQuerySender != null) { try { String preResult = (String)querySendersInfo.get("prePostQueryResult"); debugPipelineMessage(stepDisplayName, "Pre result '" + queueName + "':", preResult, writers); PipeLineSession session = new PipeLineSession(); session.put(PipeLineSession.businessCorrelationIdKey, correlationId); String postResult = prePostFixedQuerySender.sendMessage(TESTTOOL_DUMMY_MESSAGE, session).asString(); debugPipelineMessage(stepDisplayName, "Post result '" + queueName + "':", postResult, writers); if (preResult.equals(postResult)) { newRecordFound = false; } /* Fill the preResult with postResult, so closeQueues is able to determine if there * are remaining messages left. */ querySendersInfo.put("prePostQueryResult", postResult); } catch(TimeoutException e) { errorMessage("Time out on execute query for '" + queueName + "': " + e.getMessage(), e, writers); } catch(IOException | SenderException e) { errorMessage("Could not execute query for '" + queueName + "': " + e.getMessage(), e, writers); } } String message = null; if (newRecordFound) { FixedQuerySender readQueryFixedQuerySender = (FixedQuerySender)querySendersInfo.get("readQueryQueryFixedQuerySender"); try { PipeLineSession session = new PipeLineSession(); session.put(PipeLineSession.businessCorrelationIdKey, correlationId); message = readQueryFixedQuerySender.sendMessage(TESTTOOL_DUMMY_MESSAGE, session).asString(); } catch(TimeoutException e) { errorMessage("Time out on execute query for '" + queueName + "': " + e.getMessage(), e, writers); } catch(IOException | SenderException e) { errorMessage("Could not execute query for '" + queueName + "': " + e.getMessage(), e, writers); } } if (message == null) { if ("".equals(fileName)) { result = RESULT_OK; } else { errorMessage("Could not read jdbc message (null returned) or no new message found (pre result equals post result)", writers); } } else { if ("".equals(fileName)) { debugPipelineMessage(stepDisplayName, "Unexpected message read from '" + queueName + "':", message, writers); } else { result = compareResult(step, stepDisplayName, fileName, fileContent, message, properties, writers, queueName); } } return result; } private static int executeFileListenerRead(String step, String stepDisplayName, Properties properties, Map> queues, Map writers, String queueName, String fileName, String fileContent) { int result = RESULT_ERROR; Map fileListenerInfo = (Map)queues.get(queueName); FileListener fileListener = (FileListener)fileListenerInfo.get("fileListener"); String message = null; try { message = fileListener.getMessage(); } catch(Exception e) { if (!"".equals(fileName)) { errorMessage("Could not read file from '" + queueName + "': " + e.getMessage(), e, writers); } } if (message == null) { if ("".equals(fileName)) { result = RESULT_OK; } else { errorMessage("Could not read file (null returned)", writers); } } else { result = compareResult(step, stepDisplayName, fileName, fileContent, message, properties, writers, queueName); } return result; } private static int executeFileSenderRead(String step, String stepDisplayName, Properties properties, Map> queues, Map writers, String queueName, String fileName, String fileContent) { int result = RESULT_ERROR; Map fileSenderInfo = (Map)queues.get(queueName); FileSender fileSender = (FileSender)fileSenderInfo.get("fileSender"); String message = null; try { message = fileSender.getMessage(); } catch(Exception e) { if (!"".equals(fileName)) { errorMessage("Could not read file from '" + queueName + "': " + e.getMessage(), e, writers); } } if (message == null) { if ("".equals(fileName)) { result = RESULT_OK; } else { errorMessage("Could not read file (null returned)", writers); } } else { result = compareResult(step, stepDisplayName, fileName, fileContent, message, properties, writers, queueName); } return result; } private static int executeXsltProviderListenerRead(String stepDisplayName, Properties properties, Map> queues, Map writers, String queueName, String fileContent, Map xsltParameters) { int result = RESULT_ERROR; Map xsltProviderListenerInfo = (Map)queues.get(queueName); if (xsltProviderListenerInfo == null) { errorMessage("No info found for xslt provider listener '" + queueName + "'", writers); } else { XsltProviderListener xsltProviderListener = (XsltProviderListener)xsltProviderListenerInfo.get("xsltProviderListener"); if (xsltProviderListener == null) { errorMessage("XSLT provider listener not found for '" + queueName + "'", writers); } else { try { xsltProviderListener.processRequest(fileContent, xsltParameters); result = RESULT_OK; } catch(ListenerException e) { errorMessage("Could not transform xml: " + e.getMessage(), e, writers); } debugPipelineMessage(stepDisplayName, "Result:", fileContent, writers); } } return result; } public static int executeStep(String step, Properties properties, String stepDisplayName, Map> queues, Map writers, int parameterTimeout, String correlationId) { int stepPassed = RESULT_ERROR; String fileName = properties.getProperty(step); String fileNameAbsolutePath = properties.getProperty(step + ".absolutepath"); int i = step.indexOf('.'); String queueName; String fileContent; // vul globale var zeefVijlNeem = fileNameAbsolutePath; //inlezen file voor deze stap if ("".equals(fileName)) { errorMessage("No file specified for step '" + step + "'", writers); } else { if (step.endsWith("readline") || step.endsWith("writeline")) { fileContent = fileName; } else { if (fileName.endsWith("ignore")) { debugMessage("creating dummy expected file for filename '"+fileName+"'", writers); fileContent = "ignore"; } else { debugMessage("Read file " + fileName, writers); fileContent = readFile(fileNameAbsolutePath, writers); } } if (fileContent == null) { errorMessage("Could not read file '" + fileName + "'", writers); } else { queueName = step.substring(i + 1, step.lastIndexOf(".")); if (step.endsWith(".read") || (allowReadlineSteps && step.endsWith(".readline"))) { if ("nl.nn.adapterframework.jms.JmsListener".equals(properties.get(queueName + ".className"))) { stepPassed = executeJmsListenerRead(step, stepDisplayName, properties, queues, writers, queueName, fileName, fileContent); } else if ("nl.nn.adapterframework.jdbc.FixedQuerySender".equals(properties.get(queueName + ".className"))) { stepPassed = executeFixedQuerySenderRead(step, stepDisplayName, properties, queues, writers, queueName, fileName, fileContent, correlationId); } else if ("nl.nn.adapterframework.http.IbisWebServiceSender".equals(properties.get(queueName + ".className"))) { stepPassed = executeSenderRead(step, stepDisplayName, properties, queues, writers, queueName, "ibisWebService", fileName, fileContent); } else if ("nl.nn.adapterframework.http.WebServiceSender".equals(properties.get(queueName + ".className"))) { stepPassed = executeSenderRead(step, stepDisplayName, properties, queues, writers, queueName, "webService", fileName, fileContent); } else if ("nl.nn.adapterframework.http.WebServiceListener".equals(properties.get(queueName + ".className"))) { stepPassed = executeJavaListenerOrWebServiceListenerRead(step, stepDisplayName, properties, queues, writers, queueName, fileName, fileContent, parameterTimeout); } else if ("nl.nn.adapterframework.http.HttpSender".equals(properties.get(queueName + ".className"))) { stepPassed = executeSenderRead(step, stepDisplayName, properties, queues, writers, queueName, "http", fileName, fileContent); } else if ("nl.nn.adapterframework.senders.IbisJavaSender".equals(properties.get(queueName + ".className"))) { stepPassed = executeSenderRead(step, stepDisplayName, properties, queues, writers, queueName, "ibisJava", fileName, fileContent); } else if ("nl.nn.adapterframework.receivers.JavaListener".equals(properties.get(queueName + ".className"))) { stepPassed = executeJavaListenerOrWebServiceListenerRead(step, stepDisplayName, properties, queues, writers, queueName, fileName, fileContent, parameterTimeout); } else if ("nl.nn.adapterframework.testtool.FileListener".equals(properties.get(queueName + ".className"))) { stepPassed = executeFileListenerRead(step, stepDisplayName, properties, queues, writers, queueName, fileName, fileContent); } else if ("nl.nn.adapterframework.testtool.FileSender".equals(properties.get(queueName + ".className"))) { stepPassed = executeFileSenderRead(step, stepDisplayName, properties, queues, writers, queueName, fileName, fileContent); } else if ("nl.nn.adapterframework.testtool.XsltProviderListener".equals(properties.get(queueName + ".className"))) { stepPassed = executeXsltProviderListenerRead(stepDisplayName, properties, queues, writers, queueName, fileContent, createParametersMapFromParamProperties(properties, step, writers, false, null)); } else { errorMessage("Property '" + queueName + ".className' not found or not valid", writers); } } else { String resolveProperties = properties.getProperty("scenario.resolveProperties"); if( resolveProperties == null || !resolveProperties.equalsIgnoreCase("false") ){ AppConstants appConstants = AppConstants.getInstance(); fileContent = StringResolver.substVars(fileContent, appConstants); } if ("nl.nn.adapterframework.jms.JmsSender".equals(properties.get(queueName + ".className"))) { stepPassed = executeJmsSenderWrite(stepDisplayName, queues, writers, queueName, fileContent, correlationId); } else if ("nl.nn.adapterframework.http.IbisWebServiceSender".equals(properties.get(queueName + ".className"))) { stepPassed = executeSenderWrite(stepDisplayName, queues, writers, queueName, "ibisWebService", fileContent, correlationId); } else if ("nl.nn.adapterframework.http.WebServiceSender".equals(properties.get(queueName + ".className"))) { stepPassed = executeSenderWrite(stepDisplayName, queues, writers, queueName, "webService", fileContent, correlationId); } else if ("nl.nn.adapterframework.http.WebServiceListener".equals(properties.get(queueName + ".className"))) { stepPassed = executeJavaOrWebServiceListenerWrite(stepDisplayName, queues, writers, queueName, fileContent); } else if ("nl.nn.adapterframework.http.HttpSender".equals(properties.get(queueName + ".className"))) { stepPassed = executeSenderWrite(stepDisplayName, queues, writers, queueName, "http", fileContent, correlationId); } else if ("nl.nn.adapterframework.senders.IbisJavaSender".equals(properties.get(queueName + ".className"))) { stepPassed = executeSenderWrite(stepDisplayName, queues, writers, queueName, "ibisJava", fileContent, correlationId); } else if ("nl.nn.adapterframework.receivers.JavaListener".equals(properties.get(queueName + ".className"))) { stepPassed = executeJavaOrWebServiceListenerWrite(stepDisplayName, queues, writers, queueName, fileContent); } else if ("nl.nn.adapterframework.testtool.FileSender".equals(properties.get(queueName + ".className"))) { stepPassed = executeFileSenderWrite(stepDisplayName, queues, writers, queueName, fileContent); } else if ("nl.nn.adapterframework.testtool.XsltProviderListener".equals(properties.get(queueName + ".className"))) { stepPassed = executeXsltProviderListenerWrite(step, stepDisplayName, queues, writers, queueName, fileName, fileContent, properties); } else if ("nl.nn.adapterframework.senders.DelaySender".equals(properties.get(queueName + ".className"))) { stepPassed = executeDelaySenderWrite(stepDisplayName, queues, writers, queueName, fileContent); } else { errorMessage("Property '" + queueName + ".className' not found or not valid", writers); } } } } return stepPassed; } public static String readFile(String fileName, Map writers) { String result = null; String encoding = null; if (fileName.endsWith(".xml") || fileName.endsWith(".wsdl")) { // Determine the encoding the XML way but don't use an XML parser to // read the file and transform it to a string to prevent changes in // formatting and prevent adding an xml declaration where this is // not present in the file. For example, when using a // WebServiceSender to send a message to a WebServiceListener the // xml message must not contain an xml declaration. try (InputStream in = new FileInputStream(fileName)) { XMLInputFactory factory = XMLInputFactory.newInstance(); XMLStreamReader parser = factory.createXMLStreamReader(in); encoding = parser.getEncoding(); parser.close(); } catch (IOException | XMLStreamException e) { errorMessage("Could not determine encoding for file '" + fileName + "': " + e.getMessage(), e, writers); } } else if (fileName.endsWith(".utf8") || fileName.endsWith(".json")) { encoding = "UTF-8"; } else { encoding = "ISO-8859-1"; } if (encoding != null) { Reader inputStreamReader = null; try { StringBuffer stringBuffer = new StringBuffer(); inputStreamReader = StreamUtil.getCharsetDetectingInputStreamReader(new FileInputStream(fileName), encoding); char[] cbuf = new char[4096]; int len = inputStreamReader.read(cbuf); while (len != -1) { stringBuffer.append(cbuf, 0, len); len = inputStreamReader.read(cbuf); } result = stringBuffer.toString(); } catch (Exception e) { errorMessage("Could not read file '" + fileName + "': " + e.getMessage(), e, writers); } finally { if (inputStreamReader != null) { try { inputStreamReader.close(); } catch(Exception e) { errorMessage("Could not close file '" + fileName + "': " + e.getMessage(), e, writers); } } } } return result; } // Used by saveResultToFile.jsp public static void windiff(ServletContext application, HttpServletRequest request, String expectedFileName, String result, String expected) throws IOException, SenderException { AppConstants appConstants = AppConstants.getInstance(); String windiffCommand = appConstants.getResolvedProperty("larva.windiff.command"); if (windiffCommand == null) { String servletPath = request.getServletPath(); int i = servletPath.lastIndexOf('/'); String realPath = application.getRealPath(servletPath.substring(0, i)); List scenariosRootDirectories = new ArrayList(); List scenariosRootDescriptions = new ArrayList(); String currentScenariosRootDirectory = TestTool.initScenariosRootDirectories( realPath, null, scenariosRootDirectories, scenariosRootDescriptions, null); windiffCommand = currentScenariosRootDirectory + "..\\..\\IbisAlgemeenWasbak\\WinDiff\\WinDiff.Exe"; } File tempFileResult = writeTempFile(expectedFileName, result); File tempFileExpected = writeTempFile(expectedFileName, expected); String command = windiffCommand + " " + tempFileResult + " " + tempFileExpected; ProcessUtil.executeCommand(command); } private static File writeTempFile(String originalFileName, String content) throws IOException { String encoding = getEncoding(originalFileName, content); String baseName = FileUtils.getBaseName(originalFileName); String extensie = FileUtils.getFileNameExtension(originalFileName); File tempFile = null; tempFile = File.createTempFile("ibistesttool", "."+extensie); tempFile.deleteOnExit(); String tempFileMessage; if (extensie.equalsIgnoreCase("XML")) { tempFileMessage = XmlUtils.canonicalize(content); } else { tempFileMessage = content; } OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(tempFile, true), encoding); outputStreamWriter.write(tempFileMessage); outputStreamWriter.close(); return tempFile; } // Used by saveResultToFile.jsp public static void writeFile(String fileName, String content) throws IOException { String encoding = getEncoding(fileName, content); OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(fileName), encoding); outputStreamWriter.write(content); outputStreamWriter.close(); } private static String getEncoding(String fileName, String content) { String encoding = null; if (fileName.endsWith(".xml") || fileName.endsWith(".wsdl")) { if (content.startsWith("") != -1) { String declaration = content.substring(0, content.indexOf("?>")); int encodingIndex = declaration.indexOf("encoding"); if (encodingIndex != -1) { int doubleQuoteIndex1 = declaration.indexOf('"', encodingIndex); int doubleQuoteIndex2 = -1; if (doubleQuoteIndex1 != -1) { doubleQuoteIndex2 = declaration.indexOf('"', doubleQuoteIndex1 + 1); } int singleQuoteIndex1 = declaration.indexOf('\'', encodingIndex); int singleQuoteIndex2 = -1; if (singleQuoteIndex1 != -1) { singleQuoteIndex2 = declaration.indexOf('\'', singleQuoteIndex1 + 1); } if (doubleQuoteIndex2 != -1 && (singleQuoteIndex2 == -1 || doubleQuoteIndex2 < singleQuoteIndex2)) { encoding = declaration.substring(doubleQuoteIndex1 + 1, doubleQuoteIndex2); } else if (singleQuoteIndex2 != -1) { encoding = declaration.substring(singleQuoteIndex1 + 1, singleQuoteIndex2); } } } if (encoding == null) { encoding = "UTF-8"; } } else if (fileName.endsWith(".utf8")) { encoding = "UTF-8"; } else { encoding = "ISO-8859-1"; } return encoding; } public static int compareResult(String step, String stepDisplayName, String fileName, String expectedResult, String actualResult, Properties properties, Map writers, String queueName) { if (fileName.endsWith("ignore")) { debugMessage("ignoring compare for filename '"+fileName+"'", writers); return RESULT_OK; } int ok = RESULT_ERROR; String printableExpectedResult; String printableActualResult; String diffType = properties.getProperty(step + ".diffType"); if ((diffType != null && diffType.equals(".json")) || (diffType == null && fileName.endsWith(".json"))) { printableExpectedResult = Misc.jsonPretty(expectedResult); printableActualResult = Misc.jsonPretty(actualResult); } else { printableExpectedResult = XmlUtils.replaceNonValidXmlCharacters(expectedResult); printableActualResult = XmlUtils.replaceNonValidXmlCharacters(actualResult); } String preparedExpectedResult = printableExpectedResult; String preparedActualResult = printableActualResult; // Map all identifier based properties once HashMap>> ignoreMap = mapPropertiesToIgnores(properties); /* numeric decodeUnzipContentBetweenKeys */ debugMessage("Check decodeUnzipContentBetweenKeys properties", writers); boolean decodeUnzipContentBetweenKeysProcessed = false; int i = 1; while (!decodeUnzipContentBetweenKeysProcessed) { String key1 = properties.getProperty("decodeUnzipContentBetweenKeys" + i + ".key1"); String key2 = properties.getProperty("decodeUnzipContentBetweenKeys" + i + ".key2"); boolean replaceNewlines = false; if ("true".equals(properties.getProperty("decodeUnzipContentBetweenKeys" + i + ".replaceNewlines"))) { replaceNewlines = true; } if (key1 != null && key2 != null) { debugMessage("Decode and unzip content between key1 '" + key1 + "' and key2 '" + key2 + "' (replaceNewlines is " + replaceNewlines + ")", writers); preparedExpectedResult = decodeUnzipContentBetweenKeys(preparedExpectedResult, key1, key2, replaceNewlines, writers); preparedActualResult = decodeUnzipContentBetweenKeys(preparedActualResult, key1, key2, replaceNewlines, writers); i++; } else { decodeUnzipContentBetweenKeysProcessed = true; } } /* identifier based decodeUnzipContentBetweenKeys */ HashMap> decodeUnzipContentBetweenKeys = ignoreMap.get("decodeUnzipContentBetweenKeys"); if (decodeUnzipContentBetweenKeys!=null) { Iterator decodeUnzipContentBetweenKeysIt = decodeUnzipContentBetweenKeys.entrySet().iterator(); while (decodeUnzipContentBetweenKeysIt.hasNext()) { Map.Entry decodeUnzipContentBetweenKeysEntry = (Map.Entry) decodeUnzipContentBetweenKeysIt.next(); HashMap decodeUnzipContentBetweenKeysPair = (HashMap) decodeUnzipContentBetweenKeysEntry.getValue(); String key1 = decodeUnzipContentBetweenKeysPair.get("key1"); String key2 = decodeUnzipContentBetweenKeysPair.get("key2"); boolean replaceNewlines = false; if ("true".equals(decodeUnzipContentBetweenKeysPair.get("replaceNewlines"))) { replaceNewlines = true; } if (key1 != null && key2 != null) { debugMessage("Decode and unzip content between key1 '" + key1 + "' and key2 '" + key2 + "' (replaceNewlines is " + replaceNewlines + ")", writers); preparedExpectedResult = decodeUnzipContentBetweenKeys(preparedExpectedResult, key1, key2, replaceNewlines, writers); preparedActualResult = decodeUnzipContentBetweenKeys(preparedActualResult, key1, key2, replaceNewlines, writers); i++; } else { decodeUnzipContentBetweenKeysProcessed = true; } decodeUnzipContentBetweenKeysIt.remove(); } } /* numeric canonicaliseFilePathContentBetweenKeys */ debugMessage("Check canonicaliseFilePathContentBetweenKeys properties", writers); boolean canonicaliseFilePathContentBetweenKeysProcessed = false; i = 1; while (!canonicaliseFilePathContentBetweenKeysProcessed) { String key1 = properties.getProperty("canonicaliseFilePathContentBetweenKeys" + i + ".key1"); String key2 = properties.getProperty("canonicaliseFilePathContentBetweenKeys" + i + ".key2"); if (key1 != null && key2 != null) { debugMessage("Canonicalise filepath content between key1 '" + key1 + "' and key2 '" + key2 + "'", writers); preparedExpectedResult = canonicaliseFilePathContentBetweenKeys(preparedExpectedResult, key1, key2, writers); preparedActualResult = canonicaliseFilePathContentBetweenKeys(preparedActualResult, key1, key2, writers); i++; } else { canonicaliseFilePathContentBetweenKeysProcessed = true; } } /* identifier based canonicaliseFilePathContentBetweenKeys */ HashMap> canonicaliseFilePathContentBetweenKeys = ignoreMap.get("canonicaliseFilePathContentBetweenKeys"); if (canonicaliseFilePathContentBetweenKeys!=null) { Iterator canonicaliseFilePathContentBetweenKeysIt = canonicaliseFilePathContentBetweenKeys.entrySet().iterator(); while (canonicaliseFilePathContentBetweenKeysIt.hasNext()) { Map.Entry canonicaliseFilePathContentBetweenKeysEntry = (Map.Entry) canonicaliseFilePathContentBetweenKeysIt.next(); HashMap canonicaliseFilePathContentBetweenKeysPair = (HashMap) canonicaliseFilePathContentBetweenKeysEntry.getValue(); String key1 = canonicaliseFilePathContentBetweenKeysPair.get("key1"); String key2 = canonicaliseFilePathContentBetweenKeysPair.get("key2"); debugMessage("Canonicalise filepath content between key1 '" + key1 + "' and key2 '" + key2 + "'", writers); preparedExpectedResult = canonicaliseFilePathContentBetweenKeys(preparedExpectedResult, key1, key2, writers); preparedActualResult = canonicaliseFilePathContentBetweenKeys(preparedActualResult, key1, key2, writers); canonicaliseFilePathContentBetweenKeysIt.remove(); } } /* numeric formatDecimalContentBetweenKeys */ debugMessage("Check formatDecimalContentBetweenKeys properties", writers); boolean formatDecimalContentBetweenKeysProcessed = false; i = 1; while (!formatDecimalContentBetweenKeysProcessed) { String key1 = properties.getProperty("formatDecimalContentBetweenKeys" + i + ".key1"); String key2 = properties.getProperty("formatDecimalContentBetweenKeys" + i + ".key2"); if (key1 != null && key2 != null) { debugMessage("Format decimal content between key1 '" + key1 + "' and key2 '" + key2 + "'", writers); preparedExpectedResult = formatDecimalContentBetweenKeys(preparedExpectedResult, key1, key2, writers); preparedActualResult = formatDecimalContentBetweenKeys(preparedActualResult, key1, key2, writers); i++; } else { formatDecimalContentBetweenKeysProcessed = true; } } /* identifier based formatDecimalContentBetweenKeys */ HashMap> formatDecimalContentBetweenKeys = ignoreMap.get("formatDecimalContentBetweenKeys"); if (formatDecimalContentBetweenKeys!=null) { Iterator formatDecimalContentBetweenKeysIt = formatDecimalContentBetweenKeys.entrySet().iterator(); while (formatDecimalContentBetweenKeysIt.hasNext()) { Map.Entry formatDecimalContentBetweenKeysEntry = (Map.Entry) formatDecimalContentBetweenKeysIt.next(); HashMap formatDecimalContentBetweenKeysPair = (HashMap) formatDecimalContentBetweenKeysEntry.getValue(); String key1 = formatDecimalContentBetweenKeysPair.get("key1"); String key2 = formatDecimalContentBetweenKeysPair.get("key2"); debugMessage("Format decimal content between key1 '" + key1 + "' and key2 '" + key2 + "'", writers); preparedExpectedResult = formatDecimalContentBetweenKeys(preparedExpectedResult, key1, key2, writers); preparedActualResult = formatDecimalContentBetweenKeys(preparedActualResult, key1, key2, writers); formatDecimalContentBetweenKeysIt.remove(); } } /* numeric ignoreRegularExpressionKey */ debugMessage("Check ignoreRegularExpressionKey properties", writers); boolean ignoreRegularExpressionKeyProcessed = false; i = 1; while (!ignoreRegularExpressionKeyProcessed) { String key = properties.getProperty("ignoreRegularExpressionKey" + i + ".key"); if (key != null) { debugMessage("Ignore regular expression key '" + key + "'", writers); preparedExpectedResult = ignoreRegularExpression(preparedExpectedResult, key); preparedActualResult = ignoreRegularExpression(preparedActualResult, key); i++; } else { ignoreRegularExpressionKeyProcessed = true; } } /* identifier based ignoreRegularExpressionKey */ HashMap> ignoreRegularExpressionKey = ignoreMap.get("ignoreRegularExpressionKey"); if (ignoreRegularExpressionKey!=null) { Iterator ignoreRegularExpressionKeyIt = ignoreRegularExpressionKey.entrySet().iterator(); while (ignoreRegularExpressionKeyIt.hasNext()) { Map.Entry ignoreRegularExpressionKeyEntry = (Map.Entry) ignoreRegularExpressionKeyIt.next(); HashMap ignoreRegularExpressionKeyItPair = (HashMap) ignoreRegularExpressionKeyEntry.getValue(); String key = ignoreRegularExpressionKeyItPair.get("key"); debugMessage("Ignore regular expression key '" + key + "'", writers); preparedExpectedResult = ignoreRegularExpression(preparedExpectedResult, key); preparedActualResult = ignoreRegularExpression(preparedActualResult, key); ignoreRegularExpressionKeyIt.remove(); } } /* numeric removeRegularExpressionKey */ debugMessage("Check removeRegularExpressionKey properties", writers); boolean removeRegularExpressionKeyProcessed = false; i = 1; while (!removeRegularExpressionKeyProcessed) { String key = properties.getProperty("removeRegularExpressionKey" + i + ".key"); if (key != null) { debugMessage("Remove regular expression key '" + key + "'", writers); preparedExpectedResult = removeRegularExpression(preparedExpectedResult, key); preparedActualResult = removeRegularExpression(preparedActualResult, key); i++; } else { removeRegularExpressionKeyProcessed = true; } } /* identifier based removeRegularExpressionKey */ HashMap> removeRegularExpressionKey = ignoreMap.get("removeRegularExpressionKey"); if (removeRegularExpressionKey!=null) { Iterator removeRegularExpressionKeyIt = removeRegularExpressionKey.entrySet().iterator(); while (removeRegularExpressionKeyIt.hasNext()) { Map.Entry removeRegularExpressionKeyEntry = (Map.Entry) removeRegularExpressionKeyIt.next(); HashMap removeRegularExpressionKeyPair = (HashMap) removeRegularExpressionKeyEntry.getValue(); String key = removeRegularExpressionKeyPair.get("key"); debugMessage("Remove regular expression key '" + key + "'", writers); preparedExpectedResult = removeRegularExpression(preparedExpectedResult, key); preparedActualResult = removeRegularExpression(preparedActualResult, key); removeRegularExpressionKeyIt.remove(); } } /* numeric replaceRegularExpressionKeys */ debugMessage("Check replaceRegularExpressionKeys properties", writers); boolean replaceRegularExpressionKeysProcessed = false; i = 1; while (!replaceRegularExpressionKeysProcessed) { String key1 = properties.getProperty("replaceRegularExpressionKeys" + i + ".key1"); String key2 = properties.getProperty("replaceRegularExpressionKeys" + i + ".key2"); if (key1 != null && key2 != null) { debugMessage("Replace regular expression from '" + key1 + "' to '" + key2 + "'", writers); preparedExpectedResult = replaceRegularExpression(preparedExpectedResult, key1, key2); preparedActualResult = replaceRegularExpression(preparedActualResult, key1, key2); i++; } else { replaceRegularExpressionKeysProcessed = true; } } /* identifier based replaceRegularExpressionKeys */ HashMap> replaceRegularExpressionKeys = ignoreMap.get("replaceRegularExpressionKeys"); if (replaceRegularExpressionKeys!=null) { Iterator replaceRegularExpressionKeysIt = replaceRegularExpressionKeys.entrySet().iterator(); while (replaceRegularExpressionKeysIt.hasNext()) { Map.Entry replaceRegularExpressionKeysEntry = (Map.Entry) replaceRegularExpressionKeysIt.next(); HashMap replaceRegularExpressionKeysPair = (HashMap) replaceRegularExpressionKeysEntry.getValue(); String key1 = replaceRegularExpressionKeysPair.get("key1"); String key2 = replaceRegularExpressionKeysPair.get("key2"); debugMessage("Replace regular expression from '" + key1 + "' to '" + key2 + "'", writers); preparedExpectedResult = replaceRegularExpression(preparedExpectedResult, key1, key2); preparedActualResult = replaceRegularExpression(preparedActualResult, key1, key2); replaceRegularExpressionKeysIt.remove(); } } /* numeric ignoreContentBetweenKeys */ debugMessage("Check ignoreContentBetweenKeys properties", writers); boolean ignoreContentBetweenKeysProcessed = false; i = 1; while (!ignoreContentBetweenKeysProcessed) { String key1 = properties.getProperty("ignoreContentBetweenKeys" + i + ".key1"); String key2 = properties.getProperty("ignoreContentBetweenKeys" + i + ".key2"); if (key1 != null && key2 != null) { debugMessage("Ignore content between key1 '" + key1 + "' and key2 '" + key2 + "'", writers); preparedExpectedResult = ignoreContentBetweenKeys(preparedExpectedResult, key1, key2); preparedActualResult = ignoreContentBetweenKeys(preparedActualResult, key1, key2); i++; } else { ignoreContentBetweenKeysProcessed = true; } } /* identifier based ignoreContentBetweenKeys */ HashMap> ignoreContentBetweenKeys = ignoreMap.get("ignoreContentBetweenKeys"); if (ignoreContentBetweenKeys!=null) { Iterator ignoreContentBetweenKeysIt = ignoreContentBetweenKeys.entrySet().iterator(); while (ignoreContentBetweenKeysIt.hasNext()) { Map.Entry ignoreContentBetweenKeysEntry = (Map.Entry) ignoreContentBetweenKeysIt.next(); HashMap ignoreContentBetweenKeysPair = (HashMap) ignoreContentBetweenKeysEntry.getValue(); String key1 = ignoreContentBetweenKeysPair.get("key1"); String key2 = ignoreContentBetweenKeysPair.get("key2"); debugMessage("Ignore content between key1 '" + key1 + "' and key2 '" + key2 + "'", writers); preparedExpectedResult = ignoreContentBetweenKeys(preparedExpectedResult, key1, key2); preparedActualResult = ignoreContentBetweenKeys(preparedActualResult, key1, key2); ignoreContentBetweenKeysIt.remove(); } } /* numeric ignoreKeysAndContentBetweenKeys */ debugMessage("Check ignoreKeysAndContentBetweenKeys properties", writers); boolean ignoreKeysAndContentBetweenKeysProcessed = false; i = 1; while (!ignoreKeysAndContentBetweenKeysProcessed) { String key1 = properties.getProperty("ignoreKeysAndContentBetweenKeys" + i + ".key1"); String key2 = properties.getProperty("ignoreKeysAndContentBetweenKeys" + i + ".key2"); if (key1 != null && key2 != null) { debugMessage("Ignore keys and content between key1 '" + key1 + "' and key2 '" + key2 + "'", writers); preparedExpectedResult = ignoreKeysAndContentBetweenKeys(preparedExpectedResult, key1, key2); preparedActualResult = ignoreKeysAndContentBetweenKeys(preparedActualResult, key1, key2); i++; } else { ignoreKeysAndContentBetweenKeysProcessed = true; } } /* identifier based ignoreKeysAndContentBetweenKeys */ HashMap> ignoreKeysAndContentBetweenKeys = ignoreMap.get("ignoreKeysAndContentBetweenKeys"); if (ignoreKeysAndContentBetweenKeys!=null) { Iterator ignoreKeysAndContentBetweenKeysIt = ignoreKeysAndContentBetweenKeys.entrySet().iterator(); while (ignoreKeysAndContentBetweenKeysIt.hasNext()) { Map.Entry ignoreKeysAndContentBetweenKeysEntry = (Map.Entry) ignoreKeysAndContentBetweenKeysIt.next(); HashMap ignoreKeysAndContentBetweenKeysPair = (HashMap) ignoreKeysAndContentBetweenKeysEntry.getValue(); String key1 = ignoreKeysAndContentBetweenKeysPair.get("key1"); String key2 = ignoreKeysAndContentBetweenKeysPair.get("key2"); debugMessage("Ignore keys and content between key1 '" + key1 + "' and key2 '" + key2 + "'", writers); preparedExpectedResult = ignoreKeysAndContentBetweenKeys(preparedExpectedResult, key1, key2); preparedActualResult = ignoreKeysAndContentBetweenKeys(preparedActualResult, key1, key2); ignoreKeysAndContentBetweenKeysIt.remove(); } } /* numeric removeKeysAndContentBetweenKeys */ debugMessage("Check removeKeysAndContentBetweenKeys properties", writers); boolean removeKeysAndContentBetweenKeysProcessed = false; i = 1; while (!removeKeysAndContentBetweenKeysProcessed) { String key1 = properties.getProperty("removeKeysAndContentBetweenKeys" + i + ".key1"); String key2 = properties.getProperty("removeKeysAndContentBetweenKeys" + i + ".key2"); if (key1 != null && key2 != null) { debugMessage("Remove keys and content between key1 '" + key1 + "' and key2 '" + key2 + "'", writers); preparedExpectedResult = removeKeysAndContentBetweenKeys(preparedExpectedResult, key1, key2); preparedActualResult = removeKeysAndContentBetweenKeys(preparedActualResult, key1, key2); i++; } else { removeKeysAndContentBetweenKeysProcessed = true; } } /* identifier based removeKeysAndContentBetweenKeys */ HashMap> removeKeysAndContentBetweenKeys = ignoreMap.get("removeKeysAndContentBetweenKeys"); if (removeKeysAndContentBetweenKeys!=null) { Iterator removeKeysAndContentBetweenKeysIt = removeKeysAndContentBetweenKeys.entrySet().iterator(); while (removeKeysAndContentBetweenKeysIt.hasNext()) { Map.Entry removeKeysAndContentBetweenKeysEntry = (Map.Entry) removeKeysAndContentBetweenKeysIt.next(); HashMap removeKeysAndContentBetweenKeysPair = (HashMap) removeKeysAndContentBetweenKeysEntry.getValue(); String key1 = removeKeysAndContentBetweenKeysPair.get("key1"); String key2 = removeKeysAndContentBetweenKeysPair.get("key2"); debugMessage("Remove keys and content between key1 '" + key1 + "' and key2 '" + key2 + "'", writers); preparedExpectedResult = removeKeysAndContentBetweenKeys(preparedExpectedResult, key1, key2); preparedActualResult = removeKeysAndContentBetweenKeys(preparedActualResult, key1, key2); removeKeysAndContentBetweenKeysIt.remove(); } } /* numeric ignoreKey */ debugMessage("Check ignoreKey properties", writers); boolean ignoreKeyProcessed = false; i = 1; while (!ignoreKeyProcessed) { String key = properties.getProperty("ignoreKey" + i); if (key != null) { debugMessage("Ignore key '" + key + "'", writers); preparedExpectedResult = ignoreKey(preparedExpectedResult, key); preparedActualResult = ignoreKey(preparedActualResult, key); i++; } else { ignoreKeyProcessed = true; } } /* identifier based ignoreKey */ HashMap> ignoreKey = ignoreMap.get("ignoreKey"); if (ignoreKey!=null) { Iterator ignoreKeyIt = ignoreKey.entrySet().iterator(); while (ignoreKeyIt.hasNext()) { Map.Entry ignoreKeyEntry = (Map.Entry) ignoreKeyIt.next(); HashMap ignoreKeyPair = (HashMap) ignoreKeyEntry.getValue(); String key = ignoreKeyPair.get("value"); debugMessage("Ignore key '" + key + "'", writers); preparedExpectedResult = ignoreKey(preparedExpectedResult, key); preparedActualResult = ignoreKey(preparedActualResult, key); ignoreKeyIt.remove(); } } /* numeric removeKey */ debugMessage("Check removeKey properties", writers); boolean removeKeyProcessed = false; i = 1; while (!removeKeyProcessed) { String key = properties.getProperty("removeKey" + i); if (key != null) { debugMessage("Remove key '" + key + "'", writers); preparedExpectedResult = removeKey(preparedExpectedResult, key); preparedActualResult = removeKey(preparedActualResult, key); i++; } else { removeKeyProcessed = true; } } /* identifier based removeKey */ HashMap> removeKey = ignoreMap.get("removeKey"); if (removeKey!=null) { Iterator removeKeyIt = removeKey.entrySet().iterator(); while (removeKeyIt.hasNext()) { Map.Entry removeKeyEntry = (Map.Entry) removeKeyIt.next(); HashMap removeKeyPair = (HashMap) removeKeyEntry.getValue(); String key = removeKeyPair.get("value"); debugMessage("Remove key '" + key + "'", writers); preparedExpectedResult = removeKey(preparedExpectedResult, key); preparedActualResult = removeKey(preparedActualResult, key); removeKeyIt.remove(); } } /* numeric replaceKey */ debugMessage("Check replaceKey properties", writers); boolean replaceKeyProcessed = false; i = 1; while (!replaceKeyProcessed) { String key1 = properties.getProperty("replaceKey" + i + ".key1"); String key2 = properties.getProperty("replaceKey" + i + ".key2"); if (key1 != null && key2 != null) { debugMessage("Replace key from '" + key1 + "' to '" + key2 + "'", writers); preparedExpectedResult = replaceKey(preparedExpectedResult, key1, key2); preparedActualResult = replaceKey(preparedActualResult, key1, key2); i++; } else { replaceKeyProcessed = true; } } /* identifier based replaceKey */ HashMap> replaceKey = ignoreMap.get("replaceKey"); if (replaceKey!=null) { Iterator replaceKeyIt = replaceKey.entrySet().iterator(); while (replaceKeyIt.hasNext()) { Map.Entry replaceKeyEntry = (Map.Entry) replaceKeyIt.next(); HashMap replaceKeyPair = (HashMap) replaceKeyEntry.getValue(); String key1 = replaceKeyPair.get("key1"); String key2 = replaceKeyPair.get("key2"); debugMessage("Replace key from '" + key1 + "' to '" + key2 + "'", writers); preparedExpectedResult = replaceKey(preparedExpectedResult, key1, key2); preparedActualResult = replaceKey(preparedActualResult, key1, key2); replaceKeyIt.remove(); } } /* numeric replaceEverywhereKey */ debugMessage("Check replaceEverywhereKey properties", writers); boolean replaceEverywhereKeyProcessed = false; i = 1; while (!replaceEverywhereKeyProcessed) { String key1 = properties.getProperty("replaceEverywhereKey" + i + ".key1"); String key2 = properties.getProperty("replaceEverywhereKey" + i + ".key2"); if (key1 != null && key2 != null) { debugMessage("Replace key from '" + key1 + "' to '" + key2 + "'", writers); preparedExpectedResult = replaceKey(preparedExpectedResult, key1, key2); preparedActualResult = replaceKey(preparedActualResult, key1, key2); i++; } else { replaceEverywhereKeyProcessed = true; } } /* identifier based replaceEverywhereKey */ HashMap> replaceEverywhereKey = ignoreMap.get("replaceEverywhereKey"); if (replaceEverywhereKey!=null) { Iterator replaceEverywhereKeyIt = replaceEverywhereKey.entrySet().iterator(); while (replaceEverywhereKeyIt.hasNext()) { Map.Entry replaceEverywhereKeyEntry = (Map.Entry) replaceEverywhereKeyIt.next(); HashMap replaceEverywhereKeyPair = (HashMap) replaceEverywhereKeyEntry.getValue(); String key1 = replaceEverywhereKeyPair.get("key1"); String key2 = replaceEverywhereKeyPair.get("key2"); debugMessage("Replace key from '" + key1 + "' to '" + key2 + "'", writers); preparedExpectedResult = replaceKey(preparedExpectedResult, key1, key2); preparedActualResult = replaceKey(preparedActualResult, key1, key2); replaceEverywhereKeyIt.remove(); } } /* numeric ignoreCurrentTimeBetweenKeys */ debugMessage("Check ignoreCurrentTimeBetweenKeys properties", writers); boolean ignoreCurrentTimeBetweenKeysProcessed = false; i = 1; while (!ignoreCurrentTimeBetweenKeysProcessed) { String key1 = properties.getProperty("ignoreCurrentTimeBetweenKeys" + i + ".key1"); String key2 = properties.getProperty("ignoreCurrentTimeBetweenKeys" + i + ".key2"); String pattern = properties.getProperty("ignoreCurrentTimeBetweenKeys" + i + ".pattern"); String margin = properties.getProperty("ignoreCurrentTimeBetweenKeys" + i + ".margin"); boolean errorMessageOnRemainingString = true; if ("false".equals(properties.getProperty("ignoreCurrentTimeBetweenKeys" + i + ".errorMessageOnRemainingString"))) { errorMessageOnRemainingString = false; } if (key1 != null && key2 != null && margin != null) { debugMessage("Ignore current time between key1 '" + key1 + "' and key2 '" + key2 + "' (errorMessageOnRemainingString is " + errorMessageOnRemainingString + ")", writers); debugMessage("For result string", writers); preparedActualResult = ignoreCurrentTimeBetweenKeys(preparedActualResult, key1, key2, pattern, margin, errorMessageOnRemainingString, false, writers); debugMessage("For expected string", writers); preparedExpectedResult = ignoreCurrentTimeBetweenKeys(preparedExpectedResult, key1, key2, pattern, margin, errorMessageOnRemainingString, true, writers); i++; } else { ignoreCurrentTimeBetweenKeysProcessed = true; } } /* identifier based ignoreCurrentTimeBetweenKeys */ HashMap> ignoreCurrentTimeBetweenKeys = ignoreMap.get("ignoreCurrentTimeBetweenKeys"); if (ignoreCurrentTimeBetweenKeys!=null) { Iterator ignoreCurrentTimeBetweenKeysIt = ignoreCurrentTimeBetweenKeys.entrySet().iterator(); while (ignoreCurrentTimeBetweenKeysIt.hasNext()) { Map.Entry ignoreCurrentTimeBetweenKeysEntry = (Map.Entry) ignoreCurrentTimeBetweenKeysIt.next(); HashMap ignoreCurrentTimeBetweenKeysPair = (HashMap) ignoreCurrentTimeBetweenKeysEntry.getValue(); String key1 = ignoreCurrentTimeBetweenKeysPair.get("key1"); String key2 = ignoreCurrentTimeBetweenKeysPair.get("key2"); String pattern = ignoreCurrentTimeBetweenKeysPair.get("pattern"); String margin = ignoreCurrentTimeBetweenKeysPair.get("margin"); boolean errorMessageOnRemainingString = true; if ("false".equals(ignoreCurrentTimeBetweenKeysPair.get("errorMessageOnRemainingString"))) { errorMessageOnRemainingString = false; } debugMessage("Ignore current time between key1 '" + key1 + "' and key2 '" + key2 + "' (errorMessageOnRemainingString is " + errorMessageOnRemainingString + ")", writers); debugMessage("For result string", writers); preparedActualResult = ignoreCurrentTimeBetweenKeys(preparedActualResult, key1, key2, pattern, margin, errorMessageOnRemainingString, false, writers); debugMessage("For expected string", writers); preparedExpectedResult = ignoreCurrentTimeBetweenKeys(preparedExpectedResult, key1, key2, pattern, margin, errorMessageOnRemainingString, true, writers); ignoreCurrentTimeBetweenKeysIt.remove(); } } /* numeric ignoreContentBeforeKey */ debugMessage("Check ignoreContentBeforeKey properties", writers); boolean ignoreContentBeforeKeyProcessed = false; i = 1; while (!ignoreContentBeforeKeyProcessed) { String key = properties.getProperty("ignoreContentBeforeKey" + i); if (key == null) { key = properties.getProperty("ignoreContentBeforeKey" + i + ".key"); } if (key != null) { debugMessage("Ignore content before key '" + key + "'", writers); preparedExpectedResult = ignoreContentBeforeKey(preparedExpectedResult, key); preparedActualResult = ignoreContentBeforeKey(preparedActualResult, key); i++; } else { ignoreContentBeforeKeyProcessed = true; } } /* identifier based ignoreContentBeforeKey */ HashMap> ignoreContentBeforeKey = ignoreMap.get("ignoreContentBeforeKey"); // merge all without .key attribute as well // TODO: ignoreContentBeforeKey.putAll(mapPropertiesByIdentifier("ignoreContentBeforeKey", properties, new ArrayList())); if (ignoreContentBeforeKey!=null) { Iterator ignoreContentBeforeKeyIt = ignoreContentBeforeKey.entrySet().iterator(); while (ignoreContentBeforeKeyIt.hasNext()) { Map.Entry ignoreContentBeforeKeyEntry = (Map.Entry) ignoreContentBeforeKeyIt.next(); HashMap ignoreContentBeforeKeyPair = (HashMap) ignoreContentBeforeKeyEntry.getValue(); String key = ignoreContentBeforeKeyPair.get("key"); if (key == null) { key = ignoreContentBeforeKeyPair.get("value"); } debugMessage("Ignore content before key '" + key + "'", writers); preparedExpectedResult = ignoreContentBeforeKey(preparedExpectedResult, key); preparedActualResult = ignoreContentBeforeKey(preparedActualResult, key); ignoreContentBeforeKeyIt.remove(); } } /* numeric ignoreContentAfterKey */ debugMessage("Check ignoreContentAfterKey properties", writers); boolean ignoreContentAfterKeyProcessed = false; i = 1; while (!ignoreContentAfterKeyProcessed) { String key = properties.getProperty("ignoreContentAfterKey" + i); if (key == null) { key = properties.getProperty("ignoreContentAfterKey" + i + ".key"); } if (key != null) { debugMessage("Ignore content after key '" + key + "'", writers); preparedExpectedResult = ignoreContentAfterKey(preparedExpectedResult, key); preparedActualResult = ignoreContentAfterKey(preparedActualResult, key); i++; } else { ignoreContentAfterKeyProcessed = true; } } /* identifier based ignoreContentAfterKey */ HashMap> ignoreContentAfterKey = ignoreMap.get("ignoreContentAfterKey"); // merge all without .key attribute aswell // TODO: ignoreContentAfterKey.putAll(mapPropertiesByIdentifier("ignoreContentAfterKey", properties, new ArrayList())); if (ignoreContentAfterKey!=null) { Iterator ignoreContentAfterKeyIt = ignoreContentAfterKey.entrySet().iterator(); while (ignoreContentAfterKeyIt.hasNext()) { Map.Entry ignoreContentAfterKeyEntry = (Map.Entry) ignoreContentAfterKeyIt.next(); HashMap ignoreContentAfterKeyPair = (HashMap) ignoreContentAfterKeyEntry.getValue(); String key = ignoreContentAfterKeyPair.get("key"); if (key == null) { key = ignoreContentAfterKeyPair.get("value"); } debugMessage("Ignore content before key '" + key + "'", writers); preparedExpectedResult = ignoreContentBeforeKey(preparedExpectedResult, key); preparedActualResult = ignoreContentBeforeKey(preparedActualResult, key); ignoreContentAfterKeyIt.remove(); } } debugMessage("Check ignoreContentAfterKey properties", writers); if ((diffType != null && (diffType.equals(".xml") || diffType.equals(".wsdl"))) || (diffType == null && (fileName.endsWith(".xml") || fileName.endsWith(".wsdl")))) { // xml diff Diff diff = null; boolean identical = false; Exception diffException = null; try { diff = new Diff(preparedExpectedResult, preparedActualResult); identical = diff.identical(); } catch(Exception e) { diffException = e; } if (identical) { ok = RESULT_OK; debugMessage("Strings are identical", writers); debugPipelineMessage(stepDisplayName, "Result", printableActualResult, writers); debugPipelineMessagePreparedForDiff(stepDisplayName, "Result as prepared for diff", preparedActualResult, writers); } else { debugMessage("Strings are not identical", writers); String message; if (diffException == null) { message = diff.toString(); } else { message = "Exception during XML diff: " + diffException.getMessage(); errorMessage("Exception during XML diff: ", diffException, writers); } wrongPipelineMessage(stepDisplayName, message, printableActualResult, printableExpectedResult, writers); wrongPipelineMessagePreparedForDiff(stepDisplayName, preparedActualResult, preparedExpectedResult, writers); if (autoSaveDiffs) { String filenameAbsolutePath = (String)properties.get(step + ".absolutepath"); debugMessage("Copy actual result to ["+filenameAbsolutePath+"]", writers); try { org.apache.commons.io.FileUtils.writeStringToFile(new File(filenameAbsolutePath), actualResult); } catch (IOException e) { } ok = RESULT_AUTOSAVED; } } } else { // txt diff String formattedPreparedExpectedResult = formatString(preparedExpectedResult, writers); String formattedPreparedActualResult = formatString(preparedActualResult, writers); if (formattedPreparedExpectedResult.equals(formattedPreparedActualResult)) { ok = RESULT_OK; debugMessage("Strings are identical", writers); debugPipelineMessage(stepDisplayName, "Result", printableActualResult, writers); debugPipelineMessagePreparedForDiff(stepDisplayName, "Result as prepared for diff", preparedActualResult, writers); } else { debugMessage("Strings are not identical", writers); String message = null; StringBuilder diffActual = new StringBuilder(); StringBuilder diffExcpected = new StringBuilder(); int j = formattedPreparedActualResult.length(); if (formattedPreparedExpectedResult.length() > i) { j = formattedPreparedExpectedResult.length(); } for (i = 0; i < j; i++) { if (i >= formattedPreparedActualResult.length() || i >= formattedPreparedExpectedResult.length() || formattedPreparedActualResult.charAt(i) != formattedPreparedExpectedResult.charAt(i)) { if (message == null) { message = "Starting at char " + (i + 1); } if (i < formattedPreparedActualResult.length()) { diffActual.append(formattedPreparedActualResult.charAt(i)); } if (i < formattedPreparedExpectedResult.length()) { diffExcpected.append(formattedPreparedExpectedResult.charAt(i)); } } } if (diffActual.length() > 250) { diffActual.delete(250, diffActual.length()); diffActual.append(" ..."); } if (diffExcpected.length() > 250) { diffExcpected.delete(250, diffExcpected.length()); diffExcpected.append(" ..."); } message = message + " actual result is '" + diffActual + "' and expected result is '" + diffExcpected + "'"; wrongPipelineMessage(stepDisplayName, message, printableActualResult, printableExpectedResult, writers); wrongPipelineMessagePreparedForDiff(stepDisplayName, preparedActualResult, preparedExpectedResult, writers); if (autoSaveDiffs) { String filenameAbsolutePath = (String)properties.get(step + ".absolutepath"); debugMessage("Copy actual result to ["+filenameAbsolutePath+"]", writers); try { org.apache.commons.io.FileUtils.writeStringToFile(new File(filenameAbsolutePath), actualResult); } catch (IOException e) { } ok = RESULT_AUTOSAVED; } } } return ok; } public static String ignoreContentBetweenKeys(String string, String key1, String key2) { String result = string; String ignoreText = "IGNORE"; int i = result.indexOf(key1); while (i != -1 && result.length() > i + key1.length()) { int j = result.indexOf(key2, i + key1.length()); if (j != -1) { result = result.substring(0, i) + key1 + ignoreText + result.substring(j); i = result.indexOf(key1, i + key1.length() + ignoreText.length() + key2.length()); } else { i = -1; } } return result; } public static String ignoreKeysAndContentBetweenKeys(String string, String key1, String key2) { String result = string; String ignoreText = "IGNORE"; int i = result.indexOf(key1); while (i != -1 && result.length() > i + key1.length()) { int j = result.indexOf(key2, i + key1.length()); if (j != -1) { result = result.substring(0, i) + ignoreText + result.substring(j + key2.length()); i = result.indexOf(key1, i + ignoreText.length()); } else { i = -1; } } return result; } public static String removeKeysAndContentBetweenKeys(String string, String key1, String key2) { String result = string; int i = result.indexOf(key1); while (i != -1 && result.length() > i + key1.length()) { int j = result.indexOf(key2, i + key1.length()); if (j != -1) { result = result.substring(0, i) + result.substring(j + key2.length()); i = result.indexOf(key1, i); } else { i = -1; } } return result; } public static String ignoreKey(String string, String key) { String result = string; String ignoreText = "IGNORE"; int i = result.indexOf(key); while (i != -1) { result = result.substring(0, i) + ignoreText + result.substring(i + key.length()); i = result.indexOf(key, i); } return result; } public static String removeKey(String string, String key) { String result = string; int i = result.indexOf(key); while (i != -1) { result = result.substring(0, i) + result.substring(i + key.length()); i = result.indexOf(key, i); } return result; } public static String replaceKey(String string, String from, String to) { String result = string; if (!from.equals(to)) { int i = result.indexOf(from); while (i != -1) { result = result.substring(0, i) + to + result.substring(i + from.length()); i = result.indexOf(from, i); } } return result; } public static String decodeUnzipContentBetweenKeys(String string, String key1, String key2, boolean replaceNewlines, Map writers) { String result = string; int i = result.indexOf(key1); while (i != -1 && result.length() > i + key1.length()) { debugMessage("Key 1 found", writers); int j = result.indexOf(key2, i + key1.length()); if (j != -1) { debugMessage("Key 2 found", writers); String encoded = result.substring(i + key1.length(), j); String unzipped = null; byte[] decodedBytes = null; Base64 decoder = new Base64(); debugMessage("Decode", writers); decodedBytes = decoder.decodeBase64(encoded); if (unzipped == null) { try { debugMessage("Unzip", writers); StringBuffer stringBuffer = new StringBuffer(); stringBuffer.append(""); ZipInputStream zipInputStream = new ZipInputStream(new ByteArrayInputStream(decodedBytes)); stringBuffer.append("" + zipInputStream.getNextEntry().getName() + ""); stringBuffer.append(""); byte[] buffer = new byte[1024]; int readLength = zipInputStream.read(buffer); while (readLength != -1) { String part = new String(buffer, 0, readLength, "UTF-8"); if (replaceNewlines) { part = StringUtils.replace(StringUtils.replace(part, "\r", "[CARRIAGE RETURN]"), "\n", "[LINE FEED]"); } stringBuffer.append(part); readLength = zipInputStream.read(buffer); } stringBuffer.append(""); stringBuffer.append(""); unzipped = stringBuffer.toString(); } catch(Exception e) { errorMessage("Could not unzip: " + e.getMessage(), e, writers); unzipped = encoded; } } result = result.substring(0, i) + key1 + unzipped + result.substring(j); i = result.indexOf(key1, i + key1.length() + unzipped.length() + key2.length()); } else { i = -1; } } return result; } public static String canonicaliseFilePathContentBetweenKeys(String string, String key1, String key2, Map writers) { String result = string; if (key1.equals("*") && key2.equals("*")) { File file = new File(result); try { result = file.getCanonicalPath(); } catch (IOException e) { errorMessage("Could not canonicalise filepath: " + e.getMessage(), e, writers); } result = FilenameUtils.normalize(result); } else { int i = result.indexOf(key1); while (i != -1 && result.length() > i + key1.length()) { int j = result.indexOf(key2, i + key1.length()); if (j != -1) { String fileName = result.substring(i + key1.length(), j); File file = new File(fileName); try { fileName = file.getCanonicalPath(); } catch (IOException e) { errorMessage("Could not canonicalise filepath: " + e.getMessage(), e, writers); } fileName = FilenameUtils.normalize(fileName); result = result.substring(0, i) + key1 + fileName + result.substring(j); i = result.indexOf(key1, i + key1.length() + fileName.length() + key2.length()); } else { i = -1; } } } return result; } public static String ignoreCurrentTimeBetweenKeys(String string, String key1, String key2, String pattern, String margin, boolean errorMessageOnRemainingString, boolean isControlString, Map writers) { String result = string; String ignoreText = "IGNORE_CURRENT_TIME"; int i = result.indexOf(key1); while (i != -1 && result.length() > i + key1.length()) { debugMessage("Key 1 found", writers); int j = result.indexOf(key2, i + key1.length()); if (j != -1) { debugMessage("Key 2 found", writers); String dateString = result.substring(i + key1.length(), j); Date date; boolean remainingString = false; try { SimpleDateFormat simpleDateFormat = null; if (pattern == null) { // Expect time in milliseconds date = new Date(Long.parseLong(dateString)); } else { simpleDateFormat = new SimpleDateFormat(pattern); ParsePosition parsePosition = new ParsePosition(0); date = simpleDateFormat.parse(dateString, parsePosition); if (parsePosition.getIndex() != dateString.length()) { remainingString = true; i = result.indexOf(key1, j + key2.length()); if (errorMessageOnRemainingString) { errorMessage("Found remaining string after parsing date with pattern '" + pattern + "': " + dateString.substring(parsePosition.getIndex()), writers); } } } if (!remainingString) { if (isControlString) { // Ignore the date in the control string independent on margin from current time result = result.substring(0, i) + key1 + ignoreText + result.substring(j); i = result.indexOf(key1, i + key1.length() + ignoreText.length() + key2.length()); } else { // Ignore the date in the test string dependent on margin from current time String currentTime; long currentTimeMillis; if (pattern == null) { currentTime = "" + System.currentTimeMillis(); currentTimeMillis = Long.parseLong(currentTime); } else { currentTime = simpleDateFormat.format(new Date(System.currentTimeMillis())); currentTimeMillis = simpleDateFormat.parse(currentTime).getTime(); } if (date.getTime() >= currentTimeMillis - Long.parseLong(margin) && date.getTime() <= currentTimeMillis + Long.parseLong(margin)) { result = result.substring(0, i) + key1 + ignoreText + result.substring(j); i = result.indexOf(key1, i + key1.length() + ignoreText.length() + key2.length()); } else { errorMessage("Dates differ too much. Current time: '" + currentTime + "'. Result time: '" + dateString + "'", writers); i = result.indexOf(key1, j + key2.length()); } } } } catch(ParseException e) { i = -1; errorMessage("Could not parse margin or date: " + e.getMessage(), e, writers); } catch(NumberFormatException e) { i = -1; errorMessage("Could not parse long value: " + e.getMessage(), e, writers); } } else { i = -1; } } return result; } public static String formatDecimalContentBetweenKeys(String string, String key1, String key2, Map writers) { String result = string; int i = result.indexOf(key1); while (i != -1 && result.length() > i + key1.length()) { int j = result.indexOf(key2, i + key1.length()); if (j != -1) { String doubleAsString = result.substring(i + key1.length(), j); try { double d = Double.parseDouble(doubleAsString); result = result.substring(0, i) + key1 + format(d) + result.substring(j); i = result.indexOf(key1, i + key1.length() + doubleAsString.length() + key2.length()); } catch (NumberFormatException e) { i = -1; errorMessage( "Could not parse double value: " + e.getMessage(), e, writers); } } else { i = -1; } } return result; } private static String format(double d) { if (d == (long) d) return String.format("%d", (long) d); else return String.format("%s", d); } public static String ignoreContentBeforeKey(String string, String key) { int i = string.indexOf(key); if (i == -1) { return string; } else { return string.substring(i) + "IGNORE"; } } public static String ignoreContentAfterKey(String string, String key) { int i = string.indexOf(key); if (i == -1) { return string; } else { return string.substring(0, i + key.length()) + "IGNORE"; } } public static String ignoreRegularExpression(String string, String regex) { return string.replaceAll(regex, "IGNORE"); } public static String removeRegularExpression(String string, String regex) { return string.replaceAll(regex, ""); } public static String replaceRegularExpression(String string, String from, String to) { return string.replaceAll(from, to); } /** * Create a Map for a specific property based on other properties that are * the same except for a .param1.name, .param1.value or .param1.valuefile * suffix. The property with the .name suffix specifies the key for the * Map, the property with the value suffix specifies the value for the Map. * A property with a the .valuefile suffix can be used as an alternative * for a property with a .value suffix to specify the file to read the * value for the Map from. More than one param can be specified by using * param2, param3 etc. * @param properties * @param property * @param writers * @param session TODO * * @return A map with parameters */ public static Map createParametersMapFromParamProperties(Properties properties, String property, Map writers, boolean createParameterObjects, PipeLineSession session) { debugMessage("Search parameters for property '" + property + "'", writers); final String _name = ".name"; final String _param = ".param"; final String _type = ".type"; Map result = new HashMap<>(); boolean processed = false; int i = 1; while (!processed) { String name = properties.getProperty(property + _param + i + _name); if (name != null) { Object value; String type = properties.getProperty(property + _param + i + _type); if ("httpResponse".equals(type)) { String outputFile; String filename = properties.getProperty(property + _param + i + ".filename"); if (filename != null) { outputFile = properties.getProperty(property + _param + i + ".filename.absolutepath"); } else { outputFile = properties.getProperty(property + _param + i + ".outputfile"); } HttpServletResponseMock httpServletResponseMock = new HttpServletResponseMock(); httpServletResponseMock.setOutputFile(outputFile); value = httpServletResponseMock; } /** Support for httpRequest parameterType is removed because it depends on Spring and Http-client libraries that contain CVEs. Upgrading these libraries requires some work. On the other hand, httpRequest parameter is only used in CreateRestViewPipe. It is unlikely to create a larva test for this pipe. Therefore, it is decided to stop supporting it. */ /* else if ("httpRequest".equals(type)) { value = properties.getProperty(property + _param + i + ".value"); if("multipart".equals(value)){ MockMultipartHttpServletRequest request = new MockMultipartHttpServletRequest(); // following line is required to avoid // "(FileUploadException) the request was rejected because // no multipart boundary was found" request.setContentType("multipart/mixed;boundary=gc0p4Jq0M2Yt08jU534c0p"); List parts = new ArrayList<>(); boolean partsProcessed = false; int j = 1; while (!partsProcessed) { String filename = properties.getProperty(property + _param + i + ".part" + j + ".filename"); if (filename == null) { partsProcessed = true; } else { String partFile = properties.getProperty(property + _param + i + ".part" + j + ".filename.absolutepath"); String partType = properties.getProperty(property + _param + i + ".part" + j + _type); String partName = properties.getProperty(property + _param + i + ".part" + j + _name); if ("file".equalsIgnoreCase(partType)) { File file = new File(partFile); try { FilePart filePart = new FilePart( "file" + j, (partName == null ? file.getName() : partName), file); parts.add(filePart); } catch (FileNotFoundException e) { errorMessage("Could not read file '" + partFile+ "': " + e.getMessage(), e, writers); } } else { String string = readFile(partFile, writers); StringPart stringPart = new StringPart((partName == null ? "string" + j : partName), string); parts.add(stringPart); } j++; } } Part[] allParts = new Part[parts.size()]; allParts = parts.toArray(allParts); MultipartRequestEntity multipartRequestEntity = new MultipartRequestEntity(allParts, new PostMethod().getParams()); ByteArrayOutputStream requestContent = new ByteArrayOutputStream(); try { multipartRequestEntity.writeRequest(requestContent); } catch (IOException e) { errorMessage("Could not create multipart: " + e.getMessage(), e, writers); } request.setContent(requestContent.toByteArray()); request.setContentType(multipartRequestEntity.getContentType()); value = request; } else{ value = new MockHttpServletRequest(); } } */ else { value = properties.getProperty(property + _param + i + ".value"); if (value == null) { String filename = properties.getProperty(property + _param + i + ".valuefile.absolutepath"); if (filename != null) { value = new FileMessage(new File(filename)); } else { String inputStreamFilename = properties.getProperty(property + _param + i + ".valuefileinputstream.absolutepath"); if (inputStreamFilename != null) { errorMessage("valuefileinputstream is no longer supported use valuefile instead", writers); } } } } if ("node".equals(type)) { try { value = XmlUtils.buildNode(Message.asString(value), true); } catch (DomBuilderException | IOException e) { errorMessage("Could not build node for parameter '" + name + "' with value: " + value, e, writers); } } else if ("domdoc".equals(type)) { try { value = XmlUtils.buildDomDocument(Message.asString(value), true); } catch (DomBuilderException | IOException e) { errorMessage("Could not build node for parameter '" + name + "' with value: " + value, e, writers); } } else if ("list".equals(type)) { try { List parts = new ArrayList<>(Arrays.asList(Message.asString(value).split("\\s*(,\\s*)+"))); List list = new LinkedList<>(); for (String part : parts) { list.add(part); } value = list; } catch (IOException e) { errorMessage("Could not build a list for parameter '" + name + "' with value: " + value, e, writers); } } else if ("map".equals(type)) { try { List parts = new ArrayList<>(Arrays.asList(Message.asString(value).split("\\s*(,\\s*)+"))); Map map = new LinkedHashMap<>(); for (String part : parts) { String[] splitted = part.split("\\s*(=\\s*)+", 2); if (splitted.length==2) { map.put(splitted[0], splitted[1]); } else { map.put(splitted[0], ""); } } value = map; } catch (IOException e) { errorMessage("Could not build a map for parameter '" + name + "' with value: " + value, e, writers); } } if (createParameterObjects) { String pattern = properties.getProperty(property + _param + i + ".pattern"); if (value == null && pattern == null) { errorMessage("Property '" + property + _param + i + " doesn't have a value or pattern", writers); } else { try { Parameter parameter = new Parameter(); parameter.setName(name); if (value != null && !(value instanceof String)) { parameter.setSessionKey(name); session.put(name, value); } else { parameter.setValue((String)value); parameter.setPattern(pattern); } parameter.configure(); result.put(name, parameter); debugMessage("Add param with name '" + name + "', value '" + value + "' and pattern '" + pattern + "' for property '" + property + "'", writers); } catch (ConfigurationException e) { errorMessage("Parameter '" + name + "' could not be configured", writers); } } } else { if (value == null) { errorMessage("Property '" + property + _param + i + ".value' or '" + property + _param + i + ".valuefile' not found while property '" + property + _param + i + ".name' exist", writers); } else { result.put(name, value); debugMessage("Add param with name '" + name + "' and value '" + value + "' for property '" + property + "'", writers); } } i++; } else { processed = true; } } return result; } public static String formatString(String string, Map writers) { StringBuffer sb = new StringBuffer(); try { Reader reader = new StringReader(string); BufferedReader br = new BufferedReader(reader); String l = null; while ((l = br.readLine()) != null) { if (sb.length()==0) { sb.append(l); } else { sb.append(System.getProperty("line.separator") + l); } } br.close(); } catch(Exception e) { errorMessage("Could not read string '" + string + "': " + e.getMessage(), e, writers); } return sb.toString(); } /** * This method is used to provide a way to implement ignores based on an identifier. * For example: * ignoreContentBetweenKeys.fieldA.key1= * ignoreContentBetweenKeys.fieldA.key2= * * @param properties Properties to be checked * * @return HashMap>> as HashMap<'ignoreContentBetweenKeys', Hashmap<'fieldA', HashMap<'key1', ''> */ public static HashMap>> mapPropertiesToIgnores(Properties properties){ HashMap>> returnMap = new HashMap<>(); Enumeration enums = (Enumeration) properties.propertyNames(); // Loop through all properties while (enums.hasMoreElements()) { // Extract key String key = enums.nextElement(); // Extract ignore type String ignore = key.split(Pattern.quote("."))[0]; ArrayList attributes = findAttributesForIgnore(ignore); if(attributes != null){ // Extract identifier String id = key.split(Pattern.quote("."))[1]; // Find return map for ignore HashMap> ignoreMap = returnMap.get(ignore); // Create return map for ignore if not exist if(ignoreMap == null) { ignoreMap = new HashMap<>(); returnMap.put(ignore, ignoreMap); } // Find return map for identifier HashMap idMap = ignoreMap.get(id); // Create return map for identifier if not exist if(idMap == null) { idMap = new HashMap<>(); ignoreMap.put(id, idMap); } // Check attributes are provided if(!attributes.isEmpty()){ // Loop through attributes to be searched for for (String attribute : attributes) { if(key.endsWith("." + attribute)){ idMap.put(attribute, properties.getProperty(key)); } else if(attribute.equals("")){ // in case of an empty string as attribute, assume it should read the value // ie: ignoreKey.identifier=value idMap.put("value", properties.getProperty(key)); } } } } } return returnMap; } /** * This method is used to de-couple the need of providing a set of attributes when calling mapPropertiesByIdentifier(). * Caller of mapPropertiesByIdentifier() should not necescarrily know about all attributes related to an ignore. * * @param propertyName The name of the ignore we are checking, in the example 'ignoreContentBetweenKeys' * * @return ArrayList attributes */ public static ArrayList findAttributesForIgnore(String propertyName) { ArrayList attributes = null; switch (propertyName) { case "decodeUnzipContentBetweenKeys": attributes = new ArrayList( Arrays.asList( new String[]{"key1", "key2", "replaceNewlines"} ) ); break; case "canonicaliseFilePathContentBetweenKeys": case "replaceRegularExpressionKeys": case "ignoreContentBetweenKeys": case "ignoreKeysAndContentBetweenKeys": case "removeKeysAndContentBetweenKeys": case "replaceKey": case "formatDecimalContentBetweenKeys": case "replaceEverywhereKey": attributes = new ArrayList( Arrays.asList( new String[]{"key1", "key2"} ) ); break; case "ignoreRegularExpressionKey": case "removeRegularExpressionKey": case "ignoreContentBeforeKey": case "ignoreContentAfterKey": attributes = new ArrayList( Arrays.asList( new String[]{"key"} ) ); break; case "ignoreCurrentTimeBetweenKeys": attributes = new ArrayList( Arrays.asList( new String[]{"key1", "key2", "pattern", "margin", "errorMessageOnRemainingString"} ) ); break; case "ignoreKey": case "removeKey": // in case of an empty string as attribute, assume it should read the value // ie: ignoreKey.identifier=value attributes = new ArrayList(Arrays.asList( new String[]{"key", ""})); break; } return attributes; } }