http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/UrlRewriteStepProcessorStateTest.java ---------------------------------------------------------------------- diff --git a/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/UrlRewriteStepProcessorStateTest.java b/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/UrlRewriteStepProcessorStateTest.java new file mode 100644 index 0000000..bf64905 --- /dev/null +++ b/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/UrlRewriteStepProcessorStateTest.java @@ -0,0 +1,255 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.apache.knox.gateway.filter.rewrite.impl; + +import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteEnvironment; +import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFlowDescriptor; +import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteStepDescriptor; +import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteStepFlow; +import org.apache.knox.gateway.filter.rewrite.spi.UrlRewriteContext; +import org.apache.knox.gateway.filter.rewrite.spi.UrlRewriteStepProcessor; +import org.apache.knox.gateway.filter.rewrite.spi.UrlRewriteStepStatus; +import org.hamcrest.CoreMatchers; +import org.hamcrest.MatcherAssert; +import org.junit.Test; + +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.MatcherAssert.assertThat; + +public class UrlRewriteStepProcessorStateTest { + + @Test + public void testEmpty() { + List<UrlRewriteStepProcessorHolder> steps = new ArrayList<UrlRewriteStepProcessorHolder>(); + UrlRewriteStepProcessorState state = new UrlRewriteStepProcessorState( steps.iterator() ); + + MatcherAssert + .assertThat( state.status(), CoreMatchers.is( UrlRewriteStepStatus.SUCCESS ) ); + assertThat( state.hasNext(), is( false ) ); + assertThat( state.hasNextAction(), is( false ) ); + assertThat( state.hasNextCondition(), is( false ) ); + assertThat( state.nextAction( UrlRewriteStepStatus.SUCCESS ), nullValue() ); + assertThat( state.nextCondition( UrlRewriteStepStatus.SUCCESS ), nullValue() ); + } + + @Test + public void testNextAction() throws Exception { + UrlRewriteStepProcessorHolder holder; + List<UrlRewriteStepProcessorHolder> steps = new ArrayList<UrlRewriteStepProcessorHolder>(); + holder = new UrlRewriteStepProcessorHolder(); + holder.initialize( new FakeEnvironment(), new FakeActionDescriptor( "one" ), new FakeActionProcessor( "one" ) ); + steps.add( holder ); + holder = new UrlRewriteStepProcessorHolder(); + holder.initialize( new FakeEnvironment(), new FakeActionDescriptor( "two" ), new FakeActionProcessor( "two" ) ); + steps.add( holder ); + UrlRewriteStepProcessorState state = new UrlRewriteStepProcessorState( steps.iterator() ); + assertThat( state.hasNext(), is( true ) ); + assertThat( state.hasNextAction(), is( true ) ); + assertThat( state.hasNextCondition(), is( false ) ); + assertThat( state.nextCondition( UrlRewriteStepStatus.SUCCESS ), nullValue() ); + + holder = state.nextAction( UrlRewriteStepStatus.SUCCESS ); + assertThat( ((FakeActionDescriptor)holder.getDescriptor()).name, is( "one" ) ); + + assertThat( state.hasNext(), is( true ) ); + assertThat( state.hasNextAction(), is( true ) ); + assertThat( state.hasNextCondition(), is( false ) ); + assertThat( state.nextCondition( UrlRewriteStepStatus.SUCCESS ), nullValue() ); + + holder = state.nextAction( UrlRewriteStepStatus.SUCCESS ); + assertThat( ((FakeActionDescriptor)holder.getDescriptor()).name, is( "two" ) ); + + assertThat( state.hasNext(), is( false ) ); + assertThat( state.hasNextAction(), is( false ) ); + assertThat( state.hasNextCondition(), is( false ) ); + assertThat( state.nextAction( UrlRewriteStepStatus.SUCCESS ), nullValue() ); + assertThat( state.nextCondition( UrlRewriteStepStatus.SUCCESS ), nullValue() ); + } + + @Test + public void testNextCondition() throws Exception { + UrlRewriteStepProcessorHolder holder; + List<UrlRewriteStepProcessorHolder> steps = new ArrayList<UrlRewriteStepProcessorHolder>(); + holder = new UrlRewriteStepProcessorHolder(); + holder.initialize( new FakeEnvironment(), new FakeConditionDescriptor( "one" ), new FakeConditionProcessor( "one" ) ); + steps.add( holder ); + holder = new UrlRewriteStepProcessorHolder(); + holder.initialize( new FakeEnvironment(), new FakeConditionDescriptor( "two" ), new FakeConditionProcessor( "two" ) ); + steps.add( holder ); + UrlRewriteStepProcessorState state = new UrlRewriteStepProcessorState( steps.iterator() ); + assertThat( state.hasNext(), is( true ) ); + assertThat( state.hasNextAction(), is( false ) ); + assertThat( state.hasNextCondition(), is( true ) ); + assertThat( state.nextAction( UrlRewriteStepStatus.SUCCESS ), nullValue() ); + + holder = state.nextCondition( UrlRewriteStepStatus.SUCCESS ); + assertThat( ((FakeConditionDescriptor)holder.getDescriptor()).name, is( "one" ) ); + + assertThat( state.hasNext(), is( true ) ); + assertThat( state.hasNextAction(), is( false ) ); + assertThat( state.hasNextCondition(), is( true ) ); + assertThat( state.nextAction( UrlRewriteStepStatus.SUCCESS ), nullValue() ); + + holder = state.nextCondition( UrlRewriteStepStatus.SUCCESS ); + assertThat( ((FakeConditionDescriptor)holder.getDescriptor()).name, is( "two" ) ); + + assertThat( state.hasNext(), is( false ) ); + assertThat( state.hasNextAction(), is( false ) ); + assertThat( state.hasNextCondition(), is( false ) ); + assertThat( state.nextAction( UrlRewriteStepStatus.SUCCESS ), nullValue() ); + assertThat( state.nextCondition( UrlRewriteStepStatus.SUCCESS ), nullValue() ); + } + + public class FakeActionDescriptor implements UrlRewriteStepDescriptor<FakeActionDescriptor> { + public String name; + + public FakeActionDescriptor( String name ) { + this.name = name; + } + + @Override + public String type() { + return "fake-action"; + } + + @Override + public FakeActionDescriptor type( String type ) { + return null; + } + + } + + public class FakeActionProcessor implements + UrlRewriteStepProcessor<UrlRewriteStepDescriptor<FakeActionDescriptor>> { + public String name; + + public FakeActionProcessor( String name ) { + this.name = name; + } + + @Override + public String getType() { + return "fake-action"; + } + + @Override + public void initialize( UrlRewriteEnvironment environment, UrlRewriteStepDescriptor<FakeActionDescriptor> descriptor ) throws Exception { + } + + @Override + public UrlRewriteStepStatus process( UrlRewriteContext context ) throws Exception { + return null; + } + + @Override + public void destroy() throws Exception { + } + } + + public class FakeConditionDescriptor implements UrlRewriteFlowDescriptor<FakeConditionDescriptor> { + public String name; + + public FakeConditionDescriptor( String name ) { + this.name = name; + } + + @Override + public UrlRewriteStepFlow flow() { + return null; + } + + @Override + public FakeConditionDescriptor flow( String flow ) { + return null; + } + + @Override + public FakeConditionDescriptor flow( UrlRewriteStepFlow flow ) { + return null; + } + + @Override + public List<UrlRewriteStepDescriptor> steps() { + return null; + } + + @Override + public <T extends UrlRewriteStepDescriptor<?>> T addStep( String type ) { + return null; + } + + @Override + public String type() { + return "fake-condition"; + } + + @Override + public FakeConditionDescriptor type( String type ) { + return null; + } + } + + public class FakeConditionProcessor implements UrlRewriteStepProcessor<FakeConditionDescriptor> { + public String name; + + public FakeConditionProcessor( String name ) { + this.name = name; + } + + @Override + public String getType() { + return "fake-condition"; + } + + @Override + public void initialize( UrlRewriteEnvironment environment, FakeConditionDescriptor descriptor ) throws Exception { + } + + @Override + public UrlRewriteStepStatus process( UrlRewriteContext context ) throws Exception { + return null; + } + + @Override + public void destroy() throws Exception { + } + } + + private class FakeEnvironment implements UrlRewriteEnvironment { + @Override + public URL getResource( String name ) throws IOException { + return null; + } + + @Override + public <T> T getAttribute( String name ) { + return null; + } + + @Override + public List<String> resolve( String name ) { + return null; + } + } +}
http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/gateway.xml ---------------------------------------------------------------------- diff --git a/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/gateway.xml b/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/gateway.xml new file mode 100644 index 0000000..b95b90a --- /dev/null +++ b/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/gateway.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--> +<gateway> + <resource> + <role>WEBHDFS</role> + <pattern>/webhdfs/v1/?**</pattern> + ... + <filter> + <role>rewrite</role> + <name>url-rewrite</name> + <class>org.apache.knox.gateway.filter.rewrite.api.UrlRewriteServletFilter</class> + <param><name>request.url</name><value>???????????????</value></param> + <param><name>request.header</name><value>???????????????</value></param> + <param><name>request.body</name><value>???????????????</value></param> + </filter> + ... + </resource> +</gateway> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/html/HtmlFilterReaderBaseTest.java ---------------------------------------------------------------------- diff --git a/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/html/HtmlFilterReaderBaseTest.java b/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/html/HtmlFilterReaderBaseTest.java new file mode 100644 index 0000000..d146472 --- /dev/null +++ b/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/html/HtmlFilterReaderBaseTest.java @@ -0,0 +1,765 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.apache.knox.gateway.filter.rewrite.impl.html; + +import org.apache.commons.digester3.Digester; +import org.apache.commons.digester3.ExtendedBaseRules; +import org.apache.commons.digester3.binder.DigesterLoader; +import org.apache.commons.io.IOUtils; +import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFilterContentDescriptor; +import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteRuleDescriptor; +import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteRulesDescriptor; +import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteStepDescriptor; +import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteStepFlow; +import org.apache.knox.gateway.filter.rewrite.api.UrlRewriter; +import org.apache.knox.gateway.filter.rewrite.ext.UrlRewriteCheckDescriptorExt; +import org.apache.knox.gateway.filter.rewrite.ext.UrlRewriteControlDescriptor; +import org.apache.knox.gateway.filter.rewrite.ext.UrlRewriteMatchDescriptor; +import org.apache.knox.gateway.filter.rewrite.ext.UrlRewriteMatchDescriptorExt; +import org.apache.knox.gateway.filter.rewrite.impl.UrlRewriteFilterContentDescriptorImpl; +import org.apache.knox.gateway.filter.rewrite.impl.xml.XmlRewriteRulesDigester; +import org.apache.knox.gateway.filter.rewrite.spi.UrlRewriteActionDescriptorBase; +import org.hamcrest.Matchers; +import org.junit.Before; +import org.junit.Test; +import org.xml.sax.SAXException; +import org.xmlmatchers.namespace.SimpleNamespaceContext; + +import javax.xml.namespace.QName; +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Pattern; + +import static org.hamcrest.CoreMatchers.hasItem; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertEquals; +import static org.xmlmatchers.XmlMatchers.hasXPath; +import static org.xmlmatchers.transform.XmlConverters.the; + +public class HtmlFilterReaderBaseTest { + + public static class NoopXmlFilterReader extends HtmlFilterReaderBase { + public NoopXmlFilterReader( Reader reader ) throws IOException, ParserConfigurationException { + super( reader ); + } + + @Override + protected String filterText( QName elementName, String text, String ruleName ) { + return text; + } + + @Override + protected String filterAttribute( QName elementName, QName attributeName, String attributeValue, String ruleName ) { + return attributeValue; + } + + @Override + public String filterValueString( String name, String value, String ruleName ) { + return value; + } + } + + public static class MapXmlFilterReader extends HtmlFilterReaderBase { + private Map<String,String> map; + + public MapXmlFilterReader( Reader reader, Map<String,String> map ) throws IOException, ParserConfigurationException { + super( reader ); + this.map = map; + } + + @Override + protected String filterAttribute( QName elementName, QName attributeName, String attributeValue, String ruleName ) { + return map.get( attributeValue.trim() ); + } + + @Override + protected String filterText( QName elementName, String text, String ruleName ) { + return map.get( text.trim() ); + } + + @Override + public String filterValueString( String name, String value, String ruleName ) { + return map.get( value ); + } + } + + public static class MatchRuleXmlFilterReader extends HtmlFilterReaderBase { + private Map<String, Map<String,String>> rules; + public MatchRuleXmlFilterReader( Reader reader, Map<String, Map<String,String>> rules, UrlRewriteFilterContentDescriptor config ) throws IOException, ParserConfigurationException { + super( reader, config ); + this.rules = rules; + } + + @Override + protected String filterAttribute( QName elementName, QName attributeName, String attributeValue, String ruleName ) { + return filterValueString( attributeName.getLocalPart(), attributeValue, ruleName ); + } + + @Override + protected String filterText( QName elementName, String text, String ruleName ) { + return filterValueString( elementName.getLocalPart(), text, ruleName ); + } + + @Override + public String filterValueString( String name, String value, String ruleName ) { + Map<String, String> rule = rules.get( ruleName ); + if ( rule == null ){ + return value; + } + for ( Map.Entry<String, String> entry : rule.entrySet() ) { + if ( Pattern.compile( entry.getKey() ).matcher( value ).matches() ) { + return entry.getValue(); + } + } + return value; + } + } + + @Test + public void testSimple() throws IOException, ParserConfigurationException { + String inputXml = "<root/>"; + StringReader inputReader = new StringReader( inputXml ); + HtmlFilterReaderBase filterReader = new NoopXmlFilterReader( inputReader ); + String outputHtml = new String( IOUtils.toCharArray( filterReader ) ); + assertThat( the( outputHtml ), hasXPath( "/root" ) ); + } + + @Test + public void testSimpleNested() throws IOException, ParserConfigurationException { + String inputXml = "<root><child1><child11/><child12/></child1><child2><child21/><child22/></child2></root>"; + StringReader inputReader = new StringReader( inputXml ); + HtmlFilterReaderBase filterReader = new NoopXmlFilterReader( inputReader ); + String outputHtml = new String( IOUtils.toCharArray( filterReader ) ); + assertThat( the( outputHtml ), hasXPath( "/root" ) ); + assertThat( the( outputHtml ), hasXPath( "/root/child1" ) ); + assertThat( the( outputHtml ), hasXPath( "/root/child1/child11" ) ); + assertThat( the( outputHtml ), hasXPath( "/root/child1/child12" ) ); + assertThat( the( outputHtml ), hasXPath( "/root/child2" ) ); + assertThat( the( outputHtml ), hasXPath( "/root/child2/child21" ) ); + assertThat( the( outputHtml ), hasXPath( "/root/child2/child22" ) ); + } + + @Test + public void testSimpleWithNamespace() throws IOException, ParserConfigurationException { + String inputXml = "<ns:root xmlns:ns='http://hortonworks.com/xml/ns'></ns:root>"; + StringReader inputReader = new StringReader( inputXml ); + HtmlFilterReaderBase filterReader = new NoopXmlFilterReader( inputReader ); + String outputHtml = new String( IOUtils.toCharArray( filterReader ) ); + + //System.out.println( outputHtml ); + SimpleNamespaceContext ns = new SimpleNamespaceContext(); + ns.bind( "ns", "http://hortonworks.com/xml/ns" ); + assertThat( the( outputHtml ), hasXPath( "/ns:root", ns ) ); + } + + @Test + public void testSimpleTextNode() throws IOException, ParserConfigurationException { + String inputXml = "<root>text</root>"; + StringReader inputReader = new StringReader( inputXml ); + HtmlFilterReaderBase filterReader = new NoopXmlFilterReader( inputReader ); + String outputHtml = new String( IOUtils.toCharArray( filterReader ) ); + //System.out.println( outputHtml ); + assertThat( the( outputHtml ), hasXPath( "/root/text()", equalTo( "text" ) ) ); + } + + @Test + public void testSimpleAttribute() throws IOException, ParserConfigurationException { + String inputXml = "<root name='value'/>"; + StringReader inputReader = new StringReader( inputXml ); + HtmlFilterReaderBase filterReader = new NoopXmlFilterReader( inputReader ); + String outputHtml = new String( IOUtils.toCharArray( filterReader ) ); + //System.out.println( outputHtml ); + assertThat( the( outputHtml ), hasXPath( "/root/@name", equalTo( "value" ) ) ); + } + + @Test + public void testSimpleBooleanAttribute() throws IOException, ParserConfigurationException { + String inputXml = "<root name/>"; + StringReader inputReader = new StringReader(inputXml); + HtmlFilterReaderBase filterReader = new NoopXmlFilterReader(inputReader); + String outputHtml = new String(IOUtils.toCharArray(filterReader)); + assertEquals(inputXml, outputHtml); + } + + @Test + public void testComplexBooleanAttribute() throws IOException, ParserConfigurationException { + String inputXml = "<root boolean non-boolean='value' empty=''/>"; + StringReader inputReader = new StringReader(inputXml); + HtmlFilterReaderBase filterReader = new NoopXmlFilterReader(inputReader); + String outputHtml = new String(IOUtils.toCharArray(filterReader)); + assertEquals(inputXml, outputHtml); + } + + @Test + public void testMappedText() throws IOException, ParserConfigurationException { + Map<String,String> map = new HashMap<>(); + map.put( "input-text", "output-text" ); + String inputXml = "<root>input-text</root>"; + StringReader inputReader = new StringReader( inputXml ); + HtmlFilterReaderBase filterReader = new MapXmlFilterReader( inputReader, map ); + String outputHtml = new String( IOUtils.toCharArray( filterReader ) ); + //System.out.println( outputHtml ); + assertThat( the( outputHtml ), hasXPath( "/root/text()", equalTo( "output-text" ) ) ); + } + + @Test + public void testMappedAttribute() throws IOException, ParserConfigurationException { + Map<String,String> map = new HashMap<>(); + map.put( "input-text", "output-text" ); + String inputXml = "<root attribute='input-text'/>"; + StringReader inputReader = new StringReader( inputXml ); + HtmlFilterReaderBase filterReader = new MapXmlFilterReader( inputReader, map ); + String outputHtml = new String( IOUtils.toCharArray( filterReader ) ); + //System.out.println( outputHtml ); + assertThat( the( outputHtml ), hasXPath( "/root/@attribute", equalTo( "output-text" ) ) ); + } + + @Test + public void testCombined() throws IOException, ParserConfigurationException { + Map<String,String> map = new HashMap<>(); + map.put( "attr1-input", "attr1-output" ); + map.put( "attr2-input", "attr2-output" ); + map.put( "attr3-input", "attr3-output" ); + map.put( "attr4-input", "attr4-output" ); + map.put( "attr5-input", "attr5-output" ); + map.put( "attr6-input", "attr6-output" ); + map.put( "attr7-input", "attr7-output" ); + map.put( "root-input1", "root-output1" ); + map.put( "root-input2", "root-output2" ); + map.put( "root-input3", "root-output3" ); + map.put( "child1-input", "child1-output" ); + map.put( "child2-input", "child2-output" ); + + String inputXml = + "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" + + "<!-- Comment -->\n" + + "<ns1:root xmlns:ns1='http://hortonworks.com/xml/ns1' attr1='attr1-input' ns1:attr2='attr2-input'>\n" + + " root-input1\n" + + " <child1 attr3='attr3-input' ns1:attr4='attr4-input'>\n" + + " child1-input\n" + + " </child1>\n" + + " root-input2\n" + + " <ns2:child2 xmlns:ns2='http://hortonworks.com/xml/ns2' attr5='attr5-input' ns1:attr6='attr6-input' ns2:attr7='attr7-input'>\n" + + " child2-input\n" + + " </ns2:child2>\n" + + " root-input3\n" + + "</ns1:root>"; + //System.out.println( inputXml ); + + StringReader inputReader = new StringReader( inputXml ); + HtmlFilterReaderBase filterReader = new MapXmlFilterReader( inputReader, map ); + String outputXml = new String( IOUtils.toCharArray( filterReader ) ); + //System.out.println( outputXml ); + //System.out.flush(); + + SimpleNamespaceContext ns = new SimpleNamespaceContext(); + ns.bind( "n1", "http://hortonworks.com/xml/ns1" ); + ns.bind( "n2", "http://hortonworks.com/xml/ns2" ); + + assertThat( the( outputXml ), hasXPath( "/n1:root", ns ) ); + assertThat( the( outputXml ), hasXPath( "/n1:root/@attr1", ns, equalTo( "attr1-output" ) ) ); + assertThat( the( outputXml ), hasXPath( "/n1:root/@n1:attr2", ns, equalTo( "attr2-output" ) ) ); + assertThat( the( outputXml ), hasXPath( "/n1:root/text()[1]", ns, equalTo( "root-output1" ) ) ); + assertThat( the( outputXml ), hasXPath( "/n1:root/text()[2]", ns, equalTo( "root-output2" ) ) ); + assertThat( the( outputXml ), hasXPath( "/n1:root/text()[3]", ns, equalTo( "root-output3" ) ) ); + assertThat( the( outputXml ), hasXPath( "/n1:root/child1", ns ) ); + assertThat( the( outputXml ), hasXPath( "/n1:root/child1/@attr3", ns, equalTo( "attr3-output" ) ) ); + assertThat( the( outputXml ), hasXPath( "/n1:root/child1/@n1:attr4", ns, equalTo( "attr4-output" ) ) ); + assertThat( the( outputXml ), hasXPath( "/n1:root/child1/text()", ns, equalTo( "child1-output" ) ) ); + assertThat( the( outputXml ), hasXPath( "/n1:root/n2:child2", ns ) ); + assertThat( the( outputXml ), hasXPath( "/n1:root/n2:child2/@attr5", ns, equalTo( "attr5-output" ) ) ); + assertThat( the( outputXml ), hasXPath( "/n1:root/n2:child2/@n1:attr6", ns, equalTo( "attr6-output" ) ) ); + assertThat( the( outputXml ), hasXPath( "/n1:root/n2:child2/@n2:attr7", ns, equalTo( "attr7-output" ) ) ); + assertThat( the( outputXml ), hasXPath( "/n1:root/n2:child2/text()", ns, equalTo( "child2-output" ) ) ); + } + + @Test + public void testSimpleJavaScriptText() throws IOException, ParserConfigurationException { + String inputXml = "<root><script type=\"text/javascript\">input-js-text</script></root>"; + StringReader inputReader = new StringReader( inputXml ); + HtmlFilterReaderBase filterReader = new NoopXmlFilterReader( inputReader ); + String outputXml = new String( IOUtils.toCharArray( filterReader ) ); + assertThat( the( outputXml ), hasXPath( "/root/script/text()", equalTo( "input-js-text" ) ) ); + } + + @Test + public void testMatchedJavaScriptText() throws IOException, ParserConfigurationException { + Map<String, Map<String, String>> rules = new HashMap<>(); + Map<String, String> map = new HashMap<>(); + map.put( "(https?://[^/':,]+:[\\d]+)?/cluster/app", "https://knoxhost:8443/cluster/app" ); + rules.put( "test-rule", map ); + String inputXml = + "<root>\n" + + " <script type=\"text/javascript\">\n" + + " var appsTableData=[\n" + + " [\"<a href='/cluster/app/application_1436831599487_0008'>application_1436831599487_0008</a>\",\"hdfs\",\"Spark Pi\",\"SPARK\",\"<a href='http://testhost:8088/cluster/app/application_1436831599487_0008'>History</a>\"],\n" + + " [\"<a href='/cluster/app/application_1436831599487_0006'>application_1436831599487_0006</a>\",\"hdfs\",\"Spark Pi\",\"SPARK\",\"<a href='http://testhost:8088/cluster/app/application_1436831599487_0006'>History</a>\"],\n" + + " [\"<a href='/cluster/app/application_1436831599487_0007'>application_1436831599487_0007</a>\",\"hdfs\",\"Spark Pi\",\"SPARK\",\"<a href='http://testhost:8088/cluster/app/application_1436831599487_0007'>History</a>\"]\n" + + " ]\n" + + " </script>\n" + + "</root>\n"; + StringReader inputReader = new StringReader( inputXml ); + UrlRewriteFilterContentDescriptor config = new UrlRewriteFilterContentDescriptorImpl(); + config.addApply( "(https?://[^/':,]+:[\\d]+)?/cluster/app", "test-rule" ); + HtmlFilterReaderBase filterReader = new MatchRuleXmlFilterReader( inputReader, rules, config ); + String outputXml = new String( IOUtils.toCharArray( filterReader ) ); + String expectedOutput = + "<root>\n" + + " <script type=\"text/javascript\">\n" + + " var appsTableData=[\n" + + " [\"<a href='https://knoxhost:8443/cluster/app/application_1436831599487_0008'>application_1436831599487_0008</a>\",\"hdfs\",\"Spark Pi\",\"SPARK\",\"<a href='https://knoxhost:8443/cluster/app/application_1436831599487_0008'>History</a>\"],\n" + + " [\"<a href='https://knoxhost:8443/cluster/app/application_1436831599487_0006'>application_1436831599487_0006</a>\",\"hdfs\",\"Spark Pi\",\"SPARK\",\"<a href='https://knoxhost:8443/cluster/app/application_1436831599487_0006'>History</a>\"],\n" + + " [\"<a href='https://knoxhost:8443/cluster/app/application_1436831599487_0007'>application_1436831599487_0007</a>\",\"hdfs\",\"Spark Pi\",\"SPARK\",\"<a href='https://knoxhost:8443/cluster/app/application_1436831599487_0007'>History</a>\"]\n" + + " ]\n" + + " </script>\n" + + "</root>\n"; + assertThat( outputXml, is( expectedOutput ) ); + } + + @Test + public void testMRJobHistoryUIJavaScriptText() throws IOException, ParserConfigurationException { + Map<String, Map<String, String>> rules = new HashMap<>(); + Map<String, String> map = new HashMap<>(); + map.put( "https?://[^/':,]+:[\\d]+", "https://knoxhost:8443/gateway/nodemanagerui/node?host=knoxhost" ); + rules.put( "test-rule", map ); + String inputXml = + "<root>\n" + + " <script type=\"text/javascript\">\n" + + " var appsTableData=[\n" + + " [\"<a href='http://testhost:8042'>/default-rack/node</a>\",\"<a href='http://testhost:8042'>testhost:8042</a>\"],\n" + + " ]\n" + + " </script>\n" + + "</root>\n"; + StringReader inputReader = new StringReader( inputXml ); + UrlRewriteFilterContentDescriptor config = new UrlRewriteFilterContentDescriptorImpl(); + config.addApply("https?://[^/':,]+:[\\d]+", "test-rule"); + HtmlFilterReaderBase filterReader = new MatchRuleXmlFilterReader( inputReader, rules, config ); + String outputXml = new String( IOUtils.toCharArray( filterReader ) ); + String expectedOutput = + "<root>\n" + + " <script type=\"text/javascript\">\n" + + " var appsTableData=[\n" + + " [\"<a href='https://knoxhost:8443/gateway/nodemanagerui/node?host=knoxhost'>/default-rack/node</a>\",\"<a href='https://knoxhost:8443/gateway/nodemanagerui/node?host=knoxhost'>testhost:8042</a>\"],\n" + + " ]\n" + + " </script>\n" + + "</root>\n"; + assertThat( outputXml, is( expectedOutput ) ); + } + + public static class XmlRewriteRulesDescriptorDigesterTest { + + private static DigesterLoader loader = DigesterLoader.newLoader( new XmlRewriteRulesDigester() ); + private static Digester digester = loader.newDigester( new ExtendedBaseRules() ); + + @Before + public void setupTest() { + digester.setValidating( false ); + } + + @Test + public void testRuleParsing() throws IOException, SAXException { + Reader reader = new StringReader( "<rules/>" ); + UrlRewriteRulesDescriptor config = digester.parse( reader ); + assertThat( config.getRules().isEmpty(), is( true ) ); + + reader = new StringReader( "<rules><rule></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config.getRules().size(), is( 1 ) ); + UrlRewriteRuleDescriptor rule = config.getRules().get( 0 ); + assertThat( rule, notNullValue() ); + assertThat( rule.name(), nullValue() ); + assertThat( rule.pattern(), nullValue() ); + assertThat( rule.directions(), nullValue() ); + assertThat( rule.flow(), nullValue() ); + + reader = new StringReader( "<rules><rule name=\"test-name\"></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config.getRules().size(), is( 1 ) ); + rule = config.getRules().get( 0 ); + assertThat( rule, notNullValue() ); + assertThat( rule.name(), is( "test-name" ) ); + assertThat( rule.pattern(), nullValue() ); + assertThat( rule.directions(), nullValue() ); + assertThat( rule.flow(), nullValue() ); + + reader = new StringReader( "<rules><rule pattern=\"test-pattern\"></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config.getRules().size(), is( 1 ) ); + rule = config.getRules().get( 0 ); + assertThat( rule, notNullValue() ); + assertThat( rule.name(), nullValue() ); + assertThat( rule.pattern(), is( "test-pattern" ) ); + assertThat( rule.directions(), nullValue() ); + assertThat( rule.flow(), nullValue() ); + + reader = new StringReader( "<rules><rule dir=\"request\"></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config.getRules().size(), is( 1 ) ); + rule = config.getRules().get( 0 ); + assertThat( rule, notNullValue() ); + assertThat( rule.name(), nullValue() ); + assertThat( rule.pattern(), nullValue() ); + assertThat( rule.directions().size(), is( 1 ) ); + assertThat( rule.directions(), Matchers.contains( UrlRewriter.Direction.IN ) ); + assertThat( rule.flow(), nullValue() ); + + reader = new StringReader( "<rules><rule flow=\"all\"></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config.getRules().size(), is( 1 ) ); + rule = config.getRules().get( 0 ); + assertThat( rule, notNullValue() ); + assertThat( rule.name(), nullValue() ); + assertThat( rule.pattern(), nullValue() ); + assertThat( rule.directions(), nullValue() ); + assertThat( rule.flow(), Matchers.is( UrlRewriteStepFlow.ALL ) ); + } + + @Test + public void testDirectionParsing() throws IOException, SAXException { + Reader reader; + UrlRewriteRulesDescriptor config; + + reader = new StringReader( "<rules><rule dir=\"request\"></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config.getRules().get( 0 ).directions(), contains( UrlRewriter.Direction.IN ) ); + + reader = new StringReader( "<rules><rule dir=\"Request\"></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config.getRules().get( 0 ).directions(), contains( UrlRewriter.Direction.IN ) ); + + reader = new StringReader( "<rules><rule dir=\"in\"></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config.getRules().get( 0 ).directions(), contains( UrlRewriter.Direction.IN ) ); + + reader = new StringReader( "<rules><rule dir=\"req\"></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config.getRules().get( 0 ).directions(), contains( UrlRewriter.Direction.IN ) ); + + reader = new StringReader( "<rules><rule dir=\"Req\"></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config.getRules().get( 0 ).directions(), contains( UrlRewriter.Direction.IN ) ); + + reader = new StringReader( "<rules><rule dir=\"REQ\"></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config.getRules().get( 0 ).directions(), contains( UrlRewriter.Direction.IN ) ); + + reader = new StringReader( "<rules><rule dir=\"inbound\"></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config.getRules().get( 0 ).directions(), contains( UrlRewriter.Direction.IN ) ); + + reader = new StringReader( "<rules><rule dir=\"Inbound\"></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config.getRules().get( 0 ).directions(), contains( UrlRewriter.Direction.IN ) ); + + reader = new StringReader( "<rules><rule dir=\"INBOUND\"></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config.getRules().get( 0 ).directions(), contains( UrlRewriter.Direction.IN ) ); + + reader = new StringReader( "<rules><rule dir=\"in\"></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config.getRules().get( 0 ).directions(), contains( UrlRewriter.Direction.IN ) ); + + reader = new StringReader( "<rules><rule dir=\"In\"></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config.getRules().get( 0 ).directions(), contains( UrlRewriter.Direction.IN ) ); + + reader = new StringReader( "<rules><rule dir=\"IN\"></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config.getRules().get( 0 ).directions(), contains( UrlRewriter.Direction.IN ) ); + + reader = new StringReader( "<rules><rule dir=\"i\"></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config.getRules().get( 0 ).directions(), contains( UrlRewriter.Direction.IN ) ); + + reader = new StringReader( "<rules><rule dir=\"I\"></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config.getRules().get( 0 ).directions(), contains( UrlRewriter.Direction.IN ) ); + + + reader = new StringReader( "<rules><rule dir=\"response\"></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config.getRules().get( 0 ).directions(), contains( UrlRewriter.Direction.OUT ) ); + + reader = new StringReader( "<rules><rule dir=\"Response\"></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config.getRules().get( 0 ).directions(), contains( UrlRewriter.Direction.OUT ) ); + + reader = new StringReader( "<rules><rule dir=\"out\"></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config.getRules().get( 0 ).directions(), contains( UrlRewriter.Direction.OUT ) ); + + reader = new StringReader( "<rules><rule dir=\"res\"></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config.getRules().get( 0 ).directions(), contains( UrlRewriter.Direction.OUT ) ); + + reader = new StringReader( "<rules><rule dir=\"Res\"></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config.getRules().get( 0 ).directions(), contains( UrlRewriter.Direction.OUT ) ); + + reader = new StringReader( "<rules><rule dir=\"RES\"></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config.getRules().get( 0 ).directions(), contains( UrlRewriter.Direction.OUT ) ); + + reader = new StringReader( "<rules><rule dir=\"outbound\"></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config.getRules().get( 0 ).directions(), contains( UrlRewriter.Direction.OUT ) ); + + reader = new StringReader( "<rules><rule dir=\"Outbound\"></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config.getRules().get( 0 ).directions(), contains( UrlRewriter.Direction.OUT ) ); + + reader = new StringReader( "<rules><rule dir=\"OUTBOUND\"></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config.getRules().get( 0 ).directions(), contains( UrlRewriter.Direction.OUT ) ); + + reader = new StringReader( "<rules><rule dir=\"out\"></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config.getRules().get( 0 ).directions(), contains( UrlRewriter.Direction.OUT ) ); + + reader = new StringReader( "<rules><rule dir=\"Out\"></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config.getRules().get( 0 ).directions(), contains( UrlRewriter.Direction.OUT ) ); + + reader = new StringReader( "<rules><rule dir=\"OUT\"></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config.getRules().get( 0 ).directions(), contains( UrlRewriter.Direction.OUT ) ); + + reader = new StringReader( "<rules><rule dir=\"o\"></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config.getRules().get( 0 ).directions(), contains( UrlRewriter.Direction.OUT ) ); + + reader = new StringReader( "<rules><rule dir=\"O\"></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config.getRules().get( 0 ).directions(), contains( UrlRewriter.Direction.OUT ) ); + + + reader = new StringReader( "<rules><rule dir=\"request,response\"></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config.getRules().get( 0 ).directions(), hasItem( UrlRewriter.Direction.IN ) ); + assertThat( config.getRules().get( 0 ).directions(), hasItem( UrlRewriter.Direction.OUT ) ); + } + + @Test + public void testFlowParsing() throws IOException, SAXException { + Reader reader; + UrlRewriteRulesDescriptor config; + + reader = new StringReader( "<rules><rule dir=\"request\"></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config.getRules().get( 0 ).directions(), contains( UrlRewriter.Direction.IN ) ); + } + + @Test + public void testMatchParsing() throws IOException, SAXException { + Reader reader; + UrlRewriteRulesDescriptor config; + UrlRewriteRuleDescriptor rule; + UrlRewriteMatchDescriptorExt match; + List<? extends UrlRewriteStepDescriptor> steps; + + reader = new StringReader( "<rules><rule><match></match></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config, notNullValue() ); + assertThat( config.getRules(), notNullValue() ); + assertThat( config.getRules().size(), is( 1 ) ); + rule = config.getRules().get( 0 ); + assertThat( rule.steps(), notNullValue() ); + assertThat( rule.steps().size(), is( 1 ) ); + match = (UrlRewriteMatchDescriptorExt)rule.steps().get( 0 ); + assertThat( match, notNullValue() ); + //assertThat( match.type(), nullValue() ); + assertThat( match.operation(), nullValue() ); + assertThat( match.pattern(), nullValue() ); + + reader = new StringReader( "<rules><rule><match type=\"test-type\" op=\"test-op\" pattern=\"test-pattern\"></match></rule></rules>" ); + config = digester.parse( reader ); + match = (UrlRewriteMatchDescriptorExt)config.getRules().get( 0 ).steps().get( 0 ); + //assertThat( match.type(), is("test-type") ); + assertThat( match.operation(), is( "test-op" ) ); + assertThat( match.pattern(), is( "test-pattern" ) ); + + reader = new StringReader( "<rules><rule name=\"test\"><match><match pattern=\"test-pattern\"></match></match></rule></rules>" ); + config = digester.parse( reader ); + steps = ((UrlRewriteMatchDescriptor)config.getRule( "test" ).steps().get( 0 )).steps(); + assertThat( steps, notNullValue() ); + assertThat( steps.size(), is( 1 ) ); + assertThat( steps.get( 0 ), notNullValue() ); + match = (UrlRewriteMatchDescriptorExt)steps.get( 0 ); + assertThat( match.pattern(), is( "test-pattern" ) ); + } + + @Test + public void testCheckParsing() throws IOException, SAXException { + Reader reader; + UrlRewriteRulesDescriptor config; + UrlRewriteRuleDescriptor rule; + List<UrlRewriteStepDescriptor> steps; + UrlRewriteCheckDescriptorExt step; + + reader = new StringReader( "<rules><rule><check></check></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config, notNullValue() ); + assertThat( config.getRules(), notNullValue() ); + assertThat( config.getRules().size(), is( 1 ) ); + rule = config.getRules().get( 0 ); + assertThat( rule.steps(), notNullValue() ); + assertThat( rule.steps().size(), is( 1 ) ); + step = (UrlRewriteCheckDescriptorExt)rule.steps().get( 0 ); + assertThat( step, notNullValue() ); + //assertThat( step.type(), nullValue() ); + assertThat( step.operation(), nullValue() ); + assertThat( step.input(), nullValue() ); + assertThat( step.value(), nullValue() ); + + reader = new StringReader( "<rules><rule><check type=\"test-type\" op=\"test-op\" input=\"test-input\" value=\"test-value\"></check></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config, notNullValue() ); + assertThat( config.getRules(), notNullValue() ); + assertThat( config.getRules().size(), is( 1 ) ); + rule = config.getRules().get( 0 ); + assertThat( rule.steps(), notNullValue() ); + assertThat( rule.steps().size(), is( 1 ) ); + step = (UrlRewriteCheckDescriptorExt)rule.steps().get( 0 ); + assertThat( step, notNullValue() ); + //assertThat( step.type(), is( "test-type" ) ); + assertThat( step.operation(), is( "test-op" ) ); + assertThat( step.input(), is( "test-input" ) ); + assertThat( step.value(), is( "test-value" ) ); + } + + @Test + public void testActionParsing() throws IOException, SAXException { + Reader reader; + UrlRewriteRulesDescriptor config; + UrlRewriteRuleDescriptor rule; + UrlRewriteActionDescriptorBase step; + + reader = new StringReader( "<rules><rule><action></action></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config, notNullValue() ); + assertThat( config.getRules(), notNullValue() ); + assertThat( config.getRules().size(), is( 1 ) ); + rule = config.getRules().get( 0 ); + assertThat( rule.steps(), notNullValue() ); + assertThat( rule.steps().size(), is( 1 ) ); + step = (UrlRewriteActionDescriptorBase)rule.steps().get( 0 ); + assertThat( step, notNullValue() ); + //assertThat( step.type(), nullValue() ); + assertThat( step.parameter(), nullValue() ); + + reader = new StringReader( "<rules><rule><action type=\"test-type\" param=\"test-param\"></action></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config, notNullValue() ); + assertThat( config.getRules(), notNullValue() ); + assertThat( config.getRules().size(), is( 1 ) ); + rule = config.getRules().get( 0 ); + assertThat( rule.steps(), notNullValue() ); + assertThat( rule.steps().size(), is( 1 ) ); + step = (UrlRewriteActionDescriptorBase)rule.steps().get( 0 ); + assertThat( step, notNullValue() ); + //assertThat( step.type(), is( "test-type" ) ); + assertThat( step.parameter(), is( "test-param" ) ); + } + + @Test + public void testControlParsing() throws IOException, SAXException { + Reader reader; + UrlRewriteRulesDescriptor config; + UrlRewriteRuleDescriptor rule; + List<UrlRewriteStepDescriptor> steps; + + reader = new StringReader( "<rules><rule><control></control></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config, notNullValue() ); + assertThat( config.getRules(), notNullValue() ); + assertThat( config.getRules().size(), is( 1 ) ); + rule = config.getRules().get( 0 ); + assertThat( rule.steps(), notNullValue() ); + assertThat( rule.steps().size(), is( 1 ) ); + UrlRewriteControlDescriptor step = (UrlRewriteControlDescriptor)rule.steps().get( 0 ); + assertThat( step, notNullValue() ); + assertThat( step.flow(), nullValue() ); + + reader = new StringReader( "<rules><rule><control flow=\"or\"></control></rule></rules>" ); + config = digester.parse( reader ); + assertThat( config, notNullValue() ); + assertThat( config.getRules(), notNullValue() ); + assertThat( config.getRules().size(), is( 1 ) ); + rule = config.getRules().get( 0 ); + assertThat( rule.steps(), notNullValue() ); + assertThat( rule.steps().size(), is( 1 ) ); + step = (UrlRewriteControlDescriptor)rule.steps().get( 0 ); + assertThat( step, notNullValue() ); + assertThat( step.flow(), is( UrlRewriteStepFlow.OR ) ); + } + } + + @Test + public void testTagNameLetterCase() throws Exception { + String inputXml = "<Root/>"; + StringReader inputReader = new StringReader( inputXml ); + + HtmlFilterReaderBase filterReader = new NoopXmlFilterReader( inputReader ); + String outputXml = new String( IOUtils.toCharArray( filterReader ) ); + assertThat( the( outputXml ), hasXPath( "/Root" ) ); + } + + @Test + public void testXmlWithHtmlTagNames() throws Exception { + String inputXml = "<root><br><table name=\"table1\"></table><table name=\"table2\"></table></br></root>"; + StringReader inputReader = new StringReader( inputXml ); + + HtmlFilterReaderBase filterReader = new NoopXmlFilterReader( inputReader ); + String outputXml = new String( IOUtils.toCharArray( filterReader ) ); + assertThat( the( outputXml ), hasXPath( "/root/br/table[1]/@name", equalTo( "table1" ) ) ); + assertThat( the( outputXml ), hasXPath( "/root/br/table[2]/@name", equalTo( "table2" ) ) ); + } + + private class TestXmlFilterReader extends HtmlFilterReaderBase { + + protected TestXmlFilterReader( Reader reader, UrlRewriteFilterContentDescriptor contentConfig ) throws IOException, ParserConfigurationException { + super( reader ); + } + + @Override + protected String filterAttribute( QName elementName, QName attributeName, String attributeValue, String ruleName ) { + return "attr:" + ruleName + "{" + attributeValue + "}"; + } + + @Override + protected String filterText( QName elementName, String text, String ruleName ) { + return "text:" + ruleName + "{" + text + "}"; + } + + @Override + public String filterValueString( String name, String value, String ruleName ) { + return value; + } + } + +} http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/html/HtmlImportFunctionProcessorTest.java ---------------------------------------------------------------------- diff --git a/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/html/HtmlImportFunctionProcessorTest.java b/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/html/HtmlImportFunctionProcessorTest.java new file mode 100644 index 0000000..e49581b --- /dev/null +++ b/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/html/HtmlImportFunctionProcessorTest.java @@ -0,0 +1,52 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p> + * 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 org.apache.knox.gateway.filter.rewrite.impl.html; + +import org.apache.knox.gateway.filter.rewrite.spi.UrlRewriteFunctionProcessor; +import org.junit.Test; + +import java.util.Iterator; +import java.util.ServiceLoader; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.fail; + +public class HtmlImportFunctionProcessorTest { + + @SuppressWarnings("rawtypes") + @Test + public void testServiceLoader() throws Exception { + ServiceLoader loader = ServiceLoader.load( UrlRewriteFunctionProcessor.class ); + Iterator iterator = loader.iterator(); + assertThat( "Service iterator empty.", iterator.hasNext() ); + while( iterator.hasNext() ) { + Object object = iterator.next(); + if( object instanceof HtmlImportFunctionProcessor ) { + return; + } + } + fail( "Failed to find " + HtmlImportFunctionProcessor.class.getName() + " via service loader." ); + } + + @Test + public void testName() throws Exception { + HtmlImportFunctionProcessor processor = new HtmlImportFunctionProcessor(); + assertThat( processor.name(), is( "import" ) ); + } +} http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/html/HtmlPrefixProcessorTest.java ---------------------------------------------------------------------- diff --git a/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/html/HtmlPrefixProcessorTest.java b/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/html/HtmlPrefixProcessorTest.java new file mode 100644 index 0000000..8098719 --- /dev/null +++ b/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/html/HtmlPrefixProcessorTest.java @@ -0,0 +1,57 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with this + * work for additional information regarding copyright ownership. The ASF + * licenses this file to you 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 + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p> + * 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 org.apache.knox.gateway.filter.rewrite.impl.html; + +import org.apache.knox.gateway.filter.rewrite.spi.UrlRewriteFunctionProcessor; +import org.junit.Test; + +import java.util.Iterator; +import java.util.ServiceLoader; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.fail; + +public class HtmlPrefixProcessorTest { + + public HtmlPrefixProcessorTest() { + super(); + } + + @SuppressWarnings("rawtypes") + @Test + public void testServiceLoader() throws Exception { + ServiceLoader loader = ServiceLoader.load( UrlRewriteFunctionProcessor.class ); + Iterator iterator = loader.iterator(); + assertThat( "Service iterator empty.", iterator.hasNext() ); + while( iterator.hasNext() ) { + Object object = iterator.next(); + if( object instanceof HtmlPrefixProcessor) { + return; + } + } + fail( "Failed to find " + HtmlPrefixProcessor.class.getName() + " via service loader." ); + } + + @Test + public void testName() throws Exception { + HtmlPrefixProcessor processor = new HtmlPrefixProcessor(); + assertThat( processor.name(), is( "prefix" ) ); + } + + +} http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/javascript/JavaScriptFilterReaderTest.java ---------------------------------------------------------------------- diff --git a/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/javascript/JavaScriptFilterReaderTest.java b/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/javascript/JavaScriptFilterReaderTest.java new file mode 100644 index 0000000..1cca640 --- /dev/null +++ b/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/javascript/JavaScriptFilterReaderTest.java @@ -0,0 +1,118 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.apache.knox.gateway.filter.rewrite.impl.javascript; + +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Pattern; + +import org.apache.commons.io.IOUtils; +import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFilterContentDescriptor; +import org.apache.knox.gateway.filter.rewrite.impl.UrlRewriteFilterContentDescriptorImpl; + +import org.junit.Test; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +public class JavaScriptFilterReaderTest { + public static class NoopJsFilterReader extends JavaScriptFilterReader { + public NoopJsFilterReader( Reader reader, UrlRewriteFilterContentDescriptor config ) throws IOException { + super( reader, config ); + } + + @Override + public String filterValueString( String name, String value, String ruleName ) { + return value; + } + } + + public static class MatchRuleJsFilterReader extends JavaScriptFilterReader { + private Map<String, Map<String,String>> rules; + public MatchRuleJsFilterReader( Reader reader, Map<String, Map<String,String>> rules, UrlRewriteFilterContentDescriptor config ) throws IOException { + super( reader, config ); + this.rules = rules; + } + + @Override + public String filterValueString( String name, String value, String ruleName ) { + Map<String, String> rule = rules.get( ruleName ); + if ( rule == null ) { + return value; + } + for ( Map.Entry<String, String> entry : rule.entrySet() ) { + if ( Pattern.compile( entry.getKey() ).matcher( value ).matches() ) { + return entry.getValue(); + } + } + return value; + } + } + + @Test + public void testSimple() throws IOException { + String inputJs = "function load_page() {}\n"; + StringReader inputReader = new StringReader( inputJs ); + UrlRewriteFilterContentDescriptor config = new UrlRewriteFilterContentDescriptorImpl(); + JavaScriptFilterReader filterReader = new NoopJsFilterReader( inputReader, config ); + String outputJs = new String( IOUtils.toCharArray( filterReader ) ); + assertThat( outputJs, is ( inputJs ) ); + } + + @Test + public void testSimpleMultipleLines() throws IOException { + String inputJs = + "var url = '/webhdfs/v1' + abs_path + '?op=GET_BLOCK_LOCATIONS';\n" + + "$.ajax({\"url\": url, \"crossDomain\": true}).done(function(data) {}).error(network_error_handler(url));\n"; + StringReader inputReader = new StringReader( inputJs ); + UrlRewriteFilterContentDescriptor config = new UrlRewriteFilterContentDescriptorImpl(); + config.addApply( "/webhdfs/v1", "test-rule" ); + JavaScriptFilterReader filterReader = new NoopJsFilterReader( inputReader, config ); + String outputJs = new String( IOUtils.toCharArray( filterReader ) ); + assertThat( outputJs, is ( inputJs ) ); + } + + @Test + public void testMatchedJsContent() throws IOException { + Map<String, Map<String, String>> rules = new HashMap<>(); + Map<String, String> map = new HashMap<>(); + map.put( "(https?://[^/':,]+:[\\d]+)?/cluster/app", "https://knoxhost:8443/cluster/app" ); + map.put( "/webhdfs/v1", "https://knoxhost:8443/webhdfs/v1" ); + rules.put( "test-rule", map ); + String inputJs = + "var url = '/webhdfs/v1' + abs_path + '?op=GET_BLOCK_LOCATIONS';\n" + + "$.ajax({\"url\": url, \"crossDomain\": true}).done(function(data) {\n" + + " var url = http://testhost:8088/cluster/app/application_1436831599487_0001;\n" + + "}).error(network_error_handler(url));\n"; + StringReader inputReader = new StringReader( inputJs ); + UrlRewriteFilterContentDescriptor config = new UrlRewriteFilterContentDescriptorImpl(); + config.addApply( "(https?://[^/':,]+:[\\d]+)?/cluster/app", "test-rule" ); + config.addApply( "/webhdfs/v1", "test-rule" ); + JavaScriptFilterReader filterReader = new MatchRuleJsFilterReader( inputReader, rules, config ); + String outputJs = new String( IOUtils.toCharArray( filterReader ) ); + String expectedOutputJs = + "var url = 'https://knoxhost:8443/webhdfs/v1' + abs_path + '?op=GET_BLOCK_LOCATIONS';\n" + + "$.ajax({\"url\": url, \"crossDomain\": true}).done(function(data) {\n" + + " var url = https://knoxhost:8443/cluster/app/application_1436831599487_0001;\n" + + "}).error(network_error_handler(url));\n"; + assertThat( outputJs, is ( expectedOutputJs ) ); + } +} http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/json/JsonFilterReaderTest.java ---------------------------------------------------------------------- diff --git a/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/json/JsonFilterReaderTest.java b/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/json/JsonFilterReaderTest.java new file mode 100644 index 0000000..1378fef --- /dev/null +++ b/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/json/JsonFilterReaderTest.java @@ -0,0 +1,363 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.apache.knox.gateway.filter.rewrite.impl.json; + +import com.jayway.jsonassert.JsonAssert; +import org.apache.commons.io.IOUtils; +import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFilterApplyDescriptor; +import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFilterBufferDescriptor; +import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFilterContentDescriptor; +import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFilterDescriptor; +import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFilterDetectDescriptor; +import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteRulesDescriptor; +import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteRulesDescriptorFactory; +import org.apache.hadoop.test.TestUtils; +import org.junit.Test; + +import java.io.IOException; +import java.io.InputStream; +import java.io.StringReader; +import java.nio.charset.Charset; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.containsString; +import static org.junit.Assert.fail; + +public class JsonFilterReaderTest { + + @Test + public void testValueNumberWithBuffering() throws Exception { + String input = "{ \"apps\" : {\"app\":[{\"id\":\"one\", \"progress\":100.0, \"startedTime\":1399975176760}]} }"; + + UrlRewriteRulesDescriptor rulesConfig = UrlRewriteRulesDescriptorFactory.create(); + UrlRewriteFilterDescriptor filterConfig = rulesConfig.addFilter( "filter-1" ); + UrlRewriteFilterContentDescriptor contentConfig = filterConfig.addContent( "text/json" ); + UrlRewriteFilterBufferDescriptor bufferConfig = contentConfig.addBuffer( "$.apps.app[*]" ); + UrlRewriteFilterApplyDescriptor applyConfig = bufferConfig.addApply( "$.id", "test-rule" ); + + JsonFilterReader filter = new JsonFilterReader( new StringReader( input ), contentConfig ); + String output = IOUtils.toString( filter ); + assertThat( output, containsString( "\"startedTime\":1399975176760}" ) ); + } + + + @Test + public void testSimple() throws IOException { + String inputJson = "{ \"test-name\" : \"test-value\" }"; + StringReader inputReader = new StringReader( inputJson ); + JsonFilterReader filterReader = new TestJsonFilterReader( inputReader, null ); + String outputJson = new String( IOUtils.toCharArray( filterReader ) ); + //System.out.println( "JSON=" + outputJson ); + + JsonAssert.with( outputJson ).assertThat( "name<test-name>", is( "value:null<test-value>" ) ); + } + + @Test + public void testRootArray() throws Exception { + String inputJson = "[\"test-value-1\",\"test-value-2\",\"test-value-3\"]"; + StringReader inputReader = new StringReader( inputJson ); + JsonFilterReader filterReader = new TestJsonFilterReader( inputReader, null ); + String outputJson = new String( IOUtils.toCharArray( filterReader ) ); + //System.out.println( "JSON=" + outputJson ); + JsonAssert.with( outputJson ).assertThat( "$.[0]", is( "value:null<test-value-1>" ) ); + JsonAssert.with( outputJson ).assertThat( "$.[1]", is( "value:null<test-value-2>" ) ); + JsonAssert.with( outputJson ).assertThat( "$.[2]", is( "value:null<test-value-3>" ) ); + + inputJson = "[777,42]"; + inputReader = new StringReader( inputJson ); + filterReader = new TestJsonFilterReader( inputReader, null ); + outputJson = new String( IOUtils.toCharArray( filterReader ) ); + //System.out.println( "JSON=" + outputJson ); + JsonAssert.with( outputJson ).assertThat( "$.[0]", is( 777 ) ); + JsonAssert.with( outputJson ).assertThat( "$.[1]", is( 42 ) ); + } + + @Test + public void testEmptyObject() throws IOException { + String inputJson = "{}"; + StringReader inputReader = new StringReader( inputJson ); + JsonFilterReader filterReader = new TestJsonFilterReader( inputReader, null ); + String outputJson = new String( IOUtils.toCharArray( filterReader ) ); + + assertThat( outputJson, is( "{}" ) ); + } + + @Test + public void testEmptyArray() throws IOException { + String inputJson = "[]"; + StringReader inputReader = new StringReader( inputJson ); + JsonFilterReader filterReader = new TestJsonFilterReader( inputReader, null ); + String outputJson = new String( IOUtils.toCharArray( filterReader ) ); + + assertThat( outputJson, is( "[]" ) ); + } + + @Test + public void testUnscopedStreaming() throws IOException { + InputStream stream = TestUtils.getResourceStream( this.getClass(), "simple-values.json" ); + String input = IOUtils.toString( stream, Charset.forName( "UTF-8" ) ); + + //System.out.println( "INPUT=" + input ); + + UrlRewriteRulesDescriptor rulesConfig = UrlRewriteRulesDescriptorFactory.create(); + UrlRewriteFilterDescriptor filterConfig = rulesConfig.addFilter( "filter=1" ); + UrlRewriteFilterContentDescriptor contentConfig = filterConfig.addContent( "text/json" ); + UrlRewriteFilterApplyDescriptor applyConfig = contentConfig.addApply( "$['test-str']", "test-rule" ); + + JsonFilterReader filter = new TestJsonFilterReader( new StringReader( input ), contentConfig ); + String output = IOUtils.toString( filter ); + + //System.out.println( "OUTPUT=" + output ); + + JsonAssert.with( output ).assertThat( "name<test-str>", is( "value:null<text>" ) ); + } + + @Test + public void testNamesWithDots() throws IOException { + InputStream stream = TestUtils.getResourceStream( this.getClass(), "dotted-field-name.json" ); + String input = IOUtils.toString( stream, Charset.forName( "UTF-8" ) ); + + //System.out.println( "INPUT=" + input ); + + UrlRewriteRulesDescriptor rulesConfig = UrlRewriteRulesDescriptorFactory.create(); + UrlRewriteFilterDescriptor filterConfig = rulesConfig.addFilter( "test-filter" ); + UrlRewriteFilterContentDescriptor contentConfig = filterConfig.addContent( "application/json" ); + //NOTE: The field names are rewritten first so the values rules need to match the rewritten name. + contentConfig.addApply( "$.name<testField>", "test-rule" ); + contentConfig.addApply( "$.name<test_field>", "test-rule" ); + contentConfig.addApply( "$.name<test-field>", "test-rule" ); + contentConfig.addApply( "$['name<test.field>']", "test-rule" ); + + JsonFilterReader filter = new TestJsonFilterReader( new StringReader( input ), contentConfig ); + String output = IOUtils.toString( filter ); + + //System.out.println( "OUTPUT=" + output ); + + JsonAssert.with( output ).assertThat( "$['name<testField>']", is( "value:test-rule<testField value>" ) ); + JsonAssert.with( output ).assertThat( "$['name<test_field>']", is( "value:test-rule<test_field value>" ) ); + JsonAssert.with( output ).assertThat( "$['name<test-field>']", is( "value:test-rule<test-field value>" ) ); + JsonAssert.with( output ).assertThat( "$['name<test.field>']", is( "value:test-rule<test.field value>" ) ); + } + +// @Test +// public void testJsonPathObject() throws IOException { +// InputStream stream = TestUtils.getResourceStream( this.getClass(), "complex.json" ); +// String input = IOUtils.toString( stream, Charset.forName( "UTF-8" ) ); +// +// Object o; +// +// o = JsonPath.read( "$", input, JsonNode.class ); +// assertThat( o, instanceOf( ObjectNode.class ) ); +// assertThat( o.toString(), startsWith( "{" ) ); +// System.out.println( o.getClass() + "=" + o ); +// +// o = JsonPath.read( "$['test-str']", input, JsonNode.class ); +// System.out.println( o.getClass() + "=" + o ); +// +// o = JsonPath.read( "$['test-obj-multi']", input, JsonNode.class ); +// System.out.println( o.getClass() + "=" + o ); +// +// o = JsonPath.read( "$['val']", (JsonNode)o, JsonNode.class ); +// System.out.println( o.getClass() + "=" + o ); +// +// JsonPath p = JsonPath.compile( "$['test-obj-multi']['val']" ); +// o = JsonPath.read( "$['test-obj-multi']['val']", input, JsonNode.class ); +// JsonNode pp = ((JsonNode)o).findParent("val"); +// System.out.println( "$['test-obj-multi']['val']=" + o.getClass() + "=" + o ); +// +// } +// +// @Test +// public void testJsonPathArray() throws IOException { +// InputStream stream = TestUtils.getResourceStream( this.getClass(), "array.json" ); +// String input = IOUtils.toString( stream, Charset.forName( "UTF-8" ) ); +// +// Object o; +// +// o = JsonPath.read( "$", input, JsonNode.class ); +// System.out.println( o.getClass() + "=" + o ); +// +// o = JsonPath.read( "$[0]", input, JsonNode.class ); +// System.out.println( o.getClass() + "=" + o ); +// +// o = JsonPath.read( "$[*]", input, JsonNode.class ); +// System.out.println( "$[*]=" + o.getClass() + "=" + o ); +// +// o = JsonPath.read( "$['obj1-fld1']", (JsonNode)o, JsonNode.class ); +// System.out.println( o.getClass() + "=" + o ); +// +// o = JsonPath.read( "$[0]['obj1-fld1']", input, JsonNode.class ); +// System.out.println( o.getClass() + "=" + o ); +// +// } + + @Test + public void testBuffered() throws IOException { + InputStream stream = TestUtils.getResourceStream( this.getClass(), "simple-values.json" ); + String input = IOUtils.toString( stream, Charset.forName( "UTF-8" ) ); + + //System.out.println( "INPUT=" + input ); + + UrlRewriteRulesDescriptor rulesConfig = UrlRewriteRulesDescriptorFactory.create(); + UrlRewriteFilterDescriptor filterConfig = rulesConfig.addFilter( "filter-1" ); + UrlRewriteFilterContentDescriptor contentConfig = filterConfig.addContent( "text/json" ); + UrlRewriteFilterBufferDescriptor bufferConfig = contentConfig.addBuffer( "$" ); + UrlRewriteFilterApplyDescriptor applyConfig = bufferConfig.addApply( "$['name<test-str>']", "test-rule" ); + //UrlRewriteRulesDescriptorFactory.store( rulesConfig, "xml", new PrintWriter( System.out ) ); + + JsonFilterReader filter = new TestJsonFilterReader( new StringReader( input ), contentConfig ); + String output = IOUtils.toString( filter ); + + //System.out.println( "OUTPUT=" + output ); + + JsonAssert.with( output ).assertThat( "name<test-str>", is( "value:test-rule<text>" ) ); + } + + @Test + public void testBufferedDetectApply() throws IOException { + InputStream stream = TestUtils.getResourceStream( this.getClass(), "properties.json" ); + String input = IOUtils.toString( stream, Charset.forName( "UTF-8" ) ); + + //System.out.println( "INPUT=" + input ); + + UrlRewriteRulesDescriptor rulesConfig = UrlRewriteRulesDescriptorFactory.create(); + UrlRewriteFilterDescriptor filterConfig = rulesConfig.addFilter( "filter-1" ); + UrlRewriteFilterContentDescriptor contentConfig = filterConfig.addContent( "text/json" ); + UrlRewriteFilterBufferDescriptor bufferConfig = contentConfig.addBuffer( "$.name<properties>.*.name<property>" ); + UrlRewriteFilterDetectDescriptor detectConfig = bufferConfig.addDetect( "$.name<property-name>", "test-name-2" ); + UrlRewriteFilterApplyDescriptor applyConfig = detectConfig.addApply( "$.name<property-value>", "test-rule-2" ); + + //UrlRewriteRulesDescriptorFactory.store( rulesConfig, "xml", new PrintWriter( System.out ) ); + + JsonFilterReader filter = new TestJsonFilterReader( new StringReader( input ), contentConfig ); + String output = IOUtils.toString( filter ); + + //System.out.println( "OUTPUT=" + output ); + + JsonAssert.with( output ).assertThat( "name<properties>[0].name<property>.name<property-name>", is( "test-name-1" ) ); + JsonAssert.with( output ).assertThat( "name<properties>[0].name<property>.name<property-value>", is( "test-value-1" ) ); + JsonAssert.with( output ).assertThat( "name<properties>[1].name<property>.name<property-name>", is( "test-name-2" ) ); + JsonAssert.with( output ).assertThat( "name<properties>[1].name<property>.name<property-value>", is( "value:test-rule-2<test-value-2>" ) ); + JsonAssert.with( output ).assertThat( "name<properties>[2].name<property>.name<property-name>", is( "test-name-3" ) ); + JsonAssert.with( output ).assertThat( "name<properties>[2].name<property>.name<property-value>", is( "test-value-3" ) ); + } + + @Test + public void testBufferedApply() throws IOException { + InputStream stream = TestUtils.getResourceStream( this.getClass(), "properties.json" ); + String input = IOUtils.toString( stream, Charset.forName( "UTF-8" ) ); + + //System.out.println( "INPUT=" + input ); + + UrlRewriteRulesDescriptor rulesConfig = UrlRewriteRulesDescriptorFactory.create(); + UrlRewriteFilterDescriptor filterConfig = rulesConfig.addFilter( "filter-1" ); + UrlRewriteFilterContentDescriptor contentConfig = filterConfig.addContent( "text/json" ); + UrlRewriteFilterBufferDescriptor bufferConfig = contentConfig.addBuffer( "$.name<properties>.*.name<property>" ); + UrlRewriteFilterApplyDescriptor applyConfig = bufferConfig.addApply( "$.name<property-value>", "test-rule" ); + + //UrlRewriteRulesDescriptorFactory.store( rulesConfig, "xml", new PrintWriter( System.out ) ); + + JsonFilterReader filter = new TestJsonFilterReader( new StringReader( input ), contentConfig ); + String output = IOUtils.toString( filter ); + + //System.out.println( "OUTPUT=" + output ); + + JsonAssert.with( output ).assertThat( "name<properties>[0].name<property>.name<property-name>", is( "test-name-1" ) ); + JsonAssert.with( output ).assertThat( "name<properties>[0].name<property>.name<property-value>", is( "value:test-rule<test-value-1>" ) ); + JsonAssert.with( output ).assertThat( "name<properties>[1].name<property>.name<property-name>", is( "test-name-2" ) ); + JsonAssert.with( output ).assertThat( "name<properties>[1].name<property>.name<property-value>", is( "value:test-rule<test-value-2>" ) ); + JsonAssert.with( output ).assertThat( "name<properties>[2].name<property>.name<property-name>", is( "test-name-3" ) ); + JsonAssert.with( output ).assertThat( "name<properties>[2].name<property>.name<property-value>", is( "value:test-rule<test-value-3>" ) ); + } + + @Test + public void testBufferedMultiApply() throws IOException { + InputStream stream = TestUtils.getResourceStream( this.getClass(), "properties.json" ); + String input = IOUtils.toString( stream, Charset.forName( "UTF-8" ) ); + + //System.out.println( "INPUT=" + input ); + + UrlRewriteRulesDescriptor rulesConfig = UrlRewriteRulesDescriptorFactory.create(); + UrlRewriteFilterDescriptor filterConfig = rulesConfig.addFilter( "filter-1" ); + UrlRewriteFilterContentDescriptor contentConfig = filterConfig.addContent( "text/json" ); + UrlRewriteFilterBufferDescriptor bufferConfig = contentConfig.addBuffer( "$.name<properties>" ); + UrlRewriteFilterApplyDescriptor applyConfig = bufferConfig.addApply( "$.*.name<property>.name<property-value>", "test-rule" ); + + //UrlRewriteRulesDescriptorFactory.store( rulesConfig, "xml", new PrintWriter( System.out ) ); + + JsonFilterReader filter = new TestJsonFilterReader( new StringReader( input ), contentConfig ); + String output = IOUtils.toString( filter ); + + //System.out.println( "OUTPUT=" + output ); + + JsonAssert.with( output ).assertThat( "name<properties>[0].name<property>.name<property-name>", is( "test-name-1" ) ); + JsonAssert.with( output ).assertThat( "name<properties>[0].name<property>.name<property-value>", is( "value:test-rule<test-value-1>" ) ); + JsonAssert.with( output ).assertThat( "name<properties>[1].name<property>.name<property-name>", is( "test-name-2" ) ); + JsonAssert.with( output ).assertThat( "name<properties>[1].name<property>.name<property-value>", is( "value:test-rule<test-value-2>" ) ); + JsonAssert.with( output ).assertThat( "name<properties>[2].name<property>.name<property-name>", is( "test-name-3" ) ); + JsonAssert.with( output ).assertThat( "name<properties>[2].name<property>.name<property-value>", is( "value:test-rule<test-value-3>" ) ); + } + + @Test + public void testInvalidConfigShouldThrowException() throws Exception { + String input = "{\"test-name\":\"test-value\"}"; + + //System.out.println( "INPUT=" + input ); + + UrlRewriteRulesDescriptor rulesConfig = UrlRewriteRulesDescriptorFactory.create(); + UrlRewriteFilterDescriptor filterConfig = rulesConfig.addFilter( "filter-1" ); + UrlRewriteFilterContentDescriptor contentConfig = filterConfig.addContent( "*/json" ); + contentConfig.addApply( "/root/@url", "test-rule" ); + + //UrlRewriteRulesDescriptorFactory.store( rulesConfig, "xml", new PrintWriter( System.out ) ); + + try { + JsonFilterReader filter = new TestJsonFilterReader( new StringReader( input ), contentConfig ); + IOUtils.toString( filter ); + fail( "Should have thrown an IllegalArgumentException." ); + } catch ( IOException e ) { + fail( "Should have thrown an IllegalArgumentException." ); + } catch ( IllegalArgumentException e ) { + assertThat( e.getMessage(), containsString( "/root/@url" ) ); + } + } + + @Test + public void testEscapeCharactersBugKnox616() throws Exception { + String input, output; + JsonFilterReader filter; + + input = "{ \"test-name\" : \"\\\"\" }"; + filter = new NoopJsonFilterReader( new StringReader( input ), null ); + output = IOUtils.toString( filter ); + assertThat( output, is( "{\"test-name\":\"\\\"\"}" ) ); + + input = "{\"test-name\":\"\\b\"}"; + filter = new NoopJsonFilterReader( new StringReader( input ), null ); + output = IOUtils.toString( filter ); + assertThat( output, is( "{\"test-name\":\"\\b\"}" ) ); + } + +// private void dump( ObjectMapper mapper, JsonGenerator generator, JsonNode node ) throws IOException { +// mapper.writeTree( generator, node ); +// System.out.println(); +// } + +} http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/json/NoopJsonFilterReader.java ---------------------------------------------------------------------- diff --git a/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/json/NoopJsonFilterReader.java b/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/json/NoopJsonFilterReader.java new file mode 100644 index 0000000..bb5c6ca --- /dev/null +++ b/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/json/NoopJsonFilterReader.java @@ -0,0 +1,39 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.apache.knox.gateway.filter.rewrite.impl.json; + +import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFilterContentDescriptor; + +import java.io.IOException; +import java.io.Reader; + +public class NoopJsonFilterReader extends JsonFilterReader { + + public NoopJsonFilterReader( Reader reader, UrlRewriteFilterContentDescriptor config ) throws IOException { + super( reader, config ); + } + + protected String filterFieldName( String name ) { + return name; + } + + protected String filterValueString( String name, String value, String rule ) { + return value; + } + +} http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/json/TestJsonFilterReader.java ---------------------------------------------------------------------- diff --git a/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/json/TestJsonFilterReader.java b/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/json/TestJsonFilterReader.java new file mode 100644 index 0000000..197c5ec --- /dev/null +++ b/gateway-provider-rewrite/src/test/java/org/apache/knox/gateway/filter/rewrite/impl/json/TestJsonFilterReader.java @@ -0,0 +1,39 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.apache.knox.gateway.filter.rewrite.impl.json; + +import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFilterContentDescriptor; + +import java.io.IOException; +import java.io.Reader; + +public class TestJsonFilterReader extends JsonFilterReader { + + public TestJsonFilterReader( Reader reader, UrlRewriteFilterContentDescriptor config ) throws IOException { + super( reader, config ); + } + + protected String filterFieldName( String name ) { + return "name<" + name + ">"; + } + + protected String filterValueString( String name, String value, String rule ) { + return "value:" + rule + "<" + value + ">"; + } + +}