> extractors = new ArrayList<>();
+ String context;
for (int index : indexes) {
- String context = getContextString(responseDataAsString, value, index);
+ context = getContextString(responseDataAsString, value, index);
RegexCorrelationExtractor> extractor =
generateExtractor(name, value, context, ResultField.BODY);
extractor.setMultiValued(true);
diff --git a/src/main/java/com/blazemeter/jmeter/correlation/core/replacements/CorrelationReplacement.java b/src/main/java/com/blazemeter/jmeter/correlation/core/replacements/CorrelationReplacement.java
index c0dce39..75b1fe9 100644
--- a/src/main/java/com/blazemeter/jmeter/correlation/core/replacements/CorrelationReplacement.java
+++ b/src/main/java/com/blazemeter/jmeter/correlation/core/replacements/CorrelationReplacement.java
@@ -37,8 +37,8 @@
*
* Contains all the methods from loading, saving and processing requests from the server.
*
- * For a more detailed explanation on Correlation Replacements, their usages and methods, please
- * read the
+ * For a more detailed explanation on Correlation Replacements, their usages and methods, please
+ * read the
* readme.
*
* Along side {@link com.blazemeter.jmeter.correlation.core.extractors.CorrelationExtractor}
@@ -96,8 +96,8 @@ public void setVariableName(String variableName) {
}
/**
- * Handles the saving of values of the Correlation Replacement into a {@link
- * CorrelationRuleTestElement} for later storage in Test Plans and CorrelationTemplates.
+ * Handles the saving of values of the Correlation Replacement into a
+ * {@link CorrelationRuleTestElement} for later storage in Test Plans and CorrelationTemplates.
*
* This method has to be overwritten when implementing custom Correlation Replacements,
* otherwise, only the class name will be saved
@@ -115,14 +115,14 @@ public void updateTestElem(CorrelationRuleTestElement testElem) {
*
*
Both the properties in the recorded sampler and its children will be processed
*
- * @param sampler recorded sampler containing the information of the request
+ * @param sampler recorded sampler containing the information of the request
* @param children list of children added to the sampler (if the condition is matched, components
- * will be added to it to correlate the obtained values)
- * @param result result containing information about request and associated response from server
- * @param vars stored variables shared between requests during recording
+ * will be added to it to correlate the obtained values)
+ * @param result result containing information about request and associated response from server
+ * @param vars stored variables shared between requests during recording
*/
public void process(HTTPSamplerBase sampler, List children, SampleResult result,
- JMeterVariables vars) {
+ JMeterVariables vars) {
replaceTestElementProperties(sampler, vars);
for (TestElement child : children) {
if (child instanceof ConfigTestElement) {
@@ -140,7 +140,7 @@ public void process(HTTPSamplerBase sampler, List children, SampleR
* Replacement, the value will be replaced in the String as ${referenceVariableName}
,
* as many times as the logic in the condition allows it.
*
- * @param el test element to check and match the properties
+ * @param el test element to check and match the properties
* @param vars stored variables from the recording
*/
private void replaceTestElementProperties(TestElement el, JMeterVariables vars) {
@@ -165,12 +165,20 @@ private JMeterProperty replaceProperty(JMeterProperty prop, JMeterVariables vars
if (!prop.getName().equals(TestElement.GUI_CLASS)
&& !prop.getName().equals(TestElement.TEST_CLASS)) {
prop = replaceSimpleProp(prop, vars);
- LOG.debug("CorrelationReplacement result: {}", prop);
}
} else if (prop instanceof NumberProperty) {
prop = replaceSimpleProp(prop, vars);
- LOG.debug("CorrelationReplacement result: {}", prop);
} else if (prop instanceof MultiProperty) {
+ if (prop instanceof TestElementProperty) {
+ TestElementProperty testElementProperty = (TestElementProperty) prop;
+ if (testElementProperty.getObjectValue() instanceof Argument) {
+ replaceArgument((Argument) testElementProperty.getObjectValue(), vars);
+ return prop;
+ } else if (testElementProperty.getObjectValue() instanceof Header) {
+ replaceHeader((Header) testElementProperty.getObjectValue(), vars);
+ return prop;
+ }
+ }
MultiProperty multiVal = (MultiProperty) prop;
PropertyIterator propertyIterator = multiVal.iterator();
Collection newValues = new ArrayList<>();
@@ -182,19 +190,10 @@ private JMeterProperty replaceProperty(JMeterProperty prop, JMeterVariables vars
for (JMeterProperty jmp : newValues) {
multiVal.addProperty(jmp);
}
- if (multiVal instanceof TestElementProperty) {
- TestElementProperty multiProp = (TestElementProperty) multiVal;
- if (multiProp.getObjectValue() instanceof Argument) {
- replaceArgument((Argument) multiProp.getObjectValue(), vars);
- } else if (multiProp.getObjectValue() instanceof Header) {
- replaceHeader((Header) multiProp.getObjectValue(), vars);
- }
- }
- LOG.debug("CorrelationReplacement result: {}", multiVal);
-
} else {
LOG.debug("Won't replace {}", prop);
}
+ LOG.debug("CorrelationReplacement result: {}", prop);
return prop;
}
@@ -212,7 +211,7 @@ private JMeterProperty replaceSimpleProp(JMeterProperty prop, JMeterVariables va
* implemented.
*
* @param input property's string to check and replace
- * @param vars stored variables shared between request during the recording
+ * @param vars stored variables shared between request during the recording
* @return the resultant input after been processed
*/
protected abstract String replaceString(String input, JMeterVariables vars);
@@ -224,12 +223,17 @@ private void replaceArgument(Argument arg, JMeterVariables vars) {
}
/*
To normalize the replacement on arguments for HTTP requests, we include the argument name and
- '=' to the input, apply the replacement logic, and remove it afterward. This doesn't applies
+ '=' to the input, apply the replacement logic, and remove it afterward. This doesn't applies
when the argument has no name (eg: Data Body is a JSON/XML).
*/
String prefix = arg.getName().isEmpty() ? "" : arg.getName() + "=";
input = replaceString(prefix + arg.getValue(), vars).replace(prefix, "");
arg.setValue(input);
+ /*
+ In order to comply backward compatibility from <=v2.5 keys (arg name) is also processed by
+ the replacement
+ */
+ arg.setName(replaceString(arg.getName(), vars));
}
private void replaceHeader(Header header, JMeterVariables vars) {
@@ -240,6 +244,11 @@ private void replaceHeader(Header header, JMeterVariables vars) {
input = replaceString(header.getName() + ": " + header.getValue(), vars)
.replace(header.getName() + ": ", "");
header.setValue(input);
+ /*
+ In order to comply backward compatibility from <=v2.5 keys (header name) is also processed by
+ the replacement
+ */
+ header.setName(replaceString(header.getName(), vars));
}
@Override
diff --git a/src/main/java/com/blazemeter/jmeter/correlation/core/suggestions/method/ComparisonMethod.java b/src/main/java/com/blazemeter/jmeter/correlation/core/suggestions/method/ComparisonMethod.java
index ca1fb54..7700f7b 100644
--- a/src/main/java/com/blazemeter/jmeter/correlation/core/suggestions/method/ComparisonMethod.java
+++ b/src/main/java/com/blazemeter/jmeter/correlation/core/suggestions/method/ComparisonMethod.java
@@ -10,6 +10,7 @@
import com.blazemeter.jmeter.correlation.core.automatic.Sources;
import com.blazemeter.jmeter.correlation.core.automatic.extraction.StructureType;
import com.blazemeter.jmeter.correlation.core.automatic.extraction.location.LocationType;
+import com.blazemeter.jmeter.correlation.core.automatic.extraction.method.Extractor;
import com.blazemeter.jmeter.correlation.core.automatic.extraction.method.ExtractorFactory;
import com.blazemeter.jmeter.correlation.core.automatic.replacement.method.ReplacementContext;
import com.blazemeter.jmeter.correlation.core.extractors.CorrelationExtractor;
@@ -17,7 +18,6 @@
import com.blazemeter.jmeter.correlation.core.suggestions.context.ComparisonContext;
import com.blazemeter.jmeter.correlation.core.suggestions.context.CorrelationContext;
import com.helger.commons.annotation.VisibleForTesting;
-import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -46,6 +46,8 @@ public class ComparisonMethod implements CorrelationMethod {
private final List orphanSuggestions = new ArrayList<>();
private List results;
private ComparisonContext context;
+ private final HashMap structureTypeCache =
+ new HashMap<>();
public ComparisonMethod() {
}
@@ -83,10 +85,10 @@ private static boolean hasOrphans(CorrelationSuggestion suggestion) {
* @return the populated ExtractionSuggestion.
*/
private static ExtractionSuggestion generateCandidateExtractor(SampleResult result,
- Appearances appearance,
- CorrelationExtractor extractor,
- StructureType structureType,
- String name) {
+ Appearances appearance,
+ CorrelationExtractor extractor,
+ StructureType structureType,
+ String name) {
ExtractionSuggestion suggestion = new ExtractionSuggestion(extractor, result);
suggestion.setSource(structureType.name());
suggestion.setValue(appearance.getValue());
@@ -114,7 +116,6 @@ public List generateSuggestions(CorrelationContext contex
context.getClass());
return new ArrayList<>();
}
-
this.context = (ComparisonContext) context;
this.results = this.context.getRecordingSampleResults(); // Load the results once
@@ -166,7 +167,7 @@ private void loadFromDynamicElements(DynamicElement replayCandidate) {
* @return the populated CorrelationSuggestion.
*/
private CorrelationSuggestion populateSuggestion(DynamicElement element,
- CorrelationSuggestion suggestion) {
+ CorrelationSuggestion suggestion) {
addMultivaluedExtractor(element, suggestion, results, valueToReferenceName);
addMultivaluedReplacement(element, suggestion, valueToReferenceName);
return suggestion;
@@ -187,16 +188,15 @@ private CorrelationSuggestion populateSuggestion(DynamicElement element,
* extraction suggestions.
*/
private void addMultivaluedExtractor(DynamicElement element,
- CorrelationSuggestion suggestion, List results,
- Map valueToReferenceName) {
+ CorrelationSuggestion suggestion, List results,
+ Map valueToReferenceName) {
for (SampleResult result : results) {
//We use both the "original" and the "other" appearances since the map can come from either
//the original recorder or from the failing replay
- addExtractorSuggestions(valueToReferenceName, suggestion, result,
- element.getOriginalAppearance());
- addExtractorSuggestions(valueToReferenceName, suggestion, result,
- element.getOtherAppearance());
+ List appearancesList = new ArrayList<>(element.getOriginalAppearance());
+ appearancesList.addAll(element.getOtherAppearance());
+ addExtractorSuggestions(valueToReferenceName, suggestion, result, appearancesList);
}
}
@@ -220,11 +220,22 @@ private void addMultivaluedExtractor(DynamicElement element,
* suggestions.
*/
private void addExtractorSuggestions(Map valueToReferenceName,
- CorrelationSuggestion suggestion, SampleResult result,
- List appearances) {
+ CorrelationSuggestion suggestion, SampleResult result,
+ List appearances) {
+ structureTypeCache.clear();
+ // Flowing fields declared beforehand for performance proposes
+ StructureType structureType;
+ ExtractorFactory ef = new ExtractorFactory(context.getConfiguration());
+ HashMap extractorCache = new HashMap<>();
+ ResponseAnalyzer analyzer = new ResponseAnalyzer();
+ String name;
+ Extractor extractor;
for (Appearances appearance : appearances) {
- String name = suggestion.getParamName();
+ if (!Sources.isRequestSource(appearance.getSource())) {
+ continue;
+ }
+ name = suggestion.getParamName();
if (suggestion.getAppearances().size() > getConfiguration().getMaxNumberOfAppearances()
&& getConfiguration().getMaxNumberOfAppearances() != -1) {
LOG.warn("Too many appearances for element '{}'. Please review the total appearances.",
@@ -238,18 +249,15 @@ && getConfiguration().getMaxNumberOfAppearances() != -1) {
continue;
}
- ResponseAnalyzer analyzer = new ResponseAnalyzer();
LocationType locationType = analyzer.identifyArgumentLocation(result, appearance.getValue());
if (locationType == LocationType.UNKNOWN) {
- LOG.debug("Couldn't associate a location for the param '{}' in the responses of {}. "
- + "Value {}. Skipping this value.", name, result.getSampleLabel(),
- appearance.getValue());
+ // "Couldn't associate a location for the param in the responses.
+ // Skipping this value.
continue;
}
-
- StructureType structureType = analyzer.identifyStructureType(result, locationType);
- List> extractors = new ExtractorFactory(context.getConfiguration())
- .getExtractor(locationType, structureType)
+ structureType = getStructureType(result, structureTypeCache, locationType, analyzer);
+ extractor = getExtractor(locationType, structureType, extractorCache, ef);
+ List> extractors = extractor
.getCorrelationExtractors(result, appearance.getValue(), name);
if (extractors == null || extractors.isEmpty()) {
@@ -272,6 +280,33 @@ && getConfiguration().getMaxNumberOfAppearances() != -1) {
}
}
+ private static Extractor getExtractor(LocationType locationType, StructureType structureType,
+ HashMap extractorCache, ExtractorFactory ef) {
+ String extractorKey;
+ Extractor extractor;
+ extractorKey = locationType + ":" + structureType;
+ if (extractorCache.containsKey(extractorKey)) {
+ extractor = extractorCache.get(extractorKey);
+ } else {
+ extractor = ef.getExtractor(locationType, structureType);
+ extractorCache.put(extractorKey, extractor);
+ }
+ return extractor;
+ }
+
+ private static StructureType getStructureType(SampleResult result,
+ HashMap structureTypeCache, LocationType locationType,
+ ResponseAnalyzer analyzer) {
+ StructureType structureType;
+ if (structureTypeCache.containsKey(locationType)) {
+ structureType = structureTypeCache.get(locationType);
+ } else {
+ structureType = analyzer.identifyStructureType(result, locationType);
+ structureTypeCache.put(locationType, structureType);
+ }
+ return structureType;
+ }
+
/**
* This method converts a list of Appearances into a string representation. It first creates a map
* of appearance values to their counts. Then, it converts the map into a string where each entry
@@ -308,9 +343,7 @@ private String appearancesToString(List appearances) {
*/
private boolean valueInUse(SampleResult result, String value) {
String queryString = this.resultQueryString.apply(result);
- boolean encodedUsed = queryString.contains(URLEncoder.encode(value));
- boolean rawUsed = queryString.contains(value);
- return encodedUsed || rawUsed;
+ return queryString.contains(value);
}
/**
@@ -343,17 +376,8 @@ private boolean reachedUsageSampler(SampleResult result, List appea
* @return true if the replacement suggestion is already present in the list, false otherwise.
*/
private boolean isRepeated(CorrelationSuggestion suggestion,
- CorrelationReplacement> replacementSuggestion) {
- boolean repeated = false;
- List replacementSuggestions = suggestion.getReplacementSuggestions();
- for (ReplacementSuggestion existing : replacementSuggestions) {
- String s = existing.toString();
- if (s.equals(replacementSuggestion.toString())) {
- repeated = true;
- break;
- }
- }
- return repeated;
+ CorrelationReplacement> replacementSuggestion) {
+ return suggestion.getExtractionSuggestionsString().contains(replacementSuggestion.toString());
}
/**
@@ -369,15 +393,8 @@ private boolean isRepeated(CorrelationSuggestion suggestion,
* @return true if the extraction suggestion is already present in the list, false otherwise.
*/
private boolean isRepeated(CorrelationSuggestion suggestion,
- ExtractionSuggestion extractionSuggestion) {
- boolean repeated = false;
- for (ExtractionSuggestion existing : suggestion.getExtractionSuggestions()) {
- if (existing.toString().equals(extractionSuggestion.toString())) {
- repeated = true;
- break;
- }
- }
- return repeated;
+ ExtractionSuggestion extractionSuggestion) {
+ return suggestion.getExtractionSuggestionsString().contains(extractionSuggestion.toString());
}
/**
@@ -395,8 +412,8 @@ private boolean isRepeated(CorrelationSuggestion suggestion,
* replacement suggestions.
*/
private void addMultivaluedReplacement(DynamicElement element,
- CorrelationSuggestion suggestion,
- Map valueToReferenceName) {
+ CorrelationSuggestion suggestion,
+ Map valueToReferenceName) {
List originalAppearances = element.getOriginalAppearance();
List otherAppearances = element.getOtherAppearance();
@@ -422,8 +439,8 @@ private void addMultivaluedReplacement(DynamicElement element,
* suggestions.
*/
private void addReplacementSuggestions(CorrelationSuggestion suggestion,
- Map valueToReferenceName,
- List originalAppearances) {
+ Map valueToReferenceName,
+ List originalAppearances) {
String name = suggestion.getParamName();
for (Appearances appearance : originalAppearances) {
String referenceName = valueToReferenceName.get(appearance.getValue());
diff --git a/src/main/java/com/blazemeter/jmeter/correlation/core/templates/LocalConfiguration.java b/src/main/java/com/blazemeter/jmeter/correlation/core/templates/LocalConfiguration.java
index b9deb30..4932703 100644
--- a/src/main/java/com/blazemeter/jmeter/correlation/core/templates/LocalConfiguration.java
+++ b/src/main/java/com/blazemeter/jmeter/correlation/core/templates/LocalConfiguration.java
@@ -66,10 +66,12 @@ public class LocalConfiguration {
private static final String JAR_FILE_SUFFIX = ".jar";
private static final String TEMPLATES_FOLDER_PATH = "/templates/";
private static final String LOCAL_REPOSITORIES_MANAGERS_FILE_NAME = "managers";
- private static final String CORRELATION_RECORDER_TEST_PLAN = "correlation-recorder.jmx";
- private static final String CORRELATION_RECORDER_TEMPLATE_DESC = "correlation-recorder-template"
+ private static final String CORRELATION_RECORDER_TEST_PLAN = "auto-correlation-recorder.jmx";
+ private static final String CORRELATION_RECORDER_TEMPLATE_DESC = "auto-correlation-recorder"
+ + "-template"
+ "-description.xml";
- private static final String CORRELATION_RECORDER_TEMPLATE_NAME = "bzm - Correlation Recorder";
+ private static final String CORRELATION_RECORDER_TEMPLATE_NAME = "bzm - Auto Correlation "
+ + "Recorder";
private static final Logger LOG = LoggerFactory.getLogger(LocalConfiguration.class);
@JsonIgnore
diff --git a/src/main/java/com/blazemeter/jmeter/correlation/gui/TestPlanTemplatesRepository.java b/src/main/java/com/blazemeter/jmeter/correlation/gui/TestPlanTemplatesRepository.java
index 0e5feb1..b8e2f4f 100644
--- a/src/main/java/com/blazemeter/jmeter/correlation/gui/TestPlanTemplatesRepository.java
+++ b/src/main/java/com/blazemeter/jmeter/correlation/gui/TestPlanTemplatesRepository.java
@@ -14,6 +14,8 @@
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
@@ -23,6 +25,7 @@
public class TestPlanTemplatesRepository {
private static final Logger LOG = LoggerFactory.getLogger(TestPlanTemplatesRepository.class);
+ private static final String DEPRECATED_TEMPLATE_NAME = "correlation-recorder.jmx";
private String rootFolder;
public TestPlanTemplatesRepository(String rootFolder) {
@@ -45,7 +48,7 @@ public void setRootFolder(String rootFolder) {
}
public void addCorrelationRecorderTemplate(String templateFileName, String templatesFolderPath,
- String descriptionFileName, String templateName) {
+ String descriptionFileName, String templateName) {
copyTemplateFile(templateFileName, templatesFolderPath);
addTemplateDescription(descriptionFileName, templateName);
addFailExtractorAssertion(templateFileName);
@@ -53,6 +56,7 @@ public void addCorrelationRecorderTemplate(String templateFileName, String templ
private void copyTemplateFile(String fileName, String sourcePath) {
try {
+ removeDeprecatedTemplate(DEPRECATED_TEMPLATE_NAME);
File dest = new File(Paths.get(rootFolder, fileName).toAbsolutePath().toString());
String fileFromResources = getFileFromResources(sourcePath + fileName);
if (!dest.exists() || !DigestUtils
@@ -67,6 +71,21 @@ private void copyTemplateFile(String fileName, String sourcePath) {
}
}
+ private void removeDeprecatedTemplate(
+ @SuppressWarnings("SameParameterValue") String templateName) {
+ File oldTemplate =
+ new File(Paths.get(rootFolder, templateName).toAbsolutePath().toString());
+ if (!oldTemplate.exists()) {
+ return;
+ }
+ LOG.info("[ACR] Removing old template: {}", oldTemplate.getAbsolutePath());
+ if (!oldTemplate.delete()) {
+ LOG.error("[ACR] Failed to remove old template: {}", oldTemplate.getAbsolutePath());
+ return;
+ }
+ LOG.info("[ACR] Successfully removed old template: {}", oldTemplate.getAbsolutePath());
+ }
+
private String getFileFromResources(String fileName) throws IOException {
InputStream inputStream = this.getClass().getResourceAsStream(fileName);
return IOUtils.toString(inputStream, StandardCharsets.UTF_8);
@@ -75,7 +94,7 @@ private String getFileFromResources(String fileName) throws IOException {
private void addTemplateDescription(String descTemplateName, String templateName) {
try {
String filePath = Paths.get(rootFolder, "templates.xml").toAbsolutePath().toString();
- removeOldTemplate(filePath);
+ removeDeprecatedTemplatesDescription(filePath);
if (!checkIfStringExists(filePath, "" + templateName + "")) {
Path path = Paths.get(filePath);
List replacedLines = new ArrayList<>();
@@ -96,7 +115,7 @@ private void addTemplateDescription(String descTemplateName, String templateName
}
}
- private void removeOldTemplate(String filePath) {
+ private void removeDeprecatedTemplatesDescription(String filePath) {
String content;
try {
@@ -105,19 +124,24 @@ private void removeOldTemplate(String filePath) {
LOG.error("Error trying to read the file {}", filePath);
return;
}
+ List patterns =
+ Stream.of("Correlation Recorder", "bzm - Correlation Recorder")
+ .map(name -> Pattern.compile(
+ "([\\n ]*" + name + ".*)",
+ Pattern.DOTALL))
+ .collect(Collectors.toList());
+ for (Pattern pattern : patterns) {
+ Matcher matcher = pattern.matcher(content);
+ if (!matcher.find()) {
+ LOG.debug("Old Correlation Template not found.");
+ continue;
+ }
- Matcher matcher = Pattern.compile(
- "([\\n ]*Correlation Recorder.*)",
- Pattern.DOTALL).matcher(content);
- if (!matcher.find()) {
- LOG.debug("Old Correlation Template not found.");
- return;
- }
-
- try (FileWriter fileWriter = new FileWriter(filePath)) {
- fileWriter.write(content.replace(matcher.group(), ""));
- } catch (IOException e) {
- LOG.error("Error trying to write the file {}", filePath);
+ try (FileWriter fileWriter = new FileWriter(filePath)) {
+ fileWriter.write(content.replace(matcher.group(), ""));
+ } catch (IOException e) {
+ LOG.error("Error trying to write the file {}", filePath);
+ }
}
}
diff --git a/src/main/java/com/blazemeter/jmeter/correlation/gui/analysis/CorrelationTemplatesSelectionPanel.java b/src/main/java/com/blazemeter/jmeter/correlation/gui/analysis/CorrelationTemplatesSelectionPanel.java
index 26682b7..61ae328 100644
--- a/src/main/java/com/blazemeter/jmeter/correlation/gui/analysis/CorrelationTemplatesSelectionPanel.java
+++ b/src/main/java/com/blazemeter/jmeter/correlation/gui/analysis/CorrelationTemplatesSelectionPanel.java
@@ -6,6 +6,7 @@
import com.blazemeter.jmeter.correlation.core.templates.CorrelationTemplatesRepositoriesConfiguration;
import com.blazemeter.jmeter.correlation.core.templates.Repository;
import com.blazemeter.jmeter.correlation.core.templates.Template;
+import com.blazemeter.jmeter.correlation.core.templates.Template.Builder;
import com.blazemeter.jmeter.correlation.core.templates.TemplateVersion;
import com.blazemeter.jmeter.correlation.core.templates.repository.Properties;
import com.blazemeter.jmeter.correlation.core.templates.repository.RepositoryManager;
@@ -22,10 +23,14 @@
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
+import java.util.function.Function;
import java.util.stream.Collectors;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
@@ -49,18 +54,21 @@
public class CorrelationTemplatesSelectionPanel extends WizardStepPanel implements ActionListener {
private static final long serialVersionUID = 240L;
- private static final Logger LOG
- = LoggerFactory.getLogger(CorrelationTemplatesSelectionPanel.class);
+ private static final Logger LOG = LoggerFactory.getLogger(
+ CorrelationTemplatesSelectionPanel.class);
private static final String BROWSE = "browse";
private static final String CONTINUE = "continue";
private static final String CANCEL = "cancel";
private static final String RELOAD = "reload";
+ private static final String DRAFT_REPOSITORY_NAME = "Draft";
private final Analysis analysis = new Analysis();
private TemplatesSelectionTable selectionTable;
private JEditorPane informationPane;
private JTextField traceFilePath;
private BiConsumer, String> startNonCorrelatedAnalysis;
private JButton continueButton;
+ private Function buildTemplate;
+ private Template draftTemplate;
public CorrelationTemplatesSelectionPanel(CorrelationWizard wizard) {
super(wizard);
@@ -103,35 +111,22 @@ private JPanel buildInfoAndReloadPanel() {
informationLabel.setText(
"Select which Correlation Template and the version that you want to apply:");
- JButton reloadTemplates = new SwingUtils.ButtonBuilder()
- .withActionListener(this)
- .withAction(RELOAD)
- .withName("templateReloadButton")
- .build();
+ JButton reloadTemplates = new SwingUtils.ButtonBuilder().withActionListener(this)
+ .withAction(RELOAD).withName("templateReloadButton").build();
reloadTemplates.setText("Reload Templates");
reloadTemplates.setToolTipText("Reload the available Correlation Templates");
GroupLayout layout = new GroupLayout(infoAndReloadPanel);
infoAndReloadPanel.setLayout(layout);
- layout.setHorizontalGroup(
- layout.createParallelGroup(GroupLayout.Alignment.LEADING)
- .addGroup(layout.createSequentialGroup()
- .addContainerGap()
- .addComponent(informationLabel)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED,
- GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(reloadTemplates)
- .addContainerGap())
- );
- layout.setVerticalGroup(
- layout.createParallelGroup(GroupLayout.Alignment.LEADING)
- .addGroup(layout.createSequentialGroup()
- .addContainerGap()
- .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
- .addComponent(informationLabel)
- .addComponent(reloadTemplates))
- .addContainerGap())
- );
+ layout.setHorizontalGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING).addGroup(
+ layout.createSequentialGroup().addContainerGap().addComponent(informationLabel)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED,
+ GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE).addComponent(reloadTemplates)
+ .addContainerGap()));
+ layout.setVerticalGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING).addGroup(
+ layout.createSequentialGroup().addContainerGap().addGroup(
+ layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
+ .addComponent(informationLabel).addComponent(reloadTemplates)).addContainerGap()));
return infoAndReloadPanel;
}
@@ -147,24 +142,17 @@ private JPanel buildCorrelationRulesSelectionPanel() {
GroupLayout layout = new GroupLayout(correlationRulesSelectionPanel);
correlationRulesSelectionPanel.setLayout(layout);
- layout.setHorizontalGroup(
- layout.createParallelGroup(GroupLayout.Alignment.LEADING)
- .addGroup(layout.createSequentialGroup()
- .addContainerGap()
- .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
- .addComponent(correlationRulesTableScrollPane, GroupLayout.DEFAULT_SIZE, 400,
- Short.MAX_VALUE))
- .addContainerGap()));
-
- layout.setVerticalGroup(
- layout.createParallelGroup(GroupLayout.Alignment.LEADING)
- .addGroup(layout.createSequentialGroup()
- .addContainerGap()
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(correlationRulesTableScrollPane, GroupLayout.DEFAULT_SIZE, 200,
- Short.MAX_VALUE)
- .addContainerGap())
- );
+ layout.setHorizontalGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING).addGroup(
+ layout.createSequentialGroup().addContainerGap().addGroup(
+ layout.createParallelGroup(GroupLayout.Alignment.LEADING)
+ .addComponent(correlationRulesTableScrollPane, GroupLayout.DEFAULT_SIZE, 400,
+ Short.MAX_VALUE)).addContainerGap()));
+
+ layout.setVerticalGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING).addGroup(
+ layout.createSequentialGroup().addContainerGap()
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(correlationRulesTableScrollPane, GroupLayout.DEFAULT_SIZE, 200,
+ Short.MAX_VALUE).addContainerGap()));
return correlationRulesSelectionPanel;
}
@@ -181,9 +169,8 @@ private void onTemplateVersionFocus(Template focusedVersion) {
TemplateSelectionTableModel model = (TemplateSelectionTableModel) selectionTable.getModel();
boolean canUse = model.canUseTemplate(focusedVersion);
- informationPane.setText(TemplateVersionUtils
- .getInformationAsHTLM(focusedVersion, false, canUse,
- model.getRepositoryDisplayName(focusedVersion.getRepositoryId())));
+ informationPane.setText(TemplateVersionUtils.getInformationAsHTLM(focusedVersion, false, canUse,
+ model.getRepositoryDisplayName(focusedVersion.getRepositoryId())));
informationPane.setCaretPosition(0); // Scroll to the top
}
@@ -197,10 +184,33 @@ public void loadPanel() {
public void loadCorrelationTemplates() {
Map repositoryMap = this.wizard.getRepositoriesSupplier().get();
+ addDraftTemplate(repositoryMap);
selectionTable.setRepositories(repositoryMap);
selectionTable.selectFirstRow();
}
+ private void addDraftTemplate(Map repositoryMap) {
+ Repository draft = new Repository(DRAFT_REPOSITORY_NAME);
+ draft.setDisplayName(DRAFT_REPOSITORY_NAME);
+ initDraftTemplate();
+ draft.addTemplate(draftTemplate, new TemplateProperties());
+ repositoryMap.put(DRAFT_REPOSITORY_NAME, draft);
+ }
+
+ private void initDraftTemplate() {
+ String lastModifiedDate = LocalDateTime.now()
+ .format(DateTimeFormatter.ofPattern("MM.dd.yyyy-HH.mm.ss"));
+ this.draftTemplate = buildTemplate.apply(
+ new Builder().withId("draft").withRepositoryId(DRAFT_REPOSITORY_NAME)
+ .withVersion("N/A")
+ .withChanges("Rules extracted on: " + lastModifiedDate)
+ .withDescription("These are the rules which are under development in Correlation Panel")
+ .withAuthor(System.getProperty("user.name") + "(you)")
+ .withUrl("")
+ .withDependencies(Collections.emptyList()));
+
+ }
+
private JPanel buildCorrelationRulesInformationPanel() {
JPanel correlationRulesInformationPanel = new JPanel();
correlationRulesInformationPanel.setBorder(BorderFactory.createEmptyBorder());
@@ -221,21 +231,15 @@ private JPanel buildCorrelationRulesInformationPanel() {
GroupLayout layout = new GroupLayout(correlationRulesInformationPanel);
correlationRulesInformationPanel.setLayout(layout);
- layout.setHorizontalGroup(
- layout.createParallelGroup(GroupLayout.Alignment.LEADING)
- .addGroup(layout.createSequentialGroup()
- .addContainerGap()
- .addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)
- .addContainerGap())
- );
-
- layout.setVerticalGroup(
- layout.createParallelGroup(GroupLayout.Alignment.LEADING)
- .addGroup(layout.createSequentialGroup()
- .addContainerGap()
- .addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 250, Short.MAX_VALUE)
- .addContainerGap())
- );
+ layout.setHorizontalGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING).addGroup(
+ layout.createSequentialGroup().addContainerGap()
+ .addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)
+ .addContainerGap()));
+
+ layout.setVerticalGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING).addGroup(
+ layout.createSequentialGroup().addContainerGap()
+ .addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 250, Short.MAX_VALUE)
+ .addContainerGap()));
return correlationRulesInformationPanel;
}
@@ -252,11 +256,10 @@ private JPanel buildButtonsPanel() {
traceFilePanel.add(traceFilePath);
traceFilePanel.add(
builder.withAction(BROWSE).withText("Browse").withName("templateBrowseButton").build());
- JButton cancelButton =
- builder.withAction(CANCEL).withText("Cancel").withName("templateCancelButton").build();
- continueButton =
- builder.withAction(CONTINUE).withText("Continue").withName("templateContinueButton")
- .build();
+ JButton cancelButton = builder.withAction(CANCEL).withText("Cancel")
+ .withName("templateCancelButton").build();
+ continueButton = builder.withAction(CONTINUE).withText("Continue")
+ .withName("templateContinueButton").build();
enableContinue(false);
JPanel buttonPanel = new JPanel(new FlowLayout());
@@ -294,8 +297,8 @@ private void reloadCorrelationTemplates() {
UpdateRepositoriesWorker worker = new UpdateRepositoriesWorker() {
@Override
protected Boolean doInBackground() {
- return wizard.getRepositoriesConfiguration().getLocalConfig().refreshRepositories("",
- this::setProgress, this::publish);
+ return wizard.getRepositoriesConfiguration().getLocalConfig()
+ .refreshRepositories("", this::setProgress, this::publish);
}
};
@@ -326,30 +329,34 @@ private void validateAndContinue() {
}
private void onContinue() {
- Map> repositoryGrouped
- = selectionTable.getSelectedTemplateWithRepositoryMap();
+ Map> repositoryGrouped =
+ selectionTable.getSelectedTemplateWithRepositoryMap();
+ boolean isDraft = false;
List canUseTemplates = new ArrayList<>();
List cannotUseTemplates = new ArrayList<>();
for (Map.Entry> entry : repositoryGrouped.entrySet()) {
String repositoryName = entry.getKey();
+ if (repositoryName.equals(DRAFT_REPOSITORY_NAME)) {
+ isDraft = !draftTemplate.getGroups().isEmpty();
+ continue;
+ }
List templates = entry.getValue();
- CorrelationTemplatesRepositoriesConfiguration config
- = this.wizard.getRepositoriesConfiguration();
+ CorrelationTemplatesRepositoriesConfiguration config =
+ this.wizard.getRepositoriesConfiguration();
RepositoryManager repManager = config.getRepositoryManager(repositoryName);
- Map templatesAndProperties
- = repManager.getTemplatesAndProperties(templates);
+ Map templatesAndProperties =
+ repManager.getTemplatesAndProperties(
+ templates);
if (templatesAndProperties == null || templatesAndProperties.isEmpty()) {
// Get all the templates and properties for the local repository and filter the selected
- templatesAndProperties = config
- .getCorrelationTemplatesAndPropertiesByRepositoryName(repositoryName, true)
- .entrySet()
- .stream()
- .filter(templateEntry -> templates.stream().anyMatch(t ->
- templateEntry.getKey().getId().equals(t.getName()) &&
- templateEntry.getKey().getVersion().equals(t.getVersion())))
+ templatesAndProperties = config.getCorrelationTemplatesAndPropertiesByRepositoryName(
+ repositoryName, true).entrySet().stream().filter(templateEntry -> templates.stream()
+ .anyMatch(
+ t -> templateEntry.getKey().getId().equals(t.getName())
+ && templateEntry.getKey().getVersion().equals(t.getVersion())))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
@@ -370,12 +377,14 @@ private void onContinue() {
if (!cannotUseTemplates.isEmpty()) {
JOptionPane.showMessageDialog(this,
"You don't have permission to use the following templates:\n"
- + cannotUseTemplates.stream()
- .map(RepositoryUtils::getTemplateInfo)
- .collect(Collectors.joining("\n")),
- "Cannot use templates", JOptionPane.ERROR_MESSAGE);
+ + cannotUseTemplates.stream().map(RepositoryUtils::getTemplateInfo)
+ .collect(Collectors.joining("\n")), "Cannot use templates",
+ JOptionPane.ERROR_MESSAGE);
}
+ if (isDraft) {
+ canUseTemplates.add(draftTemplate);
+ }
this.startNonCorrelatedAnalysis.accept(canUseTemplates, traceFilePath.getText());
}
@@ -392,21 +401,19 @@ private void browseForJtl() {
private void enableContinue(boolean enable) {
continueButton.setEnabled(enable);
- continueButton.setToolTipText(enable ? "" : "Analysis is enabled if a recording exists."
- + "\n"
+ continueButton.setToolTipText(enable ? "" : "Analysis is enabled if a recording exists." + "\n"
+ "Make a recording or select a .jtl of a recording to be analyzed.");
}
- public void setStartNonCorrelatedAnalysis(BiConsumer,
- String> nonCorrelatedAnalysis) {
+ public void setStartNonCorrelatedAnalysis(
+ BiConsumer, String> nonCorrelatedAnalysis) {
this.startNonCorrelatedAnalysis = nonCorrelatedAnalysis;
}
public void setRecordingTrace() {
String fileName = JMeterElementUtils.getRecordingResultFileName();
boolean fileExist = fileName != null && !fileName.isEmpty();
- traceFilePath.setText(fileExist
- ? fileName : "Enter the path of the .jtl file to use");
+ traceFilePath.setText(fileExist ? fileName : "Enter the path of the .jtl file to use");
enableContinue(fileExist);
}
@@ -421,14 +428,16 @@ public String getTraceFilePath() {
}
//Reminder: this is the place where the "Analysis by Template" is called.
- public void runNonCorrelatedAnalysis(List templatesToAnalyse,
- String recordingTrace) {
+ public void runNonCorrelatedAnalysis(List templatesToAnalyse, String recordingTrace) {
analysis.run(templatesToAnalyse, recordingTrace, false);
}
//Reminder: this is the "Apply Suggestions" for Analysis.
- public void runCorrelatedAnalysis(List templatesApply,
- String recordingTrace) {
+ public void runCorrelatedAnalysis(List templatesApply, String recordingTrace) {
analysis.run(templatesApply, recordingTrace, true);
}
+
+ public void setBuildTemplate(Function buildTemplate) {
+ this.buildTemplate = buildTemplate;
+ }
}
diff --git a/src/main/java/com/blazemeter/jmeter/correlation/gui/analysis/TemplatesSelectionTable.java b/src/main/java/com/blazemeter/jmeter/correlation/gui/analysis/TemplatesSelectionTable.java
index 36e6ce5..821c318 100644
--- a/src/main/java/com/blazemeter/jmeter/correlation/gui/analysis/TemplatesSelectionTable.java
+++ b/src/main/java/com/blazemeter/jmeter/correlation/gui/analysis/TemplatesSelectionTable.java
@@ -195,9 +195,7 @@ public Component getTableCellRendererComponent(JTable table, Object value,
}
private static void setForegroundBasedOnPermissions(JTable table, int row, JComponent target) {
- if (canUseTemplate(table, row)) {
- target.setForeground(UIManager.getColor("Label.foreground"));
- } else {
+ if (!canUseTemplate(table, row)) {
target.setForeground(UIManager.getColor("Label.disabledForeground"));
}
}
diff --git a/src/main/java/com/blazemeter/jmeter/correlation/gui/automatic/CorrelationSuggestionsPanel.java b/src/main/java/com/blazemeter/jmeter/correlation/gui/automatic/CorrelationSuggestionsPanel.java
index e38f139..bbecbfa 100644
--- a/src/main/java/com/blazemeter/jmeter/correlation/gui/automatic/CorrelationSuggestionsPanel.java
+++ b/src/main/java/com/blazemeter/jmeter/correlation/gui/automatic/CorrelationSuggestionsPanel.java
@@ -332,18 +332,21 @@ public void setReplaySelectionMethod(Runnable replaySelectionMethod) {
private void exportSuggestions() {
List suggestions = exportSelectedSuggestions();
if (suggestions.isEmpty()) {
- JOptionPane.showMessageDialog(this,
- "No suggestions selected. Please select at least one suggestion to "
- + "export", "No suggestions selected",
- JOptionPane.INFORMATION_MESSAGE);
+ showExportingMessage("No suggestions selected. Please select at least one suggestion to "
+ + "export");
return;
}
Map> repositoryAndSuggestions = new HashMap<>();
+ boolean isDraft = false;
for (CorrelationSuggestion suggestion : suggestions) {
Template source = suggestion.getSource();
if (source != null) { // Source null is automatic, and not null is Template based
String repositoryId = source.getRepositoryId();
+ if ("Draft".equals(repositoryId)) {
+ isDraft = true;
+ continue;
+ }
if (!repositoryAndSuggestions.containsKey(repositoryId)) {
repositoryAndSuggestions.put(repositoryId, new HashSet<>());
}
@@ -353,6 +356,45 @@ private void exportSuggestions() {
Set canExport = new HashSet<>();
Set cannotExport = new HashSet<>();
+ populateTemplateExports(repositoryAndSuggestions, canExport, cannotExport);
+
+ if (!cannotExport.isEmpty()) {
+ JOptionPane.showMessageDialog(this,
+ "The suggestions generated from the following sources\n can't be exported:\n"
+ + String.join("\n", cannotExport.stream()
+ .map(RepositoryUtils::getTemplateInfo)
+ .collect(Collectors.joining("\n"))),
+ "Non-exportable templates",
+ JOptionPane.INFORMATION_MESSAGE);
+ }
+
+ Set rules = new HashSet<>();
+ for (CorrelationSuggestion suggestion : suggestions) {
+ Template source = suggestion.getSource();
+ // Automatic or Template based
+ if (source == null || templateContains(canExport, source)) {
+ rules.addAll(suggestion.toCorrelationRules());
+ }
+ }
+
+ exportRulesConsumer.accept(new ArrayList<>(rules));
+ if (isDraft) {
+ showExportingMessage(
+ "Draft rules weren't exported, they remain in Correlation Panel already.");
+ } else if (rules.isEmpty()) {
+ showExportingMessage("We didn't find any rules to export.");
+ } else {
+ showExportingMessage("Export successful.");
+ }
+ }
+
+ private void showExportingMessage(String message) {
+ JOptionPane.showMessageDialog(this,
+ message, "Exporting rules", JOptionPane.INFORMATION_MESSAGE);
+ }
+
+ private void populateTemplateExports(Map> repositoryAndSuggestions,
+ Set canExport, Set cannotExport) {
for (Map.Entry> entry : repositoryAndSuggestions.entrySet()) {
String repositoryName = entry.getKey();
List templates = new ArrayList<>(entry.getValue());
@@ -385,32 +427,6 @@ private void exportSuggestions() {
}
}
}
-
- if (!cannotExport.isEmpty()) {
- JOptionPane.showMessageDialog(this,
- "The suggestions generated from the following sources\n can't be exported:\n"
- + String.join("\n", cannotExport.stream()
- .map(RepositoryUtils::getTemplateInfo)
- .collect(Collectors.joining("\n"))),
- "Non-exportable templates",
- JOptionPane.INFORMATION_MESSAGE);
- }
-
- Set rules = new HashSet<>();
- for (CorrelationSuggestion suggestion : suggestions) {
- Template source = suggestion.getSource();
- // Automatic or Template based
- if (source == null || templateContains(canExport, source)) {
- rules.addAll(suggestion.toCorrelationRules());
- }
- }
-
- exportRulesConsumer.accept(new ArrayList<>(rules));
- JOptionPane.showMessageDialog(this,
- rules.isEmpty() ? "We didn't find any rules to export."
- : "Export successful.",
- "Exporting rules",
- JOptionPane.INFORMATION_MESSAGE);
}
private boolean templateContains(Set list, Template toMatch) {
diff --git a/src/main/java/com/blazemeter/jmeter/correlation/gui/automatic/CorrelationWizard.java b/src/main/java/com/blazemeter/jmeter/correlation/gui/automatic/CorrelationWizard.java
index 65c7f49..c79662a 100644
--- a/src/main/java/com/blazemeter/jmeter/correlation/gui/automatic/CorrelationWizard.java
+++ b/src/main/java/com/blazemeter/jmeter/correlation/gui/automatic/CorrelationWizard.java
@@ -15,6 +15,7 @@
import com.blazemeter.jmeter.correlation.core.templates.LocalConfiguration;
import com.blazemeter.jmeter.correlation.core.templates.Repository;
import com.blazemeter.jmeter.correlation.core.templates.Template;
+import com.blazemeter.jmeter.correlation.core.templates.Template.Builder;
import com.blazemeter.jmeter.correlation.gui.analysis.CorrelationTemplatesSelectionPanel;
import com.helger.commons.annotation.VisibleForTesting;
import java.awt.Component;
@@ -26,6 +27,7 @@
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
+import java.util.function.Function;
import java.util.function.Supplier;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
@@ -63,6 +65,7 @@ public class CorrelationWizard extends JDialog {
private LocalConfiguration configuration;
private SuggestionGenerator suggestionGenerator;
+ private Function buildTemplate;
public CorrelationWizard() {
super();
@@ -93,6 +96,7 @@ private void initCorrelateByRulesPanels() {
if (history != null) {
templateSelectionPanel.setGetCorrelationHistorySupplier(() -> history);
}
+ templateSelectionPanel.setBuildTemplate(buildTemplate);
templateSelectionPanel.setStartNonCorrelatedAnalysis(startNonCorrelatedAnalysis());
}
@@ -474,4 +478,11 @@ public void setConfiguration(LocalConfiguration configuration) {
this.configuration = configuration;
}
+ public void setBuildTemplateProvider(Function buildTemplate) {
+ this.buildTemplate = buildTemplate;
+ }
+
+ public Function getBuildTemplate() {
+ return buildTemplate;
+ }
}
diff --git a/src/main/java/com/blazemeter/jmeter/correlation/gui/automatic/SelectAllHeader.java b/src/main/java/com/blazemeter/jmeter/correlation/gui/automatic/SelectAllHeader.java
index f9d78da..3ea49f8 100644
--- a/src/main/java/com/blazemeter/jmeter/correlation/gui/automatic/SelectAllHeader.java
+++ b/src/main/java/com/blazemeter/jmeter/correlation/gui/automatic/SelectAllHeader.java
@@ -138,7 +138,7 @@ public void itemStateChanged(ItemEvent e) {
table.setValueAt(state, r, viewColumn);
}
updating = false;
- } catch (ArrayIndexOutOfBoundsException ex) {
+ } catch (IndexOutOfBoundsException ex) {
// This is thrown when the table is cleared
return;
}
diff --git a/src/main/java/com/blazemeter/jmeter/correlation/gui/common/ThemedIcon.java b/src/main/java/com/blazemeter/jmeter/correlation/gui/common/ThemedIcon.java
index f0a2963..23ec949 100644
--- a/src/main/java/com/blazemeter/jmeter/correlation/gui/common/ThemedIcon.java
+++ b/src/main/java/com/blazemeter/jmeter/correlation/gui/common/ThemedIcon.java
@@ -10,7 +10,7 @@ public class ThemedIcon {
private static final Map CACHED_ICONS = new WeakHashMap<>();
private static final Pattern DARK_THEME_PATTERN = Pattern
- .compile("Intellij|HighContrastLight|HighContrastDark|Darcula|Motif|OneDark|SolarizedDark");
+ .compile("HighContrastDark|Darcula|OneDark|SolarizedDark");
public static ImageIcon fromResourceName(String resourceName) {
String resourcePath = getThemePath() + "/" + resourceName;
diff --git a/src/main/resources/dark-theme/lock.png b/src/main/resources/dark-theme/lock.png
index 26593e5..e6f85a2 100644
Binary files a/src/main/resources/dark-theme/lock.png and b/src/main/resources/dark-theme/lock.png differ
diff --git a/src/main/resources/templates/correlation-recorder-template-description.xml b/src/main/resources/templates/auto-correlation-recorder-template-description.xml
similarity index 80%
rename from src/main/resources/templates/correlation-recorder-template-description.xml
rename to src/main/resources/templates/auto-correlation-recorder-template-description.xml
index 7a228aa..f4901fa 100644
--- a/src/main/resources/templates/correlation-recorder-template-description.xml
+++ b/src/main/resources/templates/auto-correlation-recorder-template-description.xml
@@ -1,6 +1,6 @@
- bzm - Correlation Recorder
- /bin/templates/correlation-recorder.jmx
+ bzm - Auto Correlation Recorder
+ /bin/templates/auto-correlation-recorder.jmx
Template showing how to record Correlated Scripts
JMeter Configuration
@@ -16,8 +16,9 @@
Useful links
]]>
-
\ No newline at end of file
+
diff --git a/src/main/resources/templates/correlation-recorder.jmx b/src/main/resources/templates/auto-correlation-recorder.jmx
similarity index 99%
rename from src/main/resources/templates/correlation-recorder.jmx
rename to src/main/resources/templates/auto-correlation-recorder.jmx
index cc7e248..2b6db82 100644
--- a/src/main/resources/templates/correlation-recorder.jmx
+++ b/src/main/resources/templates/auto-correlation-recorder.jmx
@@ -94,7 +94,7 @@
false
-
+
8888
.*(?!(\.json))(\.js)(.*|$)
diff --git a/src/test/java/com/blazemeter/jmeter/correlation/CorrelationProxyControlBuilder.java b/src/test/java/com/blazemeter/jmeter/correlation/CorrelationProxyControlBuilder.java
index ad1e8d8..f9521df 100644
--- a/src/test/java/com/blazemeter/jmeter/correlation/CorrelationProxyControlBuilder.java
+++ b/src/test/java/com/blazemeter/jmeter/correlation/CorrelationProxyControlBuilder.java
@@ -66,7 +66,7 @@ public CorrelationProxyControl build() {
CorrelationProxyControl model =
new CorrelationProxyControl(registry, repositoriesRegistry, configuration, engine);
- model.setName("bzm - Correlation Recorder");
+ model.setName("bzm - Auto Correlation Recorder");
if (target != null) {
model.setTarget(target);
diff --git a/src/test/java/com/blazemeter/jmeter/correlation/gui/automatic/CorrelationWizardIT.java b/src/test/java/com/blazemeter/jmeter/correlation/gui/automatic/CorrelationWizardIT.java
index 9885a1c..c672d60 100644
--- a/src/test/java/com/blazemeter/jmeter/correlation/gui/automatic/CorrelationWizardIT.java
+++ b/src/test/java/com/blazemeter/jmeter/correlation/gui/automatic/CorrelationWizardIT.java
@@ -1,21 +1,28 @@
package com.blazemeter.jmeter.correlation.gui.automatic;
import static org.assertj.swing.fixture.Containers.showInFrame;
+import static org.mockito.ArgumentMatchers.any;
+
import com.blazemeter.jmeter.correlation.SwingTestRunner;
import com.blazemeter.jmeter.correlation.core.automatic.CorrelationHistory;
import com.blazemeter.jmeter.correlation.core.templates.Template;
import com.blazemeter.jmeter.correlation.core.templates.Repository;
+import com.blazemeter.jmeter.correlation.core.templates.Template.Builder;
import java.awt.Container;
import java.io.File;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Function;
import org.assertj.core.api.JUnitSoftAssertions;
import org.assertj.swing.fixture.FrameFixture;
+import org.jetbrains.annotations.NotNull;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
@RunWith(SwingTestRunner.class)
@@ -24,6 +31,8 @@ public class CorrelationWizardIT {
public JUnitSoftAssertions softly = new JUnitSoftAssertions();
private FrameFixture frame;
private CorrelationWizard wizard;
+ @Mock
+ public Function buildProvider;
@Before
public void setUp() throws Exception {
@@ -34,6 +43,8 @@ public void setUp() throws Exception {
CorrelationHistory history = new CorrelationHistory();
wizard.setHistory(history);
wizard.setRepositoriesSupplier(CorrelationWizardIT::getMockedRepository);
+ Mockito.when(buildProvider.apply(any())).thenReturn(new Template());
+ wizard.setBuildTemplateProvider(buildProvider);
wizard.init();
Container contentPane = wizard.getContentPane();
wizard.displayTemplateSelection("Test");
@@ -124,4 +135,4 @@ public void shouldLoadTemplateVersionsWhenReloadClicked() {
private void templateSelectionPressReloadTemplates() {
frame.button("templateReloadButtonButton").click();
}
-}
\ No newline at end of file
+}
diff --git a/src/test/resources/selectedReplacementDescription.html b/src/test/resources/selectedReplacementDescription.html
index a088eee..22afa1a 100644
--- a/src/test/resources/selectedReplacementDescription.html
+++ b/src/test/resources/selectedReplacementDescription.html
@@ -3,4 +3,4 @@
.tg td { border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; font-family: Arial, sans-serif; padding-top: 10px; padding-bottom: 10px; padding-right: 5px; padding-left: 5px }
.tg th { border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; font-family: Arial, sans-serif; font-weight: normal; padding-top: 10px; padding-bottom: 10px; padding-right: 5px; padding-left: 5px }
.tg .tg-0lax { text-align: left; vertical-align: top }
- -->Siebel Counter Correlation ReplacementReplaces the matched regex with a counter that holds the value of each time it has matched on the moment the replacement occurs.
Field | Description | Default Value |
---|
RegEx | Allows to get the value of the SWECount variable in order to extract it | param="(.+?)" |
For more information about Replacements and how to use them, check the Documentation at List of Correlation Replacements