Repository: qpid-jms Updated Branches: refs/heads/master b05d577c1 -> 669cfff83
http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/669cfff8/qpid-jms-client/src/test/java/org/apache/qpid/jms/util/ClassLoadingAwareObjectInputStreamTest.java ---------------------------------------------------------------------- diff --git a/qpid-jms-client/src/test/java/org/apache/qpid/jms/util/ClassLoadingAwareObjectInputStreamTest.java b/qpid-jms-client/src/test/java/org/apache/qpid/jms/util/ClassLoadingAwareObjectInputStreamTest.java new file mode 100644 index 0000000..82de42c --- /dev/null +++ b/qpid-jms-client/src/test/java/org/apache/qpid/jms/util/ClassLoadingAwareObjectInputStreamTest.java @@ -0,0 +1,569 @@ +/* + * 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.qpid.jms.util; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.util.Arrays; +import java.util.UUID; +import java.util.Vector; + +import org.apache.qpid.jms.util.ClassLoadingAwareObjectInputStream.TrustedClassFilter; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestName; + +public class ClassLoadingAwareObjectInputStreamTest { + + private final TrustedClassFilter ACCEPTS_ALL_FILTER = new TrustedClassFilter() { + + @Override + public boolean isTrusted(Class<?> clazz) { + return true; + } + }; + + private final TrustedClassFilter ACCEPTS_NONE_FILTER = new TrustedClassFilter() { + + @Override + public boolean isTrusted(Class<?> clazz) { + return false; + } + }; + + @Rule + public TestName name = new TestName(); + + //----- Test for serialized objects --------------------------------------// + + @Test + public void testReadObject() throws Exception { + // Expect to succeed + doTestReadObject(new SimplePojo(name.getMethodName()), ACCEPTS_ALL_FILTER); + + // Expect to fail + try { + doTestReadObject(new SimplePojo(name.getMethodName()), ACCEPTS_NONE_FILTER); + fail("Should have failed to read"); + } catch (ClassNotFoundException cnfe) { + // Expected + } + } + + @Test + public void testReadObjectWithAnonymousClass() throws Exception { + AnonymousSimplePojoParent pojoParent = new AnonymousSimplePojoParent(name.getMethodName()); + + byte[] serialized = serializeObject(pojoParent); + + TrustedClassFilter myFilter = new TrustedClassFilter() { + @Override + public boolean isTrusted(Class<?> clazz) { + return clazz.equals(AnonymousSimplePojoParent.class); + } + }; + + try (ByteArrayInputStream input = new ByteArrayInputStream(serialized); + ClassLoadingAwareObjectInputStream reader = new ClassLoadingAwareObjectInputStream(input, myFilter)) { + + Object obj = reader.readObject(); + + assertTrue(obj instanceof AnonymousSimplePojoParent); + assertEquals("Unexpected payload", pojoParent.getPayload(), ((AnonymousSimplePojoParent)obj).getPayload()); + } + } + + @Test + public void testReadObjectWitLocalClass() throws Exception { + LocalSimplePojoParent pojoParent = new LocalSimplePojoParent(name.getMethodName()); + + byte[] serialized = serializeObject(pojoParent); + + TrustedClassFilter myFilter = new TrustedClassFilter() { + @Override + public boolean isTrusted(Class<?> clazz) { + return clazz.equals(LocalSimplePojoParent.class); + } + }; + + try (ByteArrayInputStream input = new ByteArrayInputStream(serialized); + ClassLoadingAwareObjectInputStream reader = new ClassLoadingAwareObjectInputStream(input, myFilter)) { + + Object obj = reader.readObject(); + + assertTrue(obj instanceof LocalSimplePojoParent); + assertEquals("Unexpected payload", pojoParent.getPayload(), ((LocalSimplePojoParent)obj).getPayload()); + } + } + + @Test + public void testReadObjectByte() throws Exception { + doTestReadObject(Byte.valueOf((byte) 255), ACCEPTS_ALL_FILTER); + } + + @Test + public void testReadObjectShort() throws Exception { + doTestReadObject(Short.valueOf((short) 255), ACCEPTS_ALL_FILTER); + } + + @Test + public void testReadObjectInteger() throws Exception { + doTestReadObject(Integer.valueOf(255), ACCEPTS_ALL_FILTER); + } + + @Test + public void testReadObjectLong() throws Exception { + doTestReadObject(Long.valueOf(255l), ACCEPTS_ALL_FILTER); + } + + @Test + public void testReadObjectFloat() throws Exception { + doTestReadObject(Float.valueOf(255.0f), ACCEPTS_ALL_FILTER); + } + + @Test + public void testReadObjectDouble() throws Exception { + doTestReadObject(Double.valueOf(255.0), ACCEPTS_ALL_FILTER); + } + + @Test + public void testReadObjectBoolean() throws Exception { + doTestReadObject(Boolean.FALSE, ACCEPTS_ALL_FILTER); + } + + @Test + public void testReadObjectString() throws Exception { + doTestReadObject(new String(name.getMethodName()), ACCEPTS_ALL_FILTER); + } + + //----- Test that arrays of objects can be read --------------------------// + + @Test + public void testReadObjectStringArray() throws Exception { + String[] value = new String[2]; + + value[0] = name.getMethodName() + "-1"; + value[1] = name.getMethodName() + "-2"; + + doTestReadObject(value, ACCEPTS_ALL_FILTER); + } + + @Test + public void testReadObjectMultiDimensionalArray() throws Exception { + String[][][] value = new String[2][2][1]; + + value[0][0][0] = "0-0-0"; + value[0][1][0] = "0-1-0"; + value[1][0][0] = "1-0-0"; + value[1][1][0] = "1-1-0"; + + doTestReadObject(value, ACCEPTS_ALL_FILTER); + } + + //----- Test that primitive types are not filtered -----------------------// + + @Test + public void testPrimitiveByteNotFiltered() throws Exception { + doTestReadPrimitive((byte) 255, ACCEPTS_NONE_FILTER); + } + + @Test + public void testPrimitiveShortNotFiltered() throws Exception { + doTestReadPrimitive((short) 255, ACCEPTS_NONE_FILTER); + } + + @Test + public void testPrimitiveIntegerNotFiltered() throws Exception { + doTestReadPrimitive(255, ACCEPTS_NONE_FILTER); + } + + @Test + public void testPrimitiveLongNotFiltered() throws Exception { + doTestReadPrimitive((long) 255, ACCEPTS_NONE_FILTER); + } + + @Test + public void testPrimitiveFloatNotFiltered() throws Exception { + doTestReadPrimitive((float) 255.0, ACCEPTS_NONE_FILTER); + } + + @Test + public void testPrimitiveDoubleNotFiltered() throws Exception { + doTestReadPrimitive(255.0, ACCEPTS_NONE_FILTER); + } + + @Test + public void testPrimitiveBooleanNotFiltered() throws Exception { + doTestReadPrimitive(false, ACCEPTS_NONE_FILTER); + } + + @Test + public void testPrimitveCharNotFiltered() throws Exception { + doTestReadPrimitive('c', ACCEPTS_NONE_FILTER); + } + + @Test + public void testReadObjectStringNotFiltered() throws Exception { + doTestReadObject(new String(name.getMethodName()), ACCEPTS_NONE_FILTER); + } + + //----- Test that primitive arrays get past filters ----------------------// + + @Test + public void testPrimitiveByteArrayNotFiltered() throws Exception { + byte[] value = new byte[2]; + + value[0] = 1; + value[1] = 2; + + doTestReadPrimitiveArray(value, ACCEPTS_NONE_FILTER); + } + + @Test + public void testPrimitiveShortArrayNotFiltered() throws Exception { + short[] value = new short[2]; + + value[0] = 1; + value[1] = 2; + + doTestReadPrimitiveArray(value, ACCEPTS_NONE_FILTER); + } + + @Test + public void testPrimitiveIntegerArrayNotFiltered() throws Exception { + int[] value = new int[2]; + + value[0] = 1; + value[1] = 2; + + doTestReadPrimitiveArray(value, ACCEPTS_NONE_FILTER); + } + + @Test + public void testPrimitiveLongArrayNotFiltered() throws Exception { + long[] value = new long[2]; + + value[0] = 1; + value[1] = 2; + + doTestReadPrimitiveArray(value, ACCEPTS_NONE_FILTER); + } + + @Test + public void testPrimitiveFloatArrayNotFiltered() throws Exception { + float[] value = new float[2]; + + value[0] = 1.1f; + value[1] = 2.1f; + + doTestReadPrimitiveArray(value, ACCEPTS_NONE_FILTER); + } + + @Test + public void testPrimitiveDoubleArrayNotFiltered() throws Exception { + double[] value = new double[2]; + + value[0] = 1.1; + value[1] = 2.1; + + doTestReadPrimitiveArray(value, ACCEPTS_NONE_FILTER); + } + + //----- Tests for types that should be filtered --------------------------// + + @Test + public void testReadObjectStringArrayFiltered() throws Exception { + String[] value = new String[2]; + + value[0] = name.getMethodName() + "-1"; + value[1] = name.getMethodName() + "-2"; + + byte[] serialized = serializeObject(value); + + try (ByteArrayInputStream input = new ByteArrayInputStream(serialized); + ClassLoadingAwareObjectInputStream reader = new ClassLoadingAwareObjectInputStream(input, ACCEPTS_NONE_FILTER)) { + + try { + reader.readObject(); + fail("Should not be able to read the payload."); + } catch (ClassNotFoundException ex) {} + } + } + + @Test + public void testReadObjectMixedTypeArrayGetsFiltered() throws Exception { + Object[] value = new Object[4]; + + value[0] = name.getMethodName(); + value[1] = UUID.randomUUID(); + value[2] = new Vector<Object>(); + value[3] = new SimplePojo(name.getMethodName()); + + byte[] serialized = serializeObject(value); + + TrustedClassFilter myFilter = new TrustedClassFilter() { + + @Override + public boolean isTrusted(Class<?> clazz) { + return !clazz.equals(SimplePojo.class); + } + }; + + try (ByteArrayInputStream input = new ByteArrayInputStream(serialized); + ClassLoadingAwareObjectInputStream reader = new ClassLoadingAwareObjectInputStream(input, myFilter)) { + + try { + reader.readObject(); + fail("Should not be able to read the payload."); + } catch (ClassNotFoundException ex) {} + } + + // Replace the filtered type and try again + value[3] = new Integer(20); + + serialized = serializeObject(value); + + try (ByteArrayInputStream input = new ByteArrayInputStream(serialized); + ClassLoadingAwareObjectInputStream reader = new ClassLoadingAwareObjectInputStream(input, myFilter)) { + + try { + Object result = reader.readObject(); + + assertNotNull(result); + assertTrue(result.getClass().isArray()); + } catch (ClassNotFoundException ex) { + fail("Should be able to read the payload."); + } + } + } + + @Test + public void testReadObjectMultiDimensionalStringArrayFiltered() throws Exception { + String[][] value = new String[2][2]; + + value[0][0] = name.getMethodName() + "-0-0"; + value[0][1] = name.getMethodName() + "-0-1"; + value[1][0] = name.getMethodName() + "-1-0"; + value[1][1] = name.getMethodName() + "-1-1"; + + byte[] serialized = serializeObject(value); + + try (ByteArrayInputStream input = new ByteArrayInputStream(serialized); + ClassLoadingAwareObjectInputStream reader = new ClassLoadingAwareObjectInputStream(input, ACCEPTS_NONE_FILTER)) { + + try { + reader.readObject(); + fail("Should not be able to read the payload."); + } catch (ClassNotFoundException ex) {} + } + } + + @Test + public void testReadObjectFailsWithUntrustedType() throws Exception { + byte[] serialized = serializeObject(new SimplePojo(name.getMethodName())); + + TrustedClassFilter myFilter = new TrustedClassFilter() { + + @Override + public boolean isTrusted(Class<?> clazz) { + return !clazz.equals(SimplePojo.class); + } + }; + + try (ByteArrayInputStream input = new ByteArrayInputStream(serialized); + ClassLoadingAwareObjectInputStream reader = new ClassLoadingAwareObjectInputStream(input, myFilter)) { + + try { + reader.readObject(); + fail("Should not be able to read the payload."); + } catch (ClassNotFoundException ex) {} + } + + serialized = serializeObject(UUID.randomUUID()); + try (ByteArrayInputStream input = new ByteArrayInputStream(serialized); + ClassLoadingAwareObjectInputStream reader = new ClassLoadingAwareObjectInputStream(input, myFilter)) { + + try { + reader.readObject(); + } catch (ClassNotFoundException ex) { + fail("Should be able to read the payload."); + } + } + } + + @Test + public void testReadObjectFailsWithUnstrustedContentInTrustedType() throws Exception { + byte[] serialized = serializeObject(new SimplePojo(UUID.randomUUID())); + + TrustedClassFilter myFilter = new TrustedClassFilter() { + + @Override + public boolean isTrusted(Class<?> clazz) { + return clazz.equals(SimplePojo.class); + } + }; + + ByteArrayInputStream input = new ByteArrayInputStream(serialized); + try (ClassLoadingAwareObjectInputStream reader = new ClassLoadingAwareObjectInputStream(input, myFilter)) { + try { + reader.readObject(); + fail("Should not be able to read the payload."); + } catch (ClassNotFoundException ex) {} + } + + serialized = serializeObject(UUID.randomUUID()); + input = new ByteArrayInputStream(serialized); + try (ClassLoadingAwareObjectInputStream reader = new ClassLoadingAwareObjectInputStream(input, myFilter)) { + try { + reader.readObject(); + fail("Should not be able to read the payload."); + } catch (ClassNotFoundException ex) { + } + } + } + + //----- Internal methods -------------------------------------------------// + + private void doTestReadObject(Object value, TrustedClassFilter filter) throws Exception { + byte[] serialized = serializeObject(value); + + try (ByteArrayInputStream input = new ByteArrayInputStream(serialized); + ClassLoadingAwareObjectInputStream reader = new ClassLoadingAwareObjectInputStream(input, filter)) { + + Object result = reader.readObject(); + assertNotNull(result); + assertEquals(value.getClass(), result.getClass()); + if (result.getClass().isArray()) { + assertTrue(Arrays.deepEquals((Object[]) value, (Object[]) result)); + } else { + assertEquals(value, result); + } + } + } + + private byte[] serializeObject(Object value) throws IOException { + byte[] result = new byte[0]; + + if (value != null) { + try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos)) { + + oos.writeObject(value); + oos.flush(); + oos.close(); + + result = baos.toByteArray(); + } + } + + return result; + } + + private void doTestReadPrimitive(Object value, TrustedClassFilter filter) throws Exception { + byte[] serialized = serializePrimitive(value); + + try (ByteArrayInputStream input = new ByteArrayInputStream(serialized); + ClassLoadingAwareObjectInputStream reader = new ClassLoadingAwareObjectInputStream(input, filter)) { + + Object result = null; + + if (value instanceof Byte) { + result = reader.readByte(); + } else if (value instanceof Short) { + result = reader.readShort(); + } else if (value instanceof Integer) { + result = reader.readInt(); + } else if (value instanceof Long) { + result = reader.readLong(); + } else if (value instanceof Float) { + result = reader.readFloat(); + } else if (value instanceof Double) { + result = reader.readDouble(); + } else if (value instanceof Boolean) { + result = reader.readBoolean(); + } else if (value instanceof Character) { + result = reader.readChar(); + } else { + throw new IllegalArgumentException("unsuitable type for primitive deserialization"); + } + + assertNotNull(result); + assertEquals(value.getClass(), result.getClass()); + assertEquals(value, result); + } + } + + private void doTestReadPrimitiveArray(Object value, TrustedClassFilter filter) throws Exception { + byte[] serialized = serializeObject(value); + + try (ByteArrayInputStream input = new ByteArrayInputStream(serialized); + ClassLoadingAwareObjectInputStream reader = new ClassLoadingAwareObjectInputStream(input, filter)) { + + Object result = reader.readObject(); + + assertNotNull(result); + assertEquals(value.getClass(), result.getClass()); + assertTrue(result.getClass().isArray()); + assertEquals(value.getClass().getComponentType(), result.getClass().getComponentType()); + assertTrue(result.getClass().getComponentType().isPrimitive()); + } + } + + private byte[] serializePrimitive(Object value) throws IOException { + byte[] result = new byte[0]; + + if (value != null) { + try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos)) { + + if (value instanceof Byte) { + oos.writeByte((byte) value); + } else if (value instanceof Short) { + oos.writeShort((short) value); + } else if (value instanceof Integer) { + oos.writeInt((int) value); + } else if (value instanceof Long) { + oos.writeLong((long) value); + } else if (value instanceof Float) { + oos.writeFloat((float) value); + } else if (value instanceof Double) { + oos.writeDouble((double) value); + } else if (value instanceof Boolean) { + oos.writeBoolean((boolean) value); + } else if (value instanceof Character) { + oos.writeChar((char) value); + } else { + throw new IllegalArgumentException("unsuitable type for primitive serialization"); + } + + oos.flush(); + oos.close(); + + result = baos.toByteArray(); + } + } + + return result; + } +} http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/669cfff8/qpid-jms-client/src/test/java/org/apache/qpid/jms/util/LocalSimplePojoParent.java ---------------------------------------------------------------------- diff --git a/qpid-jms-client/src/test/java/org/apache/qpid/jms/util/LocalSimplePojoParent.java b/qpid-jms-client/src/test/java/org/apache/qpid/jms/util/LocalSimplePojoParent.java new file mode 100644 index 0000000..45c1bd0 --- /dev/null +++ b/qpid-jms-client/src/test/java/org/apache/qpid/jms/util/LocalSimplePojoParent.java @@ -0,0 +1,46 @@ +/* + * 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.qpid.jms.util; + +import java.io.Serializable; + +public class LocalSimplePojoParent implements Serializable { + + private static final long serialVersionUID = 1L; + + private SimplePojo payload; + + public LocalSimplePojoParent(Object simplePojoPayload) { + // Create an LOCAL simple payload, itself serializable, like we + // have to be since the object references us and is used + // during the serialization. + + class LocalSimplPojo extends SimplePojo { + private static final long serialVersionUID = 1L; + + LocalSimplPojo(Object simplePojoPayload) { + super(simplePojoPayload); + } + } + + payload = new LocalSimplPojo(simplePojoPayload); + } + + public SimplePojo getPayload() { + return payload; + } +} http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/669cfff8/qpid-jms-client/src/test/java/org/apache/qpid/jms/util/PropertyUtilTest.java ---------------------------------------------------------------------- diff --git a/qpid-jms-client/src/test/java/org/apache/qpid/jms/util/PropertyUtilTest.java b/qpid-jms-client/src/test/java/org/apache/qpid/jms/util/PropertyUtilTest.java index 797f5ee..261b843 100644 --- a/qpid-jms-client/src/test/java/org/apache/qpid/jms/util/PropertyUtilTest.java +++ b/qpid-jms-client/src/test/java/org/apache/qpid/jms/util/PropertyUtilTest.java @@ -246,6 +246,17 @@ public class PropertyUtilTest { } @Test + public void testParseParametersFromStringWithNoValues() throws Exception { + Map<String, String> result = PropertyUtil.parseParameters("http://www.example.com?option=&another="); + + assertTrue(result.size() == 2); + assertTrue(result.containsKey("option")); + assertTrue(result.containsKey("another")); + assertEquals("", result.get("option")); + assertEquals("", result.get("another")); + } + + @Test public void testParseParametersFromURIStringWithNoQuery() throws Exception { Map<String, String> result = PropertyUtil.parseParameters("http://www.example.com"); assertNotNull(result); http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/669cfff8/qpid-jms-client/src/test/java/org/apache/qpid/jms/util/SimplePojo.java ---------------------------------------------------------------------- diff --git a/qpid-jms-client/src/test/java/org/apache/qpid/jms/util/SimplePojo.java b/qpid-jms-client/src/test/java/org/apache/qpid/jms/util/SimplePojo.java new file mode 100644 index 0000000..00598da --- /dev/null +++ b/qpid-jms-client/src/test/java/org/apache/qpid/jms/util/SimplePojo.java @@ -0,0 +1,73 @@ +/* + * 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.qpid.jms.util; + +import java.io.Serializable; + +public class SimplePojo implements Serializable { + + private static final long serialVersionUID = 3258560248864895099L; + + private Object payload; + + public SimplePojo() { + } + + public SimplePojo(Object payload) { + this.payload = payload; + } + + public Object getPayload() { + return payload; + } + + public void setPayload(Object payload) { + this.payload = payload; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((payload == null) ? 0 : payload.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + + SimplePojo other = (SimplePojo) obj; + if (payload == null) { + if (other.payload != null) { + return false; + } + } else if (!payload.equals(other.payload)) { + return false; + } + + return true; + } +} http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/669cfff8/qpid-jms-client/src/test/java/org/apache/qpid/jms/util/URISupportTest.java ---------------------------------------------------------------------- diff --git a/qpid-jms-client/src/test/java/org/apache/qpid/jms/util/URISupportTest.java b/qpid-jms-client/src/test/java/org/apache/qpid/jms/util/URISupportTest.java index b936b90..6495858 100644 --- a/qpid-jms-client/src/test/java/org/apache/qpid/jms/util/URISupportTest.java +++ b/qpid-jms-client/src/test/java/org/apache/qpid/jms/util/URISupportTest.java @@ -16,22 +16,28 @@ */ package org.apache.qpid.jms.util; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + import java.net.URI; import java.net.URISyntaxException; import java.util.HashMap; import java.util.Map; -import junit.framework.TestCase; - import org.apache.qpid.jms.util.URISupport.CompositeData; +import org.junit.Test; -public class URISupportTest extends TestCase { +public class URISupportTest { + @Test public void testEmptyCompositePath() throws Exception { CompositeData data = URISupport.parseComposite(new URI("broker:()/localhost?persistent=false")); assertEquals(0, data.getComponents().size()); } + @Test public void testCompositePath() throws Exception { CompositeData data = URISupport.parseComposite(new URI("test:(path)/path")); assertEquals("path", data.getPath()); @@ -39,17 +45,20 @@ public class URISupportTest extends TestCase { assertNull(data.getPath()); } + @Test public void testSimpleComposite() throws Exception { CompositeData data = URISupport.parseComposite(new URI("test:part1")); assertEquals(1, data.getComponents().size()); } + @Test public void testComposite() throws Exception { URI uri = new URI("test:(part1://host,part2://(sub1://part,sube2:part))"); CompositeData data = URISupport.parseComposite(uri); assertEquals(2, data.getComponents().size()); } + @Test public void testEmptyCompositeWithParenthesisInParam() throws Exception { URI uri = new URI("failover://()?updateURIsURL=file:/C:/Dir(1)/a.csv"); CompositeData data = URISupport.parseComposite(uri); @@ -59,6 +68,7 @@ public class URISupportTest extends TestCase { assertEquals("file:/C:/Dir(1)/a.csv", data.getParameters().get("updateURIsURL")); } + @Test public void testCompositeWithParenthesisInParam() throws Exception { URI uri = new URI("failover://(test)?updateURIsURL=file:/C:/Dir(1)/a.csv"); CompositeData data = URISupport.parseComposite(uri); @@ -68,6 +78,7 @@ public class URISupportTest extends TestCase { assertEquals("file:/C:/Dir(1)/a.csv", data.getParameters().get("updateURIsURL")); } + @Test public void testCompositeWithComponentParam() throws Exception { CompositeData data = URISupport.parseComposite(new URI("test:(part1://host?part1=true)?outside=true")); assertEquals(1, data.getComponents().size()); @@ -77,6 +88,7 @@ public class URISupportTest extends TestCase { assertTrue(part1Params.containsKey("part1")); } + @Test public void testParsingURI() throws Exception { URI source = new URI("tcp://localhost:61626/foo/bar?cheese=Edam&x=123"); @@ -91,16 +103,33 @@ public class URISupportTest extends TestCase { assertEquals("result", new URI("tcp://localhost:61626/foo/bar"), result); } + @Test + public void testParsingURIWithEmptyValuesInOptions() throws Exception { + URI source = new URI("tcp://localhost:61626/foo/bar?cheese=&x="); + + Map<String, String> map = PropertyUtil.parseParameters(source); + + assertEquals("Size: " + map, 2, map.size()); + assertMapKey(map, "cheese", ""); + assertMapKey(map, "x", ""); + + URI result = URISupport.removeQuery(source); + + assertEquals("result", new URI("tcp://localhost:61626/foo/bar"), result); + } + protected void assertMapKey(Map<String, String> map, String key, Object expected) { assertEquals("Map key: " + key, map.get(key), expected); } + @Test public void testParsingCompositeURI() throws URISyntaxException { CompositeData data = URISupport.parseComposite(new URI("broker://(tcp://localhost:61616)?name=foo")); assertEquals("one component", 1, data.getComponents().size()); assertEquals("Size: " + data.getParameters(), 1, data.getParameters().size()); } + @Test public void testCheckParenthesis() throws Exception { String str = "fred:(((ddd))"; assertFalse(URISupport.checkParenthesis(str)); @@ -108,6 +137,7 @@ public class URISupportTest extends TestCase { assertTrue(URISupport.checkParenthesis(str)); } + @Test public void testCreateWithQuery() throws Exception { URI source = new URI("vm://localhost"); URI dest = PropertyUtil.replaceQuery(source, "network=true&one=two"); @@ -118,6 +148,7 @@ public class URISupportTest extends TestCase { assertFalse("same uri, ssp", dest.getQuery().equals(source.getQuery())); } + @Test public void testParsingParams() throws Exception { URI uri = new URI("static:(http://localhost:61617?proxyHost=jo&proxyPort=90)?proxyHost=localhost&proxyPort=80"); Map<String,String>parameters = URISupport.parseParameters(uri); @@ -129,6 +160,7 @@ public class URISupportTest extends TestCase { parameters = URISupport.parseParameters(uri); } + @Test public void testCompositeCreateURIWithQuery() throws Exception { String queryString = "query=value"; URI originalURI = new URI("outerscheme:(innerscheme:innerssp)"); @@ -151,6 +183,7 @@ public class URISupportTest extends TestCase { assertEquals(new URI(querylessURI + "?" + queryString), PropertyUtil.replaceQuery(originalURI, queryString)); } + @Test public void testApplyParameters() throws Exception { URI uri = new URI("http://0.0.0.0:61616"); @@ -178,6 +211,7 @@ public class URISupportTest extends TestCase { assertEquals(parameters.get("proxyPort"), "80"); } + @Test public void testIsCompositeURIWithQueryNoSlashes() throws URISyntaxException { URI[] compositeURIs = new URI[] { new URI("test:(part1://host?part1=true)?outside=true"), new URI("broker:(tcp://localhost:61616)?name=foo") }; for (URI uri : compositeURIs) { @@ -185,6 +219,7 @@ public class URISupportTest extends TestCase { } } + @Test public void testIsCompositeURIWithQueryAndSlashes() throws URISyntaxException { URI[] compositeURIs = new URI[] { new URI("test://(part1://host?part1=true)?outside=true"), new URI("broker://(tcp://localhost:61616)?name=foo") }; for (URI uri : compositeURIs) { @@ -192,6 +227,7 @@ public class URISupportTest extends TestCase { } } + @Test public void testIsCompositeURINoQueryNoSlashes() throws URISyntaxException { URI[] compositeURIs = new URI[] { new URI("test:(part1://host,part2://(sub1://part,sube2:part))"), new URI("test:(path)/path") }; for (URI uri : compositeURIs) { @@ -199,10 +235,12 @@ public class URISupportTest extends TestCase { } } + @Test public void testIsCompositeURINoQueryNoSlashesNoParentheses() throws URISyntaxException { assertFalse("test:part1" + " must be detected as non-composite URI", URISupport.isCompositeURI(new URI("test:part1"))); } + @Test public void testIsCompositeURINoQueryWithSlashes() throws URISyntaxException { URI[] compositeURIs = new URI[] { new URI("failover://(tcp://bla:61616,tcp://bla:61617)"), new URI("failover://(tcp://localhost:61616,ssl://anotherhost:61617)") }; @@ -210,5 +248,4 @@ public class URISupportTest extends TestCase { assertTrue(uri + " must be detected as composite URI", URISupport.isCompositeURI(uri)); } } - } http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/669cfff8/qpid-jms-docs/Configuration.md ---------------------------------------------------------------------- diff --git a/qpid-jms-docs/Configuration.md b/qpid-jms-docs/Configuration.md index 6e04a6b..6ff5820 100644 --- a/qpid-jms-docs/Configuration.md +++ b/qpid-jms-docs/Configuration.md @@ -99,7 +99,7 @@ The options apply to the behaviour of the JMS objects such as Connection, Sessio + **jms.connectionIDPrefix** Optional prefix value that is used for generated Connection ID values when a new Connection is created for the JMS ConnectionFactory. This connection ID is used when logging some information from the JMS Connection object so a configurable prefix can make breadcrumbing the logs easier. The default prefix is 'ID:'. + **jms.populateJMSXUserID** Controls whether a MessageProducer will populate the JMSXUserID value for each sent message using the authenticated username from the connection. This value defaults to false and the JMSXUserID for all sent message will not be populated. -These values control how many messages the remote peer can send to the client and be held in a prefetch buffer for each consumer instance. +The Prefetch Policy controls how many messages the remote peer can send to the client and be held in a prefetch buffer for each consumer instance. + **jms.prefetchPolicy.queuePrefetch** defaults to 1000 + **jms.prefetchPolicy.topicPrefetch** defaults to 1000 @@ -107,7 +107,7 @@ These values control how many messages the remote peer can send to the client an + **jms.prefetchPolicy.durableTopicPrefetch** defaults to 1000 + **jms.prefetchPolicy.all** used to set all prefetch values at once. -The RedeliveryPolicy controls how redelivered messages are handled on the client. +The Redelivery Policy controls how redelivered messages are handled on the client. + **jms.redeliveryPolicy.maxRedeliveries** controls when an incoming message is rejected based on the number of times it has been redelivered, the default value is (-1) disabled. A value of zero would indicate no message redeliveries are accepted, a value of five would allow a message to be redelivered five times, etc. @@ -115,7 +115,7 @@ The MessageID Policy controls the type of the Message ID assigned to messages se + **jms.messageIDPolicy.messageIDType** By default a generated String value is used for the MessageID on outgoing messages. Other available types are UUID and UUID_STRING. -The PresettlePolicy controls when a producer or consumer instance will be configured to use AMQP presettled messaging semantics. +The Presettle Policy controls when a producer or consumer instance will be configured to use AMQP presettled messaging semantics. + **jms.presettlePolicy.presettleAll** when true all producers and non-transacted consumers created operate in presettled mode, defaults to false. + **jms.presettlePolicy.presettleProducers** when true all producers operate in presettled mode, defaults to false. @@ -126,6 +126,11 @@ The PresettlePolicy controls when a producer or consumer instance will be config + **jms.presettlePolicy.presettleTopicConsumers** when true any consumer that is receiving from a Topic or Temporary Topic destination will operate in presettled mode, defaults to false. + **jms.presettlePolicy.presettleQueueConsumers** when true any consumer that is receiving from a Queue or Temporary Queue destination will operate in presettled mode, defaults to false. +The Deserialization Policy provides a means of controlling which types are trusted to be deserialized from the object stream while retrieving the body from an incoming JMS ObjectMessage composed of serialized Java Object content. By default all types are trusted during attempt to deserialize the body. The default Deserialization Policy object provides URI options that allow specifying a whitelist and a blacklist of Java class or package names. + +**jms.deserializationPolicy.whiteList** A comma separated list of class/package names that should be allowed when deserializing the contents of a JMS ObjectMessage, unless overridden by the blackList. The names in this list are not pattern values, the exact class or package name must be configured, e.g "java.util.Map" or "java.util". Package matches include sub-packages. Default is to allow all. +**jms.deserializationPolicy.blackList** A comma separated list of class/package names that should be rejected when deserializing the contents of a JMS ObjectMessage. The names in this list are not pattern values, the exact class or package name must be configured, e.g "java.util.Map" or "java.util". Package matches include sub-packages. Default is to prevent none. + ### TCP Transport Configuration options When connected to a remote using plain TCP these options configure the behaviour of the underlying socket. These options are appended to the connection URI along with the other configuration options, for example: --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
