blob: 85503ae760a3ad09879ce0594d9b5438fbc0016f [file] [log] [blame]
/*
*
* 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.server.model.testmodels.hierarchy;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.google.common.collect.Lists;
import org.apache.qpid.server.configuration.IllegalConfigurationException;
import org.apache.qpid.server.model.*;
import org.apache.qpid.server.model.testmodels.hierarchy.TestCar.Colour;
import org.apache.qpid.server.plugin.ConfiguredObjectAttributeInjector;
import org.apache.qpid.test.utils.QpidTestCase;
public class InjectedAttributeTest extends QpidTestCase
{
private static class TestInjector implements ConfiguredObjectAttributeInjector
{
private Collection<ConfiguredObjectInjectedAttribute<?, ?>> _injectedAttributes;
private Collection<ConfiguredObjectInjectedStatistic<?, ?>> _injectedStatistics;
private Collection<ConfiguredObjectInjectedOperation<?>> _injectedOperations;
private TestInjector(ConfiguredObjectInjectedAttribute<?, ?>... attributes)
{
this(Arrays.asList(attributes),
Collections.<ConfiguredObjectInjectedStatistic<?, ?>>emptyList(),
Collections.<ConfiguredObjectInjectedOperation<?>>emptyList());
}
private TestInjector(ConfiguredObjectInjectedStatistic<?, ?>... statistics)
{
this(Collections.<ConfiguredObjectInjectedAttribute<?, ?>>emptyList(),
Arrays.asList(statistics),
Collections.<ConfiguredObjectInjectedOperation<?>>emptyList());
}
private TestInjector(ConfiguredObjectInjectedOperation<?>... operations)
{
this(Collections.<ConfiguredObjectInjectedAttribute<?, ?>>emptyList(),
Collections.<ConfiguredObjectInjectedStatistic<?, ?>>emptyList(),
Arrays.asList(operations));
}
private TestInjector(final Collection<ConfiguredObjectInjectedAttribute<?, ?>> injectedAttributes,
final Collection<ConfiguredObjectInjectedStatistic<?, ?>> injectedStatistics,
final Collection<ConfiguredObjectInjectedOperation<?>> injectedOperations)
{
_injectedAttributes = injectedAttributes;
_injectedStatistics = injectedStatistics;
_injectedOperations = injectedOperations;
}
@Override
public Collection<ConfiguredObjectInjectedAttribute<?, ?>> getInjectedAttributes()
{
return _injectedAttributes;
}
@Override
public Collection<ConfiguredObjectInjectedStatistic<?, ?>> getInjectedStatistics()
{
return _injectedStatistics;
}
@Override
public Collection<ConfiguredObjectInjectedOperation<?>> getInjectedOperations()
{
return _injectedOperations;
}
@Override
public String getType()
{
return "TEST";
}
}
public void testInjectedSettableAttributeWithDefault()
{
InjectedAttributeOrStatistic.TypeValidator validator =
new InjectedAttributeOrStatistic.TypeValidator()
{
@Override
public boolean appliesToType(final Class<? extends ConfiguredObject<?>> type)
{
return TestCar.class.isAssignableFrom(type);
}
};
final ConfiguredSettableInjectedAttribute<?, ?> attrInjector =
new ConfiguredSettableInjectedAttribute<TestCar<?>, Integer>("meaningOfLife",
Integer.class,
Integer.class,
"42",
false,
true,
false,
"",
false,
"",
"",
null,
"", validator, Initialization.none);
TestModel model = new TestModel(null, new TestInjector(attrInjector));
TestCar<?> testCar = new TestStandardCarImpl(Collections.<String,Object>singletonMap("name", "Arthur"), model);
assertEquals("incorrect attribute value", Integer.valueOf(42), testCar.getAttribute("meaningOfLife"));
testCar.setAttributes(Collections.<String,Object>singletonMap("meaningOfLife", 54));
assertEquals("incorrect attribute value", Integer.valueOf(54), testCar.getAttribute("meaningOfLife"));
Map<String, String> context = new HashMap<>(testCar.getContext());
context.put("varieties","57");
testCar.setAttributes(Collections.<String,Object>singletonMap("context", context));
testCar.setAttributes(Collections.<String,Object>singletonMap("meaningOfLife", "${varieties}"));
assertEquals("incorrect attribute value", Integer.valueOf(57), testCar.getAttribute("meaningOfLife"));
}
public void testInjectedSettableAttributeValidValues()
{
InjectedAttributeOrStatistic.TypeValidator validator =
new InjectedAttributeOrStatistic.TypeValidator()
{
@Override
public boolean appliesToType(final Class<? extends ConfiguredObject<?>> type)
{
return TestCar.class.isAssignableFrom(type);
}
};
final ConfiguredSettableInjectedAttribute<?, ?> attrInjector =
new ConfiguredSettableInjectedAttribute<TestCar<?>, Integer>("meaningOfLife",
Integer.class,
Integer.class,
"42",
false,
true,
false,
"",
false,
"",
"",
new String[] { "42", "49" },
"", validator, Initialization.none);
TestModel model = new TestModel(null, new TestInjector(attrInjector));
TestCar<?> testCar = new TestStandardCarImpl(Collections.<String,Object>singletonMap("name", "Arthur"), model);
assertEquals("incorrect attribute value", Integer.valueOf(42), testCar.getAttribute("meaningOfLife"));
testCar.setAttributes(Collections.<String,Object>singletonMap("meaningOfLife", 49));
assertEquals("incorrect attribute value", Integer.valueOf(49), testCar.getAttribute("meaningOfLife"));
try
{
testCar.setAttributes(Collections.<String, Object>singletonMap("meaningOfLife", 54));
fail("Should not be able to set attribute value to 54 as it is not a valid value");
}
catch (IllegalConfigurationException e)
{
// pass
}
}
public void testInjectedSettableAttributeEnumValidValues_Unrestricted()
{
final ConfiguredSettableInjectedAttribute<?, ?> attribute =
new ConfiguredSettableInjectedAttribute<TestCar<?>, Colour>("trimColour",
Colour.class,
Colour.class,
Colour.BLACK.name(),
false,
true,
false,
"",
false,
"",
"",
null,
"",
null, Initialization.none);
assertEquals("The attribute's valid values should match the set of the enum",
Lists.newArrayList("BLACK", "RED", "BLUE", "GREY"),
attribute.validValues());
}
public void testInjectedSettableAttributeEnumValidValues_RestrictedSet()
{
final ConfiguredSettableInjectedAttribute<?, ?> attribute =
new ConfiguredSettableInjectedAttribute<TestCar<?>, Colour>("trimColour",
Colour.class,
Colour.class,
Colour.BLACK.name(),
false,
true,
false,
"",
false,
"",
"",
new String[] {Colour.GREY.name(), Colour.BLACK.name()},
"",
null, Initialization.none);
assertEquals("The attribute's valid values should match the restricted set defined on the attribute itself",
Lists.newArrayList("GREY", "BLACK"),
attribute.validValues());
}
public void testInjectedDerivedAttribute() throws Exception
{
Method method = InjectedAttributeTest.class.getDeclaredMethod("getMeaningOfLife", TestCar.class);
InjectedAttributeOrStatistic.TypeValidator validator =
new InjectedAttributeOrStatistic.TypeValidator()
{
@Override
public boolean appliesToType(final Class<? extends ConfiguredObject<?>> type)
{
return TestCar.class.isAssignableFrom(type);
}
};
final ConfiguredDerivedInjectedAttribute<?, ?> attrInjector =
new ConfiguredDerivedInjectedAttribute<TestCar<?>, Integer>("meaningOfLife",
method,
null, false,
false,
"",
false,
"",
"",
validator);
TestModel model = new TestModel(null, new TestInjector(attrInjector));
TestCar<?> testCar = new TestStandardCarImpl(Collections.<String,Object>singletonMap("name", "Arthur"), model);
assertEquals("incorrect attribute value", Integer.valueOf(42), testCar.getAttribute("meaningOfLife"));
}
public void testInjectedStatistic() throws Exception
{
Method method = InjectedAttributeTest.class.getDeclaredMethod("getMeaningOfLife", TestCar.class);
InjectedAttributeOrStatistic.TypeValidator validator =
new InjectedAttributeOrStatistic.TypeValidator()
{
@Override
public boolean appliesToType(final Class<? extends ConfiguredObject<?>> type)
{
return TestCar.class.isAssignableFrom(type);
}
};
final ConfiguredObjectInjectedStatistic<?, ?> statInjector =
new ConfiguredObjectInjectedStatistic<TestCar<?>, Integer>("meaningOfLife",
method,
null, "",
validator,
StatisticUnit.COUNT,
StatisticType.POINT_IN_TIME,
"What is 6 x 9?");
TestModel model = new TestModel(null, new TestInjector(statInjector));
TestCar<?> testCar = new TestStandardCarImpl(Collections.<String,Object>singletonMap("name", "Arthur"), model);
final Map<String, Object> statistics = testCar.getStatistics();
assertEquals("incorrect number of statistics", 1, statistics.size());
assertEquals("incorrect statistic value", 42, statistics.get("meaningOfLife"));
}
public void testInjectedStatisticWithParameters() throws Exception
{
Method method = InjectedAttributeTest.class.getDeclaredMethod("getWhatISent", TestCar.class, Integer.TYPE);
InjectedAttributeOrStatistic.TypeValidator validator =
new InjectedAttributeOrStatistic.TypeValidator()
{
@Override
public boolean appliesToType(final Class<? extends ConfiguredObject<?>> type)
{
return TestCar.class.isAssignableFrom(type);
}
};
final ConfiguredObjectInjectedStatistic<?, ?> statInjector1 =
new ConfiguredObjectInjectedStatistic<TestCar<?>, Integer>("whatISent1",
method,
new Object[] { 1 }, "",
validator,
StatisticUnit.COUNT,
StatisticType.POINT_IN_TIME,
"One");
final ConfiguredObjectInjectedStatistic<?, ?> statInjector2 =
new ConfiguredObjectInjectedStatistic<TestCar<?>, Integer>("whatISent2",
method,
new Object[] { 2 }, "",
validator,
StatisticUnit.COUNT,
StatisticType.POINT_IN_TIME,
"Two");
TestModel model = new TestModel(null, new TestInjector(statInjector1, statInjector2));
TestCar<?> testCar = new TestStandardCarImpl(Collections.<String,Object>singletonMap("name", "Arthur"), model);
final Map<String, Object> statistics = testCar.getStatistics();
assertEquals("incorrect number of statistics", 2, statistics.size());
assertEquals("incorrect statistic value", 1, statistics.get("whatISent1"));
assertEquals("incorrect statistic value", 2, statistics.get("whatISent2"));
}
public void testInjectedOperation() throws Exception
{
Method method = InjectedAttributeTest.class.getDeclaredMethod("fly", TestCar.class, Integer.TYPE);
InjectedAttributeOrStatistic.TypeValidator validator =
new InjectedAttributeOrStatistic.TypeValidator()
{
@Override
public boolean appliesToType(final Class<? extends ConfiguredObject<?>> type)
{
return TestCar.class.isAssignableFrom(type);
}
};
final OperationParameter[] params = new OperationParameter[1];
params[0] = new OperationParameterFromInjection("height", Integer.TYPE, Integer.TYPE, "", "", new String[0]);
final ConfiguredObjectInjectedOperation<?> operationInjector =
new ConfiguredObjectInjectedOperation<TestCar<?>>("fly", "", true,
false,
"", params, method, null, validator);
TestModel model = new TestModel(null, new TestInjector(operationInjector));
TestCar testCar = new TestStandardCarImpl(Collections.<String,Object>singletonMap("name", "Arthur"), model);
final Map<String, ConfiguredObjectOperation<?>> allOperations =
model.getTypeRegistry().getOperations(testCar.getClass());
assertTrue("Operation fly(int height) is missing", allOperations.containsKey("fly"));
final ConfiguredObjectOperation foundOperation = allOperations.get("fly");
Object result = foundOperation.perform(testCar, Collections.<String, Object>singletonMap("height", 0)
);
assertEquals("Car should be able to fly at 0m", Boolean.TRUE, result);
result = foundOperation.perform(testCar, Collections.<String, Object>singletonMap("height", 5000)
);
assertEquals("Car should not be able to fly at 5000m", Boolean.FALSE, result);
}
public void testInjectedOperationWithStaticParams() throws Exception
{
Method method = InjectedAttributeTest.class.getDeclaredMethod("saySomething", TestCar.class, String.class, Integer.TYPE);
InjectedAttributeOrStatistic.TypeValidator validator =
new InjectedAttributeOrStatistic.TypeValidator()
{
@Override
public boolean appliesToType(final Class<? extends ConfiguredObject<?>> type)
{
return TestCar.class.isAssignableFrom(type);
}
};
final OperationParameter[] params = new OperationParameter[1];
params[0] = new OperationParameterFromInjection("count", Integer.TYPE, Integer.TYPE, "", "", new String[0]);
final ConfiguredObjectInjectedOperation<?> hello =
new ConfiguredObjectInjectedOperation<TestCar<?>>("sayHello", "", true,
false,
"", params, method, new String[] { "Hello"}, validator
);
final ConfiguredObjectInjectedOperation<?> goodbye =
new ConfiguredObjectInjectedOperation<TestCar<?>>("sayGoodbye", "", true,
false,
"",
params, method, new String[] { "Goodbye"}, validator
);
TestModel model = new TestModel(null, new TestInjector(hello, goodbye));
TestCar testCar = new TestStandardCarImpl(Collections.<String,Object>singletonMap("name", "Arthur"), model);
final Map<String, ConfiguredObjectOperation<?>> allOperations =
model.getTypeRegistry().getOperations(testCar.getClass());
assertTrue("Operation sayHello(int count) is missing", allOperations.containsKey("sayHello"));
assertTrue("Operation sayGoodbye(int count) is missing", allOperations.containsKey("sayGoodbye"));
final ConfiguredObjectOperation helloOperation = allOperations.get("sayHello");
final ConfiguredObjectOperation goodbyeOperation = allOperations.get("sayGoodbye");
Object result = helloOperation.perform(testCar, Collections.<String, Object>singletonMap("count", 3)
);
assertEquals("Car should say 'Hello' 3 times", Arrays.asList("Hello", "Hello", "Hello"), result);
result = goodbyeOperation.perform(testCar, Collections.<String, Object>singletonMap("count", 1)
);
assertEquals("Car say 'Goodbye' once", Collections.singletonList("Goodbye"), result);
}
public static int getMeaningOfLife(TestCar<?> car)
{
return 42;
}
public static int getWhatISent(TestCar<?> car, int whatIsent)
{
return whatIsent;
}
public static boolean fly(TestCar<?> car, int height)
{
return height == 0;
}
public static List<String> saySomething(TestCar<?> car, String whatToSay, int count)
{
List<String> list = new ArrayList<>();
for(int i = 0; i < count; i++)
{
list.add(whatToSay);
}
return list;
}
}