/** * 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.hadoop.gateway.filter.rewrite.impl.json; import com.jayway.jsonassert.JsonAssert; import org.apache.commons.io.IOUtils; import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteFilterApplyDescriptor; import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteFilterBufferDescriptor; import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteFilterContentDescriptor; import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteFilterDescriptor; import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteFilterDetectDescriptor; import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteRulesDescriptor; import org.apache.hadoop.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.math.BigInteger; 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(); // } }