/*
* JBoss, Home of Professional Open Source
* Copyright 2015, Red Hat, Inc., and individual contributors as indicated
* by the @authors tag.
*
* Licensed 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.jboss.as.controller.operation.global;
import static org.jboss.as.controller.SimpleAttributeDefinitionBuilder.create;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.COMPOSITE;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.STEPS;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.VALUE;
import java.util.List;
import java.util.Map;
import org.jboss.as.controller.AbstractAddStepHandler;
import org.jboss.as.controller.AbstractWriteAttributeHandler;
import org.jboss.as.controller.AttributeDefinition;
import org.jboss.as.controller.CompositeOperationHandler;
import org.jboss.as.controller.ExpressionResolver;
import org.jboss.as.controller.ManagementModel;
import org.jboss.as.controller.ModelOnlyWriteAttributeHandler;
import org.jboss.as.controller.ObjectListAttributeDefinition;
import org.jboss.as.controller.ObjectTypeAttributeDefinition;
import org.jboss.as.controller.OperationContext;
import org.jboss.as.controller.OperationFailedException;
import org.jboss.as.controller.OperationStepHandler;
import org.jboss.as.controller.PathAddress;
import org.jboss.as.controller.PropertiesAttributeDefinition;
import org.jboss.as.controller.ReloadRequiredRemoveStepHandler;
import org.jboss.as.controller.ResourceBuilder;
import org.jboss.as.controller.ResourceDefinition;
import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
import org.jboss.as.controller.StringListAttributeDefinition;
import org.jboss.as.controller.descriptions.NonResolvingResourceDescriptionResolver;
import org.jboss.as.controller.operations.global.GlobalNotifications;
import org.jboss.as.controller.operations.global.GlobalOperationHandlers;
import org.jboss.as.controller.registry.ManagementResourceRegistration;
import org.jboss.as.controller.test.AbstractControllerTestBase;
import org.jboss.dmr.ModelNode;
import org.jboss.dmr.ModelType;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
/**
* @author Tomaz Cerar (c) 2015 Red Hat Inc.
*/
public class EnhancedSyntaxTestCase extends AbstractControllerTestBase {
private static final StringListAttributeDefinition LIST_ATTRIBUTE = new StringListAttributeDefinition.Builder("my-list-attribute")
.setAllowDuplicates(false)
.setAllowNull(true)
.build();
private static final StringListAttributeDefinition RUNTIME_LIST_ATTRIBUTE = new StringListAttributeDefinition.Builder("runtime-list-attribute")
.setAllowNull(true)
.setStorageRuntime()
.build();
private static final PropertiesAttributeDefinition MAP_ATTRIBUTE = new PropertiesAttributeDefinition.Builder("map-attribute", true)
.setAllowNull(true)
.build();
private static final PropertiesAttributeDefinition RUNTIME_MAP_ATTRIBUTE = new PropertiesAttributeDefinition.Builder("runtime-map-attribute", true)
.setAllowNull(true)
.setStorageRuntime()
.build();
private static final AttributeDefinition ATTR_1 = create("attr1", ModelType.STRING)
.setAllowNull(true)
.build();
private static final AttributeDefinition ATTR_2 = create("attr2", ModelType.BOOLEAN)
.setAllowNull(false)
.build();
private static final ObjectTypeAttributeDefinition COMPLEX_ATTRIBUTE = ObjectTypeAttributeDefinition.Builder.of("complex-attribute", ATTR_1, ATTR_2, MAP_ATTRIBUTE, RUNTIME_MAP_ATTRIBUTE).build();
private static final ObjectListAttributeDefinition OBJECT_LIST = ObjectListAttributeDefinition.Builder.of("object-list", COMPLEX_ATTRIBUTE).setAllowNull(true).build();
private static final ObjectTypeAttributeDefinition COMPLEX_ATTRIBUTE2 = ObjectTypeAttributeDefinition.Builder.of("complex-attribute2", OBJECT_LIST).build();
private static final AttributeDefinition NORMAL_LOOKING_EXTENDED = new SimpleAttributeDefinitionBuilder("normal.looking.extended", ModelType.STRING, true).build();
private static PathAddress TEST_ADDRESS = PathAddress.pathAddress("subsystem", "test");
private static ModelNode runtimeListAttributeValue;
private static ModelNode runtimeMapAttributeValue;
@Override
protected void initModel(ManagementModel managementModel) {
ManagementResourceRegistration rootRegistration = managementModel.getRootResourceRegistration();
// register the global operations to be able to call :read-attribute and :write-attribute
GlobalOperationHandlers.registerGlobalOperations(rootRegistration, processType);
// register the global notifications so there is no warning that emitted notifications are not described by the resource.
GlobalNotifications.registerGlobalNotifications(rootRegistration, processType);
rootRegistration.registerOperationHandler(CompositeOperationHandler.DEFINITION, CompositeOperationHandler.INSTANCE);
ResourceDefinition profileDefinition = createDummyProfileResourceDefinition();
rootRegistration.registerSubModel(profileDefinition);
}
private static ResourceDefinition createDummyProfileResourceDefinition() {
return ResourceBuilder.Factory.create(TEST_ADDRESS.getElement(0),
new NonResolvingResourceDescriptionResolver())
.setAddOperation(new AbstractAddStepHandler() {
@Override
protected void populateModel(ModelNode operation, ModelNode model) throws OperationFailedException {
LIST_ATTRIBUTE.validateAndSet(operation, model);
RUNTIME_LIST_ATTRIBUTE.validateAndSet(operation, model);
MAP_ATTRIBUTE.validateAndSet(operation, model);
RUNTIME_MAP_ATTRIBUTE.validateAndSet(operation, model);
COMPLEX_ATTRIBUTE.validateAndSet(operation, model);
OBJECT_LIST.validateAndSet(operation, model);
COMPLEX_ATTRIBUTE2.validateAndSet(operation, model);
NORMAL_LOOKING_EXTENDED.validateAndSet(operation, model);
}
})
.setRemoveOperation(ReloadRequiredRemoveStepHandler.INSTANCE)
.addReadWriteAttribute(LIST_ATTRIBUTE, null, new ModelOnlyWriteAttributeHandler(LIST_ATTRIBUTE))
.addReadWriteAttribute(RUNTIME_LIST_ATTRIBUTE, new OperationStepHandler() {
@Override
public void execute(OperationContext context, ModelNode operation) throws OperationFailedException {
context.addStep((context1, operation1) -> context.getResult().set(runtimeListAttributeValue),
OperationContext.Stage.RUNTIME);
}
}, new AbstractWriteAttributeHandler(RUNTIME_LIST_ATTRIBUTE) {
@Override
protected boolean applyUpdateToRuntime(OperationContext context, ModelNode operation, String attributeName, ModelNode resolvedValue, ModelNode currentValue, HandbackHolder handbackHolder) throws OperationFailedException {
runtimeListAttributeValue = operation.get(VALUE);
return false;
}
@Override
protected void revertUpdateToRuntime(OperationContext context, ModelNode operation, String attributeName, ModelNode valueToRestore, ModelNode valueToRevert, Object handback) throws OperationFailedException {
}
})
.addReadWriteAttribute(MAP_ATTRIBUTE, null, new ModelOnlyWriteAttributeHandler(MAP_ATTRIBUTE))
.addReadWriteAttribute(RUNTIME_MAP_ATTRIBUTE, new OperationStepHandler() {
@Override
public void execute(OperationContext context, ModelNode operation) throws OperationFailedException {
context.addStep((context1, operation1) -> context.getResult().set(runtimeMapAttributeValue),
OperationContext.Stage.RUNTIME);
}
}, new AbstractWriteAttributeHandler(RUNTIME_MAP_ATTRIBUTE) {
@Override
protected boolean applyUpdateToRuntime(OperationContext context, ModelNode operation, String attributeName, ModelNode resolvedValue, ModelNode currentValue, HandbackHolder handbackHolder) throws OperationFailedException {
runtimeMapAttributeValue = operation.get(VALUE);
return false;
}
@Override
protected void revertUpdateToRuntime(OperationContext context, ModelNode operation, String attributeName, ModelNode valueToRestore, ModelNode valueToRevert, Object handback) throws OperationFailedException {
}
}).addReadWriteAttribute(COMPLEX_ATTRIBUTE, null, new ModelOnlyWriteAttributeHandler(COMPLEX_ATTRIBUTE))
.addReadWriteAttribute(OBJECT_LIST, null, new ModelOnlyWriteAttributeHandler(OBJECT_LIST))
.addReadWriteAttribute(COMPLEX_ATTRIBUTE2, null, new ModelOnlyWriteAttributeHandler(COMPLEX_ATTRIBUTE2))
.addReadWriteAttribute(NORMAL_LOOKING_EXTENDED, null, new ModelOnlyWriteAttributeHandler(NORMAL_LOOKING_EXTENDED))
.build();
}
/*
Map read enhancements
# return value of map-attribute with key "myKey"
:read-attribute(name=map-attribute.myKey)
List read enhancements
# return element under index 5 of list-attribute
:read-attribute(name=list-attribute[5])
*/
@Before
public void setup() throws OperationFailedException {
executeCheckNoFailure(createOperation("add", TEST_ADDRESS));
runtimeListAttributeValue = new ModelNode();
runtimeMapAttributeValue = new ModelNode();
}
@After
public void cleanup() throws OperationFailedException {
executeCheckNoFailure(createOperation("remove", TEST_ADDRESS));
}
@Test
public void testReadAttribute() throws OperationFailedException {
ModelNode op = createOperation("map-put", TEST_ADDRESS);
op.get("name").set(MAP_ATTRIBUTE.getName());
op.get("key").set("map-key");
op.get("value").set("map-value");
executeCheckNoFailure(op);
op = createOperation("map-get", TEST_ADDRESS);
op.get("name").set(MAP_ATTRIBUTE.getName());
op.get("key").set("map-key");
Assert.assertEquals("map-value", executeForResult(op).asString());
// return value of map-attribute with key "myKey"
// :read-attribute(name=map-attribute.myKey)
op = createOperation("read-attribute", TEST_ADDRESS);
op.get("name").set(MAP_ATTRIBUTE.getName() + ".map-key");
Assert.assertEquals("map-value", executeForResult(op).asString());
op.get("name").set(MAP_ATTRIBUTE.getName() + ".wrong-key");
executeForFailure(op);
//test list elements
op = createOperation("list-add", TEST_ADDRESS);
op.get("name").set(LIST_ATTRIBUTE.getName());
op.get("value").set("value1");
executeCheckNoFailure(op);
//add second value
op.get("value").set("value2");
executeCheckNoFailure(op);
op = createOperation("read-attribute", TEST_ADDRESS);
op.get("name").set(LIST_ATTRIBUTE.getName());
Assert.assertTrue(executeForResult(op).isDefined());
// return value of list-attribute on index 0
// :read-attribute(name=map-attribute.myKey)
op = createOperation("read-attribute", TEST_ADDRESS);
op.get("name").set(LIST_ATTRIBUTE.getName() + "[0]");
Assert.assertEquals("value1", executeForResult(op).asString());
op.get("name").set(LIST_ATTRIBUTE.getName() + "[1]");
Assert.assertEquals("value2", executeForResult(op).asString());
}
@Test
public void testComplexAttributes() throws OperationFailedException {
//test set
ModelNode op = createOperation("write-attribute", TEST_ADDRESS);
op.get("name").set(COMPLEX_ATTRIBUTE.getName());
ModelNode value = new ModelNode();
value.get(ATTR_1.getName()).set("attr1-string");
value.get(ATTR_2.getName()).set(true);
op.get("value").set(value);
executeCheckNoFailure(op);
//test read-attribute(name=complex-attribute.attr1)
op = createOperation("read-attribute", TEST_ADDRESS);
op.get("name").set(COMPLEX_ATTRIBUTE.getName() + "." + ATTR_1.getName());
Assert.assertEquals("attr1-string", executeForResult(op).asString());
//test read-attribute(name=complex-attribute.attr2)
op = createOperation("read-attribute", TEST_ADDRESS);
op.get("name").set(COMPLEX_ATTRIBUTE.getName() + "." + ATTR_2.getName());
Assert.assertTrue(executeForResult(op).asBoolean());
//test List<Object>
op = createOperation("write-attribute", TEST_ADDRESS);
op.get("name").set(OBJECT_LIST.getName());
value = new ModelNode();
for (int i = 0; i <= 5; i++) {
ModelNode item = value.add();
item.get(ATTR_1.getName()).set("value" + i);
item.get(ATTR_2.getName()).set(true);
}
op.get("value").set(value);
executeCheckNoFailure(op);
//test read-attribute(name=object-list[1])
op = createOperation("read-attribute", TEST_ADDRESS);
op.get("name").set(OBJECT_LIST.getName() + "[1]");
Assert.assertTrue(executeForResult(op).isDefined());
//test read-attribute(name=object-list[1].attr1)
op = createOperation("read-attribute", TEST_ADDRESS);
op.get("name").set(OBJECT_LIST.getName() + "[3].attr1");
Assert.assertEquals("value3", executeForResult(op).asString());
//test read-attribute(name=object-list[-3].attr1)
op = createOperation("read-attribute", TEST_ADDRESS);
op.get("name").set(OBJECT_LIST.getName() + "[-3].attr1");
executeCheckForFailure(op);
//complex attribute with list with complex attributes
op = createOperation("write-attribute", TEST_ADDRESS);
op.get("name").set(COMPLEX_ATTRIBUTE2.getName());
value = new ModelNode();
ModelNode listValue = value.get(OBJECT_LIST.getName());
for (int i = 0; i <= 5; i++) {
ModelNode item = listValue.add();
item.get(ATTR_1.getName()).set("value" + i);
item.get(ATTR_2.getName()).set(true);
ModelNode mapValue = item.get(MAP_ATTRIBUTE.getName());
mapValue.get("key1").set("value1");
mapValue.get("key2").set("value2");
}
op.get("value").set(value);
executeCheckNoFailure(op);
//test read-attribute(name=complex-attribute2.object-list[1].attr1)
op = createOperation("read-attribute", TEST_ADDRESS);
op.get("name").set(COMPLEX_ATTRIBUTE2.getName() + "." + OBJECT_LIST.getName() + "[3].attr1");
Assert.assertEquals("value3", executeForResult(op).asString());
//test :read-attribute(name=complex-attribute2.object-list[1].map-attribute.key1)
op = createOperation("read-attribute", TEST_ADDRESS);
op.get("name").set(COMPLEX_ATTRIBUTE2.getName() + "." + OBJECT_LIST.getName() + "[1].map-attribute.key1");
Assert.assertEquals("value1", executeForResult(op).asString());
//test :map-get(name=complex-attribute2.object-list[1].map-attribute key=key1)
op = createOperation("map-get", TEST_ADDRESS);
op.get("name").set(COMPLEX_ATTRIBUTE2.getName() + "." + OBJECT_LIST.getName() + "[1].map-attribute");
op.get("key").set("key1");
Assert.assertEquals("value1", executeForResult(op).asString());
//test :list-get(name=complex-attribute2.object-list index=1)
op = createOperation("list-get", TEST_ADDRESS);
op.get("name").set(COMPLEX_ATTRIBUTE2.getName() + "." + OBJECT_LIST.getName());
op.get("index").set(1);
Assert.assertEquals(3, executeForResult(op).asList().size()); //there should be 3 attributes on this list element
}
@Test
public void testWriteAttribute() throws OperationFailedException {
//test :write-attribute(name="map-attribute.map-key" value="map-value")
ModelNode op = createOperation("write-attribute", TEST_ADDRESS);
op.get("name").set(MAP_ATTRIBUTE.getName() + ".map-key");
op.get("value").set("map-value");
executeCheckNoFailure(op);
op = createOperation("map-get", TEST_ADDRESS);
op.get("name").set(MAP_ATTRIBUTE.getName());
op.get("key").set("map-key");
Assert.assertEquals("map-value", executeForResult(op).asString());
op = createOperation("write-attribute", TEST_ADDRESS);
op.get("name").set(MAP_ATTRIBUTE.getName() + ".map-key.sub-key"); //invalid and need to fail
op.get("value").set("map-value");
executeForFailure(op);
//test list elements
op = createOperation("write-attribute", TEST_ADDRESS);
op.get("name").set(LIST_ATTRIBUTE.getName() + "[-1]");
op.get("value").set("value1");
executeCheckNoFailure(op);
//add second value
op.get("value").set("value2");
executeCheckNoFailure(op);
op = createOperation("read-attribute", TEST_ADDRESS);
op.get("name").set(LIST_ATTRIBUTE.getName());
ModelNode res = executeForResult(op);
Assert.assertTrue(res.isDefined());
// return value of list-attribute on index 0
// :read-attribute(name=map-attribute.myKey)
op = createOperation("read-attribute", TEST_ADDRESS);
op.get("name").set(LIST_ATTRIBUTE.getName() + "[0]");
Assert.assertEquals("value1", executeForResult(op).asString());
op.get("name").set(LIST_ATTRIBUTE.getName() + "[1]");
Assert.assertEquals("value2", executeForResult(op).asString());
}
@Test
public void testComplexWrite() throws OperationFailedException {
//test write-attribute(name="complex-attribute.attr1, value="attr1-string")
ModelNode op = createOperation("write-attribute", TEST_ADDRESS);
op.get("name").set(COMPLEX_ATTRIBUTE.getName() + "." + ATTR_1.getName());
op.get("value").set("attr1-string");
executeCheckNoFailure(op);
//test write-attribute(name="complex-attribute.attr2, value=true)
op.get("name").set(COMPLEX_ATTRIBUTE.getName() + "." + ATTR_2.getName());
op.get("value").set(true);
executeCheckNoFailure(op);
//test read-attribute(name=complex-attribute.attr1)
op = createOperation("read-attribute", TEST_ADDRESS);
op.get("name").set(COMPLEX_ATTRIBUTE.getName() + "." + ATTR_1.getName());
Assert.assertEquals("attr1-string", executeForResult(op).asString());
//test read-attribute(name=complex-attribute.attr2)
op = createOperation("read-attribute", TEST_ADDRESS);
op.get("name").set(COMPLEX_ATTRIBUTE.getName() + "." + ATTR_2.getName());
Assert.assertTrue(executeForResult(op).asBoolean());
//test List<Object>
op = createOperation("write-attribute", TEST_ADDRESS);
for (int i = 0; i <= 5; i++) {
op.get("name").set(OBJECT_LIST.getName() + "[-1].attr1"); // add new element
op.get("value").set("value"+i);
executeCheckNoFailure(op);
}
//test read-attribute(name=object-list[1])
op = createOperation("read-attribute", TEST_ADDRESS);
op.get("name").set(OBJECT_LIST.getName() + "[1]");
Assert.assertTrue(executeForResult(op).isDefined());
//test read-attribute(name=object-list[1].attr1)
op = createOperation("read-attribute", TEST_ADDRESS);
op.get("name").set(OBJECT_LIST.getName() + "[3].attr1");
Assert.assertEquals("value3", executeForResult(op).asString());
op = createOperation("write-attribute", TEST_ADDRESS);
op.get("name").set(OBJECT_LIST.getName() + "[3].attr1"); // update element on index 3
op.get("value").set("updated");
executeCheckNoFailure(op);
op = createOperation("read-attribute", TEST_ADDRESS);
op.get("name").set(OBJECT_LIST.getName() + "[3].attr1");
Assert.assertEquals("updated", executeForResult(op).asString());
//complex attribute with list with complex attributes
op = createOperation("write-attribute", TEST_ADDRESS);
op.get("name").set(COMPLEX_ATTRIBUTE2.getName());
ModelNode value = new ModelNode();
ModelNode listValue = value.get(OBJECT_LIST.getName());
for (int i = 0; i <= 5; i++) {
ModelNode item = listValue.add();
item.get(ATTR_1.getName()).set("value" + i);
item.get(ATTR_2.getName()).set(true);
ModelNode mapValue = item.get(MAP_ATTRIBUTE.getName());
mapValue.get("key1").set("value1");
mapValue.get("key2").set("value2");
}
op.get("value").set(value);
executeCheckNoFailure(op);
//test read-attribute(name=complex-attribute2.object-list[1].attr1)
op = createOperation("read-attribute", TEST_ADDRESS);
op.get("name").set(COMPLEX_ATTRIBUTE2.getName() + "." + OBJECT_LIST.getName() + "[3].attr1");
Assert.assertEquals("value3", executeForResult(op).asString());
//test :read-attribute(name=complex-attribute2.object-list[1].map-attribute.key1)
op = createOperation("read-attribute", TEST_ADDRESS);
op.get("name").set(COMPLEX_ATTRIBUTE2.getName() + "." + OBJECT_LIST.getName() + "[1].map-attribute.key1");
Assert.assertEquals("value1", executeForResult(op).asString());
//test :write-attribute(name=complex-attribute2.object-list[1].map-attribute.key1)
op = createOperation("write-attribute", TEST_ADDRESS);
op.get("name").set(COMPLEX_ATTRIBUTE2.getName() + "." + OBJECT_LIST.getName() + "[3].map-attribute.key1");
op.get("value").set("updated-value");
executeCheckNoFailure(op);
op = createOperation("read-attribute", TEST_ADDRESS);
op.get("name").set(COMPLEX_ATTRIBUTE2.getName() + "." + OBJECT_LIST.getName() + "[3].map-attribute.key1");
Assert.assertEquals("updated-value", executeForResult(op).asString());
//test :write-attribute(name=complex-attribute2.object-list[-1].map-attribute.key1)
op = createOperation("write-attribute", TEST_ADDRESS);
op.get("name").set(COMPLEX_ATTRIBUTE2.getName() + "." + OBJECT_LIST.getName() + "[-1].map-attribute.key1");
op.get("value").set("added-value");
executeCheckNoFailure(op);
op = createOperation("read-attribute", TEST_ADDRESS);
op.get("name").set(COMPLEX_ATTRIBUTE2.getName() + "." + OBJECT_LIST.getName() + "[6].map-attribute.key1");
Assert.assertEquals("added-value", executeForResult(op).asString());
//test :map-get(name=complex-attribute2.object-list[t].map-attribute key=key1)
op = createOperation("map-get", TEST_ADDRESS);
op.get("name").set(COMPLEX_ATTRIBUTE2.getName() + "." + OBJECT_LIST.getName() + "[6].map-attribute");
op.get("key").set("key1");
Assert.assertEquals("added-value", executeForResult(op).asString());
//test :list-get(name=complex-attribute2.object-list index=5)
op = createOperation("list-get", TEST_ADDRESS);
op.get("name").set(COMPLEX_ATTRIBUTE2.getName() + "." + OBJECT_LIST.getName());
op.get("index").set(1);
Assert.assertEquals(3, executeForResult(op).asList().size()); //there should be 3 attributes on this list element
//test :map-put(name=complex-attribute2.object-list[t].map-attribute key=map-put-key value="map-put-value")
op = createOperation("map-put", TEST_ADDRESS);
op.get("name").set(COMPLEX_ATTRIBUTE2.getName() + "." + OBJECT_LIST.getName() + "[6].map-attribute");
op.get("key").set("map-put-key");
op.get("value").set("map-put-value");
executeCheckNoFailure(op);
op = createOperation("map-get", TEST_ADDRESS);
op.get("name").set(COMPLEX_ATTRIBUTE2.getName() + "." + OBJECT_LIST.getName() + "[6].map-attribute");
op.get("key").set("map-put-key");
Assert.assertEquals("map-put-value", executeForResult(op).asString());
}
@Test
public void testNormalAttributeLookingExtended() throws Exception {
final ModelNode wa = createOperation("write-attribute", TEST_ADDRESS);
wa.get("name").set(NORMAL_LOOKING_EXTENDED.getName());
wa.get("value").set("test123");
executeCheckNoFailure(wa);
final ModelNode ra = createOperation("read-attribute", TEST_ADDRESS);
ra.get("name").set(NORMAL_LOOKING_EXTENDED.getName());
Assert.assertEquals("test123", executeForResult(ra).asString());
executeCheckNoFailure(createOperation("remove", TEST_ADDRESS));
final ModelNode add = createOperation("add", TEST_ADDRESS);
add.get(NORMAL_LOOKING_EXTENDED.getName()).set("test456");
executeCheckNoFailure(add);
Assert.assertEquals("test456", executeForResult(ra).asString());
}
@Test
public void testComplexListValue()throws Exception{
//test List<Object>
ModelNode op = createOperation("list-add", TEST_ADDRESS);
op.get("name").set(OBJECT_LIST.getName());
ModelNode value = new ModelNode();
value.get(ATTR_1.getName()).set("complex value");
value.get(ATTR_2.getName()).set(true);
op.get("value").set(value);
executeCheckNoFailure(op);
ModelNode readOp = createOperation("read-attribute", TEST_ADDRESS);
readOp.get("name").set(OBJECT_LIST.getName());
ModelNode result = executeForResult(readOp);
Assert.assertEquals(1, result.asList().size());
executeCheckNoFailure(op);
result = executeForResult(readOp);
Assert.assertEquals(2, result.asList().size());
}
@Test
public void testRuntimeMapAttributeRead() throws Exception {
ModelNode op = createOperation("map-put", TEST_ADDRESS);
op.get("name").set(RUNTIME_MAP_ATTRIBUTE.getName());
op.get("key").set("map-key");
op.get("value").set("map-value");
executeCheckNoFailure(op);
// :map-get(name=runtime-map-attribute, key=map-key)
op = createOperation("map-get", TEST_ADDRESS);
op.get("name").set(RUNTIME_MAP_ATTRIBUTE.getName());
op.get("key").set("map-key");
Assert.assertEquals("map-value", executeForResult(op).asString());
// :read-attribute(name=runtime-map-attribute)
op = createOperation("read-attribute", TEST_ADDRESS);
op.get("name").set(RUNTIME_MAP_ATTRIBUTE.getName());
Assert.assertEquals("{\"map-key\" => \"map-value\"}", executeForResult(op).asString());
// :read-attribute(name=runtime-map-attribute.map-key)
op = createOperation("read-attribute", TEST_ADDRESS);
op.get("name").set(RUNTIME_MAP_ATTRIBUTE.getName() + ".map-key");
Assert.assertEquals("map-value", executeForResult(op).asString());
op.get("name").set(RUNTIME_MAP_ATTRIBUTE.getName() + ".wrong-key");
executeForFailure(op);
}
@Test
public void testRuntimeMapAttributeWrite() throws Exception {
// :write-attribute(name=runtime-map-attribute.map-key)
ModelNode op = createOperation("write-attribute", TEST_ADDRESS);
op.get("name").set(RUNTIME_MAP_ATTRIBUTE.getName() + ".map-key");
op.get("value").set("map-value");
executeCheckNoFailure(op);
Map<String, String> map = PropertiesAttributeDefinition.unwrapModel(ExpressionResolver.TEST_RESOLVER, runtimeMapAttributeValue);
Assert.assertEquals(1, map.size());
Assert.assertEquals("map-value", map.get("map-key"));
op = createOperation("write-attribute", TEST_ADDRESS);
op.get("name").set(RUNTIME_MAP_ATTRIBUTE.getName() + ".map-key2");
op.get("value").set("map-value2");
executeCheckNoFailure(op);
map = PropertiesAttributeDefinition.unwrapModel(ExpressionResolver.TEST_RESOLVER, runtimeMapAttributeValue);
Assert.assertEquals(2, map.size());
Assert.assertEquals("map-value", map.get("map-key"));
Assert.assertEquals("map-value2", map.get("map-key2"));
}
@Test
public void testRuntimeListAttributeRead() throws Exception {
ModelNode op = createOperation("list-add", TEST_ADDRESS);
op.get("name").set(RUNTIME_LIST_ATTRIBUTE.getName());
op.get("value").set("list-value");
executeCheckNoFailure(op);
op = createOperation("list-get", TEST_ADDRESS);
op.get("name").set(RUNTIME_LIST_ATTRIBUTE.getName());
op.get("index").set(0);
Assert.assertEquals("list-value", executeForResult(op).asString());
// :read-attribute(name=runtime-list-attribute)
op = createOperation("read-attribute", TEST_ADDRESS);
op.get("name").set(RUNTIME_LIST_ATTRIBUTE.getName());
Assert.assertEquals("[\"list-value\"]", executeForResult(op).asString());
// :read-attribute(name=runtime-list-attribute[0])
op = createOperation("read-attribute", TEST_ADDRESS);
op.get("name").set(RUNTIME_LIST_ATTRIBUTE.getName() + "[0]");
Assert.assertEquals("list-value", executeForResult(op).asString());
// :read-attribute(name=runtime-list-attribute[1])
op.get("name").set(RUNTIME_LIST_ATTRIBUTE.getName() + "[1]"); // index out of range
Assert.assertEquals(ModelType.UNDEFINED, executeForResult(op).getType());
}
@Test
public void testRuntimeListAttributeWrite() throws Exception {
ModelNode op = createOperation("list-add", TEST_ADDRESS);
op.get("name").set(RUNTIME_LIST_ATTRIBUTE.getName());
op.get("value").set("list-value");
executeCheckNoFailure(op);
List<String> list = StringListAttributeDefinition.unwrapValue(ExpressionResolver.TEST_RESOLVER, runtimeListAttributeValue);
Assert.assertEquals(1, list.size());
Assert.assertEquals("list-value", list.get(0));
// :write-attribute(name=runtime-list-attribute[-1])
op = createOperation("write-attribute", TEST_ADDRESS);
op.get("name").set(RUNTIME_LIST_ATTRIBUTE.getName() + "[-1]");
op.get("value").set("list-value2");
executeCheckNoFailure(op);
list = StringListAttributeDefinition.unwrapValue(ExpressionResolver.TEST_RESOLVER, runtimeListAttributeValue);
Assert.assertEquals(2, list.size());
Assert.assertEquals("list-value", list.get(0));
Assert.assertEquals("list-value2", list.get(1));
// :write-attribute(name=runtime-list-attribute[0])
op = createOperation("write-attribute", TEST_ADDRESS);
op.get("name").set(RUNTIME_LIST_ATTRIBUTE.getName() + "[0]");
op.get("value").set("list-value3");
executeCheckNoFailure(op);
list = StringListAttributeDefinition.unwrapValue(ExpressionResolver.TEST_RESOLVER, runtimeListAttributeValue);
Assert.assertEquals(2, list.size());
Assert.assertEquals("list-value3", list.get(0));
Assert.assertEquals("list-value2", list.get(1));
}
@Test
public void testCompositeListWrite() throws Exception {
performCompositeListWrite(LIST_ATTRIBUTE.getName());
performCompositeListWrite(RUNTIME_LIST_ATTRIBUTE.getName());
}
private void performCompositeListWrite(String attrName) throws Exception {
ModelNode compositeOp = createOperation(COMPOSITE, PathAddress.EMPTY_ADDRESS);
ModelNode op = createOperation("write-attribute", TEST_ADDRESS);
op.get("name").set(attrName + "[-1]");
op.get("value").set("list-value");
compositeOp.get(STEPS).add(op);
op = createOperation("write-attribute", TEST_ADDRESS);
op.get("name").set(attrName + "[-1]");
op.get("value").set("list-value2");
compositeOp.get(STEPS).add(op);
executeCheckNoFailure(compositeOp);
op = createOperation("read-attribute", TEST_ADDRESS);
op.get("name").set(attrName);
ModelNode result = executeForResult(op);
Assert.assertEquals(2, result.asList().size());
Assert.assertEquals("list-value", result.asList().get(0).asString());
Assert.assertEquals("list-value2", result.asList().get(1).asString());
}
@Test
public void testCompositeMapWrite() throws Exception {
performCompositeMapWrite(MAP_ATTRIBUTE.getName());
performCompositeMapWrite(RUNTIME_MAP_ATTRIBUTE.getName());
}
private void performCompositeMapWrite(String attrName) throws Exception {
ModelNode compositeOp = createOperation(COMPOSITE, PathAddress.EMPTY_ADDRESS);
ModelNode op = createOperation("write-attribute", TEST_ADDRESS);
op.get("name").set(attrName + ".map-key");
op.get("value").set("map-value");
compositeOp.get(STEPS).add(op);
op = createOperation("write-attribute", TEST_ADDRESS);
op.get("name").set(attrName + ".map-key2");
op.get("value").set("map-value2");
compositeOp.get(STEPS).add(op);
executeCheckNoFailure(compositeOp);
op = createOperation("read-attribute", TEST_ADDRESS);
op.get("name").set(attrName);
ModelNode result = executeForResult(op);
Assert.assertEquals(2, result.keys().size());
Assert.assertEquals("map-value", result.get("map-key").asString());
Assert.assertEquals("map-value2", result.get("map-key2").asString());
}
}