Mercurial > stress-tester
changeset 903:8b26804049d4
HttpMessageModificationFilter - $lookup operator
author | Devel 2 |
---|---|
date | Wed, 18 Apr 2018 10:47:13 +0200 |
parents | f8b01b4c713f |
children | ede69c8df2fa |
files | stress-tester/src/main/java/com/passus/st/client/http/filter/HttpMessageModificationFilter.java stress-tester/src/main/java/com/passus/st/client/http/filter/HttpMessageModificationFilterTransformer.java stress-tester/src/test/java/com/passus/st/client/http/filter/HttpMessageModificationFilterTest.java stress-tester/src/test/java/com/passus/st/client/http/filter/HttpMessageModificationFilterTransformerTest.java |
diffstat | 4 files changed, 131 insertions(+), 67 deletions(-) [+] |
line wrap: on
line diff
--- a/stress-tester/src/main/java/com/passus/st/client/http/filter/HttpMessageModificationFilter.java Wed Apr 18 09:02:17 2018 +0200 +++ b/stress-tester/src/main/java/com/passus/st/client/http/filter/HttpMessageModificationFilter.java Wed Apr 18 10:47:13 2018 +0200 @@ -11,6 +11,7 @@ import com.passus.data.ByteString; import com.passus.filter.UnmutableValueExtractor; import com.passus.filter.ValueExtractor; +import com.passus.lookup.filter.LookupValueExtractorDefinitionCreator; import com.passus.net.http.HttpMessageHelper; import com.passus.net.http.HttpParameters; import com.passus.net.http.HttpRequest; @@ -20,17 +21,17 @@ import com.passus.st.config.HeaderOperationNodeDefinition; import com.passus.st.plugin.PluginConstants; import com.passus.st.validation.HeaderNameValidator; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + import java.text.ParseException; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; import static com.passus.config.schema.ConfigurationSchemaBuilder.*; /** - * * @author Mirosław Hawrot */ @NodeDefinitionCreate(HttpMessageModificationFilter.HttpMessageModificationFilterNodeDefCreator.class) @@ -603,12 +604,15 @@ @Override public NodeDefinition create() { + NodeDefinition lookupNodeDef = LookupValueExtractorDefinitionCreator.createNodeDef(); + NodeDefinition paramNodeDef = new HeaderOperationNodeDefinition( mixedDef( valueDef(), listDef(valueDef()), mapDef( - tupleDef("$expr", valueDef()) + tupleDef("$expr", valueDef()).setRequired(false), + tupleDef("$lookup", lookupNodeDef).setRequired(false) ) ) ).addParam(tupleDef("*escape", valueDefBool()).setRequired(false)); @@ -616,7 +620,10 @@ HeaderOperationNodeDefinition headerNodeDef = new HeaderOperationNodeDefinition( mixedDef( valueDef(), - mapDef(tupleDef("$expr", valueDef())) + mapDef( + tupleDef("$expr", valueDef()).setRequired(false), + tupleDef("$lookup", lookupNodeDef).setRequired(false) + ) ) ).addParam(tupleDef("*escape", valueDefBool()).setRequired(false));
--- a/stress-tester/src/main/java/com/passus/st/client/http/filter/HttpMessageModificationFilterTransformer.java Wed Apr 18 09:02:17 2018 +0200 +++ b/stress-tester/src/main/java/com/passus/st/client/http/filter/HttpMessageModificationFilterTransformer.java Wed Apr 18 10:47:13 2018 +0200 @@ -1,37 +1,32 @@ package com.passus.st.client.http.filter; -import com.passus.config.CListNode; -import com.passus.config.CMapNode; -import com.passus.config.CNode; -import com.passus.config.CTupleNode; -import com.passus.config.CValueNode; -import com.passus.config.ConfigurationContext; -import com.passus.config.ConfigurationUtils; -import com.passus.config.NodeType; +import com.passus.config.*; import com.passus.config.schema.NodeTransformer; import com.passus.config.validation.Errors; import com.passus.filter.ValueExtractor; import com.passus.filter.config.ExpressionNodeTransformer; +import com.passus.lookup.Lookup; +import com.passus.lookup.filter.LookupValueExtractorTransformer; import com.passus.st.client.http.extractor.ContentExtractorUtils; import com.passus.st.client.http.extractor.ContentReplacer; import com.passus.st.client.http.filter.HttpMessageModificationFilter.*; import com.passus.st.filter.Transformers; import com.passus.st.utils.ConfigurationContextConsts; -import static com.passus.st.validation.NodeValidationUtils.validateType; - import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; +import static com.passus.st.validation.NodeValidationUtils.validateType; + /** * @author Mirosław Hawrot */ public class HttpMessageModificationFilterTransformer implements NodeTransformer { private static Operation createNameOperation(CTupleNode tuple, - Errors errors, Class<? extends Operation> clazz) { + Errors errors, Class<? extends Operation> clazz) { if (validateType(tuple.getNode(), NodeType.VALUE, errors)) { CValueNode valNode = (CValueNode) tuple.getNode(); try { @@ -46,9 +41,53 @@ return null; } + private static ValueExtractor createValueExtractor(CNode node, Errors errors, + ExpressionNodeTransformer expressionNodeTransformer, + LookupValueExtractorTransformer lookupValueTransformer) { + NodeType type = node.getType(); + ValueExtractor valueExtractor = null; + if (type == NodeType.VALUE) { + try { + valueExtractor = expressionNodeTransformer.transform(node); + } catch (Exception e) { + errors.reject("Invalid expression.", node); + } + } else if (type == NodeType.MAP) { + CMapNode mapNode = (CMapNode) node; + if (mapNode.size() != 1) { + errors.reject("Invalid node.", node); + return null; + } + + CTupleNode tupleNode = mapNode.getFirstChild(); + String opName = tupleNode.getName(); + if (opName.equals("$expr")) { + try { + valueExtractor = expressionNodeTransformer.transform(node); + } catch (Exception e) { + errors.reject("Invalid expression.", node); + } + } else if (opName.equals("$lookup")) { + CNode valNode = tupleNode.getNode(); + try { + valueExtractor = (ValueExtractor) lookupValueTransformer.transform(valNode); + } catch(NodeConversionException e) { + errors.reject("Invalid lookup definition. " + e.getMessage(), valNode); + } catch(Exception e) { + errors.reject("Invalid lookup definition.", valNode); + } + } + } else { + errors.reject("Invalid node.", node); + } + + return valueExtractor; + } + private static AbstractNameValueOperation createNameValueOperation(CTupleNode nodeTuple, - Errors errors, Class<? extends AbstractNameValueOperation> clazz, - ExpressionNodeTransformer expressionNodeTransformer) { + Errors errors, Class<? extends AbstractNameValueOperation> clazz, + ExpressionNodeTransformer expressionNodeTransformer, + LookupValueExtractorTransformer lookupValueTransformer) { AbstractNameValueOperation op = null; if (validateType(nodeTuple.getNode(), NodeType.MAP, errors)) { @@ -64,19 +103,12 @@ break; default: CNode valNode = tuple.getNode(); - NodeType type = valNode.getType(); - if (type == NodeType.VALUE || type == NodeType.MAP) { - try { - valueExtractor = expressionNodeTransformer.transform(valNode); - field = name; - } catch (Exception e) { - errors.reject("Invalid expression.", valNode); - return null; - } - } else { - errors.reject("Invalid node.", valNode); + valueExtractor = createValueExtractor(valNode, errors, expressionNodeTransformer, lookupValueTransformer); + if (valueExtractor == null) { return null; } + + field = name; } if (errors.hasError()) { @@ -100,8 +132,9 @@ } private static AddParamOperation createAddParamOperation(CTupleNode nodeTuple, - Errors errors, Class<? extends AddParamOperation> clazz, - ExpressionNodeTransformer expressionNodeTransformer) { + Errors errors, Class<? extends AddParamOperation> clazz, + ExpressionNodeTransformer expressionNodeTransformer, + LookupValueExtractorTransformer lookupValueTransformer) { AddParamOperation op = null; if (validateType(nodeTuple.getNode(), NodeType.MAP, errors)) { @@ -118,18 +151,10 @@ default: paramName = tuple.getName(); CNode valNode = tuple.getNode(); - NodeType type = valNode.getType(); - if (type == NodeType.VALUE || type == NodeType.MAP) { - try { - valueExtractor = expressionNodeTransformer.transform(valNode); - } catch (Exception e) { - errors.reject("Invalid expression.", valNode); - return null; - } - } else { - throw new RuntimeException("Value or Map node required."); + valueExtractor = createValueExtractor(valNode, errors, expressionNodeTransformer, lookupValueTransformer); + if (valueExtractor == null) { + return null; } - break; } if (errors.hasError()) { @@ -164,7 +189,9 @@ } Map<String, ValueExtractor> vars = (Map<String, ValueExtractor>) context.get(ConfigurationContextConsts.APP_VARS); - final ExpressionNodeTransformer transformer = Transformers.expressionNodeTransformer(vars); + List<Lookup> lookups = context.get(ConfigurationContextConsts.LOOKUPS, Collections.EMPTY_LIST); + final ExpressionNodeTransformer expressionNodeTransformer = Transformers.expressionNodeTransformer(vars); + final LookupValueExtractorTransformer lookupValueTransformer = new LookupValueExtractorTransformer(lookups); for (CTupleNode tuple : tuples) { String opName = tuple.getName(); @@ -176,37 +203,37 @@ op = createNameOperation(tuple, errors, RemoveHeaderOperation.class); break; case "addheader": - op = createNameValueOperation(tuple, errors, AddHeaderOperation.class, transformer); + op = createNameValueOperation(tuple, errors, AddHeaderOperation.class, expressionNodeTransformer, lookupValueTransformer); break; case "setheader": - op = createNameValueOperation(tuple, errors, SetHeaderOperation.class, transformer); + op = createNameValueOperation(tuple, errors, SetHeaderOperation.class, expressionNodeTransformer, lookupValueTransformer); break; case "removecookie": op = createNameOperation(tuple, errors, RemoveCookieOperation.class); break; case "addcookie": - op = createNameValueOperation(tuple, errors, AddCookieOperation.class, transformer); + op = createNameValueOperation(tuple, errors, AddCookieOperation.class, expressionNodeTransformer, lookupValueTransformer); break; case "setcookie": - op = createNameValueOperation(tuple, errors, SetCookieOperation.class, transformer); + op = createNameValueOperation(tuple, errors, SetCookieOperation.class, expressionNodeTransformer, lookupValueTransformer); break; case "removepostparam": op = createNameOperation(tuple, errors, PostDataRemoveParamOperation.class); break; case "addpostparam": - op = createAddParamOperation(tuple, errors, PostDataAddParamOperation.class, transformer); + op = createAddParamOperation(tuple, errors, PostDataAddParamOperation.class, expressionNodeTransformer, lookupValueTransformer); break; case "setpostparam": - op = createAddParamOperation(tuple, errors, PostDataSetParamOperation.class, transformer); + op = createAddParamOperation(tuple, errors, PostDataSetParamOperation.class, expressionNodeTransformer, lookupValueTransformer); break; case "removequeryparam": op = createNameOperation(tuple, errors, RemoveQueryParameterOperation.class); break; case "addqueryparam": - op = createNameValueOperation(tuple, errors, AddQueryParameterOperation.class, transformer); + op = createNameValueOperation(tuple, errors, AddQueryParameterOperation.class, expressionNodeTransformer, lookupValueTransformer); break; case "setqueryparam": - op = createNameValueOperation(tuple, errors, SetQueryParameterOperation.class, transformer); + op = createNameValueOperation(tuple, errors, SetQueryParameterOperation.class, expressionNodeTransformer, lookupValueTransformer); break; case "setcontent": if (validateType(tuple.getNode(), NodeType.MAP, errors)) {
--- a/stress-tester/src/test/java/com/passus/st/client/http/filter/HttpMessageModificationFilterTest.java Wed Apr 18 09:02:17 2018 +0200 +++ b/stress-tester/src/test/java/com/passus/st/client/http/filter/HttpMessageModificationFilterTest.java Wed Apr 18 10:47:13 2018 +0200 @@ -257,6 +257,7 @@ Errors errors = new Errors(); ConfigurationContextImpl emptyContext = new ConfigurationContextImpl(); List<HttpFilter> filters = HttpFiltersConfigurator.getFilters(filterConfig, errors, emptyContext); + HttpFilterTestUtils.printErrors(errors); HttpMessageModificationFilter filter = (HttpMessageModificationFilter) filters.get(0); HttpFlowContext mockContext = HttpFilterTestUtils.createMockContext();
--- a/stress-tester/src/test/java/com/passus/st/client/http/filter/HttpMessageModificationFilterTransformerTest.java Wed Apr 18 09:02:17 2018 +0200 +++ b/stress-tester/src/test/java/com/passus/st/client/http/filter/HttpMessageModificationFilterTransformerTest.java Wed Apr 18 10:47:13 2018 +0200 @@ -1,25 +1,29 @@ package com.passus.st.client.http.filter; +import com.passus.commons.utils.ReflectionUtils; +import com.passus.config.*; +import com.passus.config.validation.Errors; +import com.passus.filter.UnmutableValueExtractor; +import com.passus.filter.ValueExtractor; +import com.passus.lookup.Lookup; +import com.passus.lookup.LookupList; +import com.passus.lookup.filter.LookupValueExtractor; +import com.passus.st.client.http.filter.HttpMessageModificationFilter.*; +import com.passus.st.utils.ConfigurationContextConsts; +import org.testng.annotations.Test; + +import java.util.List; +import java.util.Map; +import java.util.Set; + import static com.passus.commons.collection.FluentBuilder.e; import static com.passus.commons.collection.FluentBuilder.map; -import com.passus.commons.utils.ReflectionUtils; -import com.passus.config.CMapNode; -import com.passus.config.CTupleNode; -import com.passus.config.CValueNode; -import com.passus.config.ConfigurationContextImpl; -import com.passus.config.YamlConfigurationReader; -import com.passus.config.validation.Errors; -import com.passus.filter.UnmutableValueExtractor; -import com.passus.filter.ValueExtractor; -import com.passus.st.client.http.filter.HttpMessageModificationFilter.*; import static com.passus.st.client.http.filter.HttpVarsFilterTest.expr; import static com.passus.st.client.http.filter.HttpVarsFilterTest.val; -import com.passus.st.filter.HttpMessageWrapperDynamicExtractor; -import com.passus.st.utils.ConfigurationContextConsts; -import java.util.List; -import java.util.Map; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; import static org.testng.AssertJUnit.*; -import org.testng.annotations.Test; /** * @@ -229,7 +233,6 @@ ConfigurationContextImpl context = new ConfigurationContextImpl(); context.add(ConfigurationContextConsts.APP_VARS, appVars); CValueNode value = transformer.transform(node.getNode(), errors, context); - HttpFilterTestUtils.printErrors(errors); List<Operation> operations = (List) value.getValue(); assertEquals("req.url.path", getFieldName(operations.get(0))); @@ -237,6 +240,32 @@ assertEquals("value1", getExtractorValue(operations.get(2))); } + @Test + public void testTransform_lookups() throws Exception { + ConfigurationContextImpl context = new ConfigurationContextImpl(); + Lookup lookup = mock(Lookup.class); + when(lookup.getName()).thenReturn("test"); + when(lookup.lookup(any(Set.class), any(Lookup.KeyInfo.class))).thenReturn("testValue"); + + LookupList lookups = new LookupList(lookup); + context.add(ConfigurationContextConsts.LOOKUPS, lookups); + String config = "operations:\n" + + " setHeader:\n" + + " H2: {$lookup: {name: 'test', keys: {col1: test}}}\n"; + CTupleNode node = read(config); + Errors errors = new Errors(); + CValueNode value = transformer.transform(node.getNode(), errors, context); + + assertEquals(0, errors.getErrorCount()); + + List<Operation> operations = (List) value.getValue(); + SetHeaderOperation operation = (SetHeaderOperation)operations.get(0); + assertTrue(operation.getValueExtractor() instanceof LookupValueExtractor); + + LookupValueExtractor lookupValueExtractor = (LookupValueExtractor) operation.getValueExtractor(); + assertSame(lookup, lookupValueExtractor.getLookup()); + } + private static boolean getReplacerEscape(Operation o) { return ReflectionUtils.getFieldByPath(o, "replacer.escape"); }