/* * JBoss, Home of Professional Open Source. * Copyright 2011, Red Hat Middleware LLC, and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jboss.as.controller; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import java.io.File; import org.jboss.dmr.ModelNode; import org.jboss.dmr.ModelType; import org.jboss.dmr.ValueExpression; import org.junit.Test; /** * * @author <a href="kabir.khan@jboss.com">Kabir Khan</a> */ public class ExpressionResolverUnitTestCase { @Test(expected = OperationFailedException.class) public void testDefaultExpressionResolverWithNoResolutions() throws OperationFailedException { ModelNode unresolved = createModelNode(); ExpressionResolver.TEST_RESOLVER.resolveExpressions(unresolved); fail("Did not fail with OFE: " + unresolved); } @Test public void testDefaultExpressionResolverWithRecursiveSystemPropertyResolutions() throws OperationFailedException { System.setProperty("test.prop.expr", "EXPR"); System.setProperty("test.prop.b", "B"); System.setProperty("test.prop.c", "C"); System.setProperty("test.prop.two", "TWO"); System.setProperty("test.prop.three", "THREE"); // recursive example System.setProperty("test.prop.prop", "${test.prop.prop.intermediate}"); System.setProperty("test.prop.prop.intermediate", "PROP"); // recursive example with a property expression as the default System.setProperty("test.prop.expr", "${NOTHERE:${ISHERE}}"); System.setProperty("ISHERE", "EXPR"); //PROP try { ModelNode node = ExpressionResolver.TEST_RESOLVER.resolveExpressions(createModelNode()); checkResolved(node); } finally { System.clearProperty("test.prop.expr"); System.clearProperty("test.prop.b"); System.clearProperty("test.prop.c"); System.clearProperty("test.prop.two"); System.clearProperty("test.prop.three"); System.clearProperty("test.prop.prop"); } } @Test public void testDefaultExpressionResolverWithSystemPropertyResolutions() throws OperationFailedException { System.setProperty("test.prop.expr", "EXPR"); System.setProperty("test.prop.b", "B"); System.setProperty("test.prop.c", "C"); System.setProperty("test.prop.two", "TWO"); System.setProperty("test.prop.three", "THREE"); System.setProperty("test.prop.prop", "PROP"); try { ModelNode node = ExpressionResolver.TEST_RESOLVER.resolveExpressions(createModelNode()); checkResolved(node); } finally { System.clearProperty("test.prop.expr"); System.clearProperty("test.prop.b"); System.clearProperty("test.prop.c"); System.clearProperty("test.prop.two"); System.clearProperty("test.prop.three"); System.clearProperty("test.prop.prop"); } } @Test public void testPluggableExpressionResolverRecursive() throws OperationFailedException { ModelNode node = new ExpressionResolverImpl() { @Override protected void resolvePluggableExpression(ModelNode node) { String s = node.asString(); if (s.equals("${test.prop.expr}")) { node.set("${test.prop.expr.inner}"); } else if (s.equals("${test.prop.expr.inner}")) { node.set("EXPR"); } else if (s.equals("${test.prop.b}")) { node.set("B"); } else if (s.equals("${test.prop.c}")) { node.set("C"); } else if (s.equals("${test.prop.two}")) { node.set("TWO"); } else if (s.equals("${test.prop.three}")) { node.set("THREE"); } else if (s.equals("${test.prop.prop}")) { node.set("PROP"); } } }.resolveExpressions(createModelNode()); checkResolved(node); } @Test public void testPluggableExpressionResolver() throws OperationFailedException { ModelNode node = new ExpressionResolverImpl() { @Override protected void resolvePluggableExpression(ModelNode node) { String s = node.asString(); if (s.equals("${test.prop.expr}")) { node.set("EXPR"); } else if (s.equals("${test.prop.b}")) { node.set("B"); } else if (s.equals("${test.prop.c}")) { node.set("C"); } else if (s.equals("${test.prop.two}")) { node.set("TWO"); } else if (s.equals("${test.prop.three}")) { node.set("THREE"); } else if (s.equals("${test.prop.prop}")) { node.set("PROP"); } } }.resolveExpressions(createModelNode()); checkResolved(node); } @Test(expected = OperationFailedException.class) public void testPluggableExpressionResolverNotResolved() throws OperationFailedException { ModelNode unresolved = createModelNode(); new ExpressionResolverImpl() { @Override protected void resolvePluggableExpression(ModelNode node) { } }.resolveExpressions(unresolved); fail("Did not fail with OFE: " + unresolved); } @Test public void testPluggableExpressionResolverSomeResolvedAndSomeByDefault() throws OperationFailedException { System.setProperty("test.prop.c", "C"); System.setProperty("test.prop.three", "THREE"); System.setProperty("test.prop.prop", "PROP"); try { ModelNode node = new ExpressionResolverImpl() { @Override protected void resolvePluggableExpression(ModelNode node) { String s = node.asString(); if (s.equals("${test.prop.expr}")) { node.set("EXPR"); } else if (s.equals("${test.prop.b}")) { node.set("B"); } else if (s.equals("${test.prop.two}")) { node.set("TWO"); } } }.resolveExpressions(createModelNode()); checkResolved(node); } finally { System.clearProperty("test.prop.c"); System.clearProperty("test.prop.three"); System.clearProperty("test.prop.prop"); } } @Test public void testSimpleLenientResolver() { ModelNode input = createModelNode(); input.get("defaulted").set(new ValueExpression("${test:default}")); ModelNode node = new ModelNode(); try { node = ExpressionResolver.SIMPLE_LENIENT.resolveExpressions(input); } catch (OperationFailedException ofe) { fail("Should not have thrown OFE: " + ofe.toString()); } assertEquals(7, node.keys().size()); assertEquals(1, node.get("int").asInt()); assertEquals(new ValueExpression("${test.prop.expr}"), node.get("expr").asExpression()); assertEquals(3, node.get("map").keys().size()); assertEquals("a", node.get("map", "plain").asString()); assertEquals(new ValueExpression("${test.prop.b}"), node.get("map", "prop.b").asExpression()); assertEquals(new ValueExpression("${test.prop.c}"), node.get("map", "prop.c").asExpression()); assertEquals(3, node.get("list").asList().size()); assertEquals("one", node.get("list").asList().get(0).asString()); assertEquals(new ValueExpression("${test.prop.two}"), node.get("list").asList().get(1).asExpression()); assertEquals(new ValueExpression("${test.prop.three}"), node.get("list").asList().get(2).asExpression()); assertEquals("plain", node.get("plainprop").asProperty().getValue().asString()); assertEquals(new ValueExpression("${test.prop.prop}"), node.get("prop").asProperty().getValue().asExpression()); assertEquals("default", node.get("defaulted").asString()); } @Test public void testPluggableExpressionResolverNestedExpression() throws OperationFailedException { System.setProperty("test.prop.nested", "expr"); try { ModelNode node = new ExpressionResolverImpl() { @Override protected void resolvePluggableExpression(ModelNode node) { String s = node.asString(); if (s.equals("${test.prop.expr}")) { node.set("EXPR"); } } }.resolveExpressions(new ModelNode(new ValueExpression("${test.prop.${test.prop.nested}}"))); assertEquals("EXPR", node.asString()); } finally { System.clearProperty("test.prop.nested"); } } @Test public void testNestedExpressions() throws OperationFailedException { System.setProperty("foo", "FOO"); System.setProperty("bar", "BAR"); System.setProperty("baz", "BAZ"); System.setProperty("FOO", "oof"); System.setProperty("BAR", "rab"); System.setProperty("BAZ", "zab"); System.setProperty("foo.BAZ.BAR", "FOO.baz.bar"); System.setProperty("foo.BAZBAR", "FOO.bazbar"); System.setProperty("bazBAR", "BAZbar"); System.setProperty("fooBAZbar", "FOObazBAR"); try { ModelNode node = ExpressionResolver.TEST_RESOLVER.resolveExpressions(expression("${foo:${bar}}")); assertEquals("FOO", node.asString()); node = ExpressionResolver.TEST_RESOLVER.resolveExpressions(expression("${${bar}}")); assertEquals("rab", node.asString()); node = ExpressionResolver.TEST_RESOLVER.resolveExpressions(expression("${foo.${baz}.${bar}}")); assertEquals("FOO.baz.bar", node.asString()); node = ExpressionResolver.TEST_RESOLVER.resolveExpressions(expression("${foo.${baz}${bar}}")); assertEquals("FOO.bazbar", node.asString()); node = ExpressionResolver.TEST_RESOLVER.resolveExpressions(expression("a${foo${baz${bar}}}b")); assertEquals("aFOObazBARb", node.asString()); node = ExpressionResolver.TEST_RESOLVER.resolveExpressions(expression("a${foo${baz${bar}}}")); assertEquals("aFOObazBAR", node.asString()); node = ExpressionResolver.TEST_RESOLVER.resolveExpressions(expression("${foo${baz${bar}}}b")); assertEquals("FOObazBARb", node.asString()); node = ExpressionResolver.TEST_RESOLVER.resolveExpressions(expression("a${foo}.b.${bar}c")); assertEquals("aFOO.b.BARc", node.asString()); System.clearProperty("foo"); node = ExpressionResolver.TEST_RESOLVER.resolveExpressions(expression("${foo:${bar}}")); assertEquals("BAR", node.asString()); node = ExpressionResolver.TEST_RESOLVER.resolveExpressions(expression("${foo:${bar}.{}.$$}")); assertEquals("BAR.{}.$$", node.asString()); node = ExpressionResolver.TEST_RESOLVER.resolveExpressions(expression("$$${bar}")); assertEquals("$BAR", node.asString()); } finally { System.clearProperty("foo"); System.clearProperty("bar"); System.clearProperty("baz"); System.clearProperty("FOO"); System.clearProperty("BAR"); System.clearProperty("BAZ"); System.clearProperty("foo.BAZ.BAR"); System.clearProperty("foo.BAZBAR"); System.clearProperty("bazBAR"); System.clearProperty("fooBAZbar"); } } @Test public void testDollarEscaping() throws OperationFailedException { System.setProperty("$$", "FOO"); try { ModelNode node = ExpressionResolver.TEST_RESOLVER.resolveExpressions(expression("$$")); assertEquals("$", node.asString()); node = ExpressionResolver.TEST_RESOLVER.resolveExpressions(expression("$$$")); assertEquals("$$", node.asString()); node = ExpressionResolver.TEST_RESOLVER.resolveExpressions(expression("$$$$")); assertEquals("$$", node.asString()); node = ExpressionResolver.TEST_RESOLVER.resolveExpressions(expression("${$$$$:$$}")); assertEquals("$$", node.asString()); node = ExpressionResolver.TEST_RESOLVER.resolveExpressions(expression("${$$:$$}")); assertEquals("FOO", node.asString()); node = ExpressionResolver.TEST_RESOLVER.resolveExpressions(expression("${foo:$${bar}}")); assertEquals("${bar}", node.asString()); node = ExpressionResolver.TEST_RESOLVER.resolveExpressions(expression("$${bar}")); assertEquals("${bar}", node.asString()); } finally { System.clearProperty("$$"); } } @Test public void testFileSeparator() throws OperationFailedException { assertEquals(File.separator, ExpressionResolver.TEST_RESOLVER.resolveExpressions(expression("${/}")).asString()); assertEquals(File.separator + "a", ExpressionResolver.TEST_RESOLVER.resolveExpressions(expression("${/}a")).asString()); assertEquals("a" + File.separator, ExpressionResolver.TEST_RESOLVER.resolveExpressions(expression("a${/}")).asString()); } @Test public void testPathSeparator() { assertEquals(File.pathSeparator, new ValueExpression("${:}").resolveString()); assertEquals(File.pathSeparator + "a", new ValueExpression("${:}a").resolveString()); assertEquals("a" + File.pathSeparator, new ValueExpression("a${:}").resolveString()); } @Test public void testNonExpression() throws OperationFailedException { ModelNode node = ExpressionResolver.TEST_RESOLVER.resolveExpressions(expression("abc")); assertEquals("abc", node.asString()); assertEquals(ModelType.STRING, node.getType()); } @Test public void testBlankExpression() throws OperationFailedException { ModelNode node = ExpressionResolver.TEST_RESOLVER.resolveExpressions(expression("")); assertEquals("", node.asString()); assertEquals(ModelType.STRING, node.getType()); } /** * Test that a incomplete expression to a system property reference throws an ISE */ @Test(expected = OperationFailedException.class) public void testIncompleteReference() throws OperationFailedException { System.setProperty("test.property1", "test.property1.value"); try { ModelNode resolved = ExpressionResolver.TEST_RESOLVER.resolveExpressions(expression("${test.property1")); fail("Did not fail with OFE: " + resolved); } finally { System.clearProperty("test.property1"); } } /** * Test that an incomplete expression is ignored if escaped */ @Test public void testEscapedIncompleteReference() throws OperationFailedException { assertEquals("${test.property1", ExpressionResolver.TEST_RESOLVER.resolveExpressions(expression("$${test.property1")).asString()); } /** * Test that a incomplete expression to a system property reference throws an ISE */ @Test(expected = OperationFailedException.class) public void testIncompleteReferenceFollowingSuccessfulResolve() throws OperationFailedException { System.setProperty("test.property1", "test.property1.value"); try { ModelNode resolved = ExpressionResolver.TEST_RESOLVER.resolveExpressions(expression("${test.property1} ${test.property1")); fail("Did not fail with OFE: "+ resolved); } finally { System.clearProperty("test.property1"); } } /** * Test an expression that contains more than one system property name to * see that the second property value is used when the first property * is not defined. */ @Test public void testSystemPropertyRefs() throws OperationFailedException { System.setProperty("test.property2", "test.property2.value"); try { assertEquals("test.property2.value", ExpressionResolver.TEST_RESOLVER.resolveExpressions(expression("${test.property1,test.property2}")).asString()); } finally { System.clearProperty("test.property2"); } assertEquals("default", ExpressionResolver.TEST_RESOLVER.resolveExpressions(expression("${test.property1,test.property2:default}")).asString()); } @Test public void testExpressionWithDollarEndingDefaultValue() throws OperationFailedException { try { ModelNode node = new ModelNode(); node.get("expr").set(new ValueExpression("${test.property.dollar.default:default$}-test")); node = ExpressionResolver.TEST_RESOLVER.resolveExpressions(node); assertEquals("default$-test", node.get("expr").asString()); node = new ModelNode(); node.get("expr").set(new ValueExpression("${test.property.dollar.default:default$test}-test")); node = ExpressionResolver.TEST_RESOLVER.resolveExpressions(node); assertEquals(1, node.keys().size()); assertEquals("default$test-test", node.get("expr").asString()); System.setProperty("test.property.dollar.default", "system-prop-value"); node = new ModelNode(); node.get("expr").set(new ValueExpression("${test.property.dollar.default:default$}-test")); node = ExpressionResolver.TEST_RESOLVER.resolveExpressions(node); assertEquals(1, node.keys().size()); assertEquals("system-prop-value-test", node.get("expr").asString()); node = new ModelNode(); node.get("expr").set(new ValueExpression("${test.property.dollar.default:default$test}-test")); node = ExpressionResolver.TEST_RESOLVER.resolveExpressions(node); assertEquals(1, node.keys().size()); assertEquals("system-prop-value-test", node.get("expr").asString()); } finally { System.clearProperty("test.property.dollar.default"); } } private ModelNode expression(String str) { return new ModelNode(new ValueExpression(str)); } private void checkResolved(ModelNode node) { assertEquals(6, node.keys().size()); assertEquals(1, node.get("int").asInt()); assertEquals("EXPR", node.get("expr").asString()); assertEquals(3, node.get("map").keys().size()); assertEquals("a", node.get("map", "plain").asString()); assertEquals("B", node.get("map", "prop.b").asString()); assertEquals("C", node.get("map", "prop.c").asString()); assertEquals(3, node.get("list").asList().size()); assertEquals("one", node.get("list").asList().get(0).asString()); assertEquals("TWO", node.get("list").asList().get(1).asString()); assertEquals("THREE", node.get("list").asList().get(2).asString()); assertEquals("plain", node.get("plainprop").asProperty().getValue().asString()); assertEquals("PROP", node.get("prop").asProperty().getValue().asString()); } private ModelNode createModelNode() { ModelNode node = new ModelNode(); node.get("int").set(1); node.get("expr").set(new ValueExpression("${test.prop.expr}")); node.get("map", "plain").set("a"); node.get("map", "prop.b").set(new ValueExpression("${test.prop.b}")); node.get("map", "prop.c").set(new ValueExpression("${test.prop.c}")); node.get("list").add("one"); node.get("list").add(new ValueExpression("${test.prop.two}")); node.get("list").add(new ValueExpression("${test.prop.three}")); node.get("plainprop").set("plain", "plain"); node.get("prop").set("test", new ValueExpression("${test.prop.prop}")); return node; } }