/*
* JBoss, Home of Professional Open Source.
* Copyright 2011, Red Hat, Inc., 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.test.integration.domain.suites;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ADD;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.COMPOSITE;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.CORE_SERVICE;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.HOST;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.INET_ADDRESS;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.INTERFACE;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.NAME;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP_ADDR;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.PLATFORM_MBEAN;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.PROFILE;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.READ_ATTRIBUTE_OPERATION;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.REMOVE;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SCHEMA_LOCATIONS;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SERVER;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SERVER_GROUP;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SOCKET_BINDING_GROUP;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.STEPS;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SYSTEM_PROPERTY;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.TYPE;
import static org.jboss.as.test.integration.domain.management.util.DomainTestSupport.validateFailedResponse;
import static org.jboss.as.test.integration.domain.management.util.DomainTestSupport.validateResponse;
import java.io.IOException;
import org.jboss.as.controller.client.helpers.domain.DomainClient;
import org.jboss.as.controller.operations.common.SchemaLocationAddHandler;
import org.jboss.as.controller.operations.common.SchemaLocationRemoveHandler;
import org.jboss.as.controller.operations.common.Util;
import org.jboss.as.test.integration.domain.management.util.DomainLifecycleUtil;
import org.jboss.as.test.integration.domain.management.util.DomainTestSupport;
import org.jboss.dmr.ModelNode;
import org.jboss.dmr.ModelType;
import org.jboss.dmr.Property;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
/**
* Test of various management operations to confirm they are or are not allowed access.
*
* @author Brian Stansberry (c) 2011 Red Hat Inc.
*/
public class ManagementAccessTestCase {
private static DomainTestSupport testSupport;
private static DomainLifecycleUtil domainMasterLifecycleUtil;
private static DomainLifecycleUtil domainSlaveLifecycleUtil;
private static final String TEST = "mgmt-access-test";
private static final ModelNode ROOT_ADDRESS = new ModelNode().setEmptyList();
private static final ModelNode MASTER_ROOT_ADDRESS = new ModelNode().add(HOST, "master");
private static final ModelNode SLAVE_ROOT_ADDRESS = new ModelNode().add(HOST, "slave");
private static final ModelNode ROOT_PROP_ADDRESS = new ModelNode().add(SYSTEM_PROPERTY, TEST);
private static final ModelNode OTHER_SERVER_GROUP_ADDRESS = new ModelNode().add(SERVER_GROUP, "other-server-group");
private static final ModelNode TEST_SERVER_GROUP_ADDRESS = new ModelNode().add(SERVER_GROUP, "test-server-group");
private static final ModelNode MASTER_INTERFACE_ADDRESS = new ModelNode().set(MASTER_ROOT_ADDRESS).add(INTERFACE, "management");
private static final ModelNode SLAVE_INTERFACE_ADDRESS = new ModelNode().set(SLAVE_ROOT_ADDRESS).add(INTERFACE, "management");
private static final ModelNode MAIN_RUNNING_SERVER_ADDRESS = new ModelNode().add(HOST, "master").add(SERVER, "main-one");
private static final ModelNode MAIN_RUNNING_SERVER_CLASSLOADING_ADDRESS = new ModelNode().set(MAIN_RUNNING_SERVER_ADDRESS).add(CORE_SERVICE, PLATFORM_MBEAN).add(TYPE, "class-loading");
private static final ModelNode OTHER_RUNNING_SERVER_ADDRESS = new ModelNode().add(HOST, "slave").add(SERVER, "other-two");
private static final ModelNode OTHER_RUNNING_SERVER_CLASSLOADING_ADDRESS = new ModelNode().set(OTHER_RUNNING_SERVER_ADDRESS).add(CORE_SERVICE, PLATFORM_MBEAN).add(TYPE, "class-loading");
static {
ROOT_ADDRESS.protect();
MASTER_ROOT_ADDRESS.protect();
SLAVE_ROOT_ADDRESS.protect();
ROOT_PROP_ADDRESS.protect();
OTHER_SERVER_GROUP_ADDRESS.protect();
MASTER_INTERFACE_ADDRESS.protect();
SLAVE_INTERFACE_ADDRESS.protect();
MAIN_RUNNING_SERVER_ADDRESS.protect();
MAIN_RUNNING_SERVER_CLASSLOADING_ADDRESS.protect();
OTHER_RUNNING_SERVER_ADDRESS.protect();
OTHER_RUNNING_SERVER_CLASSLOADING_ADDRESS.protect();
}
@BeforeClass
public static void setupDomain() throws Exception {
testSupport = DomainTestSuite.createSupport(ManagementAccessTestCase.class.getSimpleName());
domainMasterLifecycleUtil = testSupport.getDomainMasterLifecycleUtil();
domainSlaveLifecycleUtil = testSupport.getDomainSlaveLifecycleUtil();
}
@AfterClass
public static void tearDownDomain() throws Exception {
testSupport = null;
domainMasterLifecycleUtil = null;
domainSlaveLifecycleUtil = null;
DomainTestSuite.stopSupport();
}
private DomainClient masterClient;
private DomainClient slaveClient;
@Before
public void setup() throws Exception {
masterClient = domainMasterLifecycleUtil.getDomainClient();
slaveClient = domainSlaveLifecycleUtil.getDomainClient();
}
@After
public void teardown() throws Exception {
masterClient.execute(Util.getEmptyOperation(REMOVE, TEST_SERVER_GROUP_ADDRESS));
masterClient.execute(SchemaLocationRemoveHandler.getRemoveSchemaLocationOperation(ROOT_ADDRESS, "uri"));
masterClient.execute(SchemaLocationRemoveHandler.getRemoveSchemaLocationOperation(MASTER_ROOT_ADDRESS, "uri"));
masterClient.execute(SchemaLocationRemoveHandler.getRemoveSchemaLocationOperation(SLAVE_ROOT_ADDRESS, "uri"));
}
@Test
public void testDomainReadAccess() throws IOException {
// Start with reads of the root resource
ModelNode response = masterClient.execute(getReadAttributeOperation(ROOT_ADDRESS, SCHEMA_LOCATIONS));
ModelNode returnVal = validateResponse(response);
response = slaveClient.execute(getReadAttributeOperation(ROOT_ADDRESS, SCHEMA_LOCATIONS));
ModelNode slaveReturnVal = validateResponse(response);
Assert.assertEquals(returnVal, slaveReturnVal);
// Now try a resource below root
response = masterClient.execute(getReadAttributeOperation(OTHER_SERVER_GROUP_ADDRESS, PROFILE));
returnVal = validateResponse(response);
Assert.assertEquals("other", returnVal.asString());
response = slaveClient.execute(getReadAttributeOperation(OTHER_SERVER_GROUP_ADDRESS, PROFILE));
slaveReturnVal = validateResponse(response);
Assert.assertEquals(returnVal, slaveReturnVal);
}
@Test
public void testCompositeDomainReadAccess() throws IOException {
ModelNode request = getEmptyOperation(COMPOSITE, null);
ModelNode steps = request.get(STEPS);
steps.add(getReadAttributeOperation(ROOT_ADDRESS, SCHEMA_LOCATIONS));
steps.add(getReadAttributeOperation(OTHER_SERVER_GROUP_ADDRESS, PROFILE));
request.protect();
ModelNode response = masterClient.execute(request);
System.out.println(response);
ModelNode returnVal = validateResponse(response);
validateResponse(returnVal.get("step-1"));
ModelNode profile = validateResponse(returnVal.get("step-2"));
Assert.assertEquals("other", profile.asString());
response = slaveClient.execute(request);
System.out.println(response);
ModelNode slaveReturnVal = validateResponse(response);
Assert.assertEquals(returnVal, slaveReturnVal);
}
@Test
public void testHostReadAccess() throws IOException {
// Start with reads of the root resource
ModelNode response = masterClient.execute(getReadAttributeOperation(MASTER_ROOT_ADDRESS, NAME));
ModelNode returnVal = validateResponse(response);
Assert.assertEquals("master", returnVal.asString());
response = slaveClient.execute(getReadAttributeOperation(SLAVE_ROOT_ADDRESS, NAME));
ModelNode slaveReturnVal = validateResponse(response);
Assert.assertEquals("slave", slaveReturnVal.asString());
// Now try a resource below root
response = masterClient.execute(getReadAttributeOperation(MASTER_INTERFACE_ADDRESS, INET_ADDRESS));
returnVal = validateResponse(response);
Assert.assertEquals(ModelType.EXPRESSION, returnVal.getType());
response = slaveClient.execute(getReadAttributeOperation(SLAVE_INTERFACE_ADDRESS, INET_ADDRESS));
slaveReturnVal = validateResponse(response);
Assert.assertEquals(ModelType.EXPRESSION, slaveReturnVal.getType());
response = masterClient.execute(getReadAttributeOperation(SLAVE_INTERFACE_ADDRESS, INET_ADDRESS));
returnVal = validateResponse(response);
Assert.assertEquals(ModelType.EXPRESSION, returnVal.getType());
Assert.assertEquals(returnVal, slaveReturnVal);
// Can't access the master via the slave
response = slaveClient.execute(getReadAttributeOperation(MASTER_ROOT_ADDRESS, NAME));
validateFailedResponse(response);
response = slaveClient.execute(getReadAttributeOperation(MASTER_INTERFACE_ADDRESS, INET_ADDRESS));
validateFailedResponse(response);
}
@Test
public void testCompositeHostReadAccess() throws IOException {
ModelNode masterRequest = getEmptyOperation(COMPOSITE, null);
ModelNode steps = masterRequest.get(STEPS);
steps.add(getReadAttributeOperation(MASTER_ROOT_ADDRESS, NAME));
steps.add(getReadAttributeOperation(MASTER_INTERFACE_ADDRESS, INET_ADDRESS));
masterRequest.protect();
ModelNode response = masterClient.execute(masterRequest);
System.out.println(response);
ModelNode returnVal = validateResponse(response);
ModelNode name = validateResponse(returnVal.get("step-1"));
Assert.assertEquals("master", name.asString());
ModelNode inetAddress = validateResponse(returnVal.get("step-2"));
Assert.assertEquals(ModelType.EXPRESSION, inetAddress.getType());
ModelNode slaveRequest = getEmptyOperation(COMPOSITE, null);
steps = slaveRequest.get(STEPS);
steps.add(getReadAttributeOperation(SLAVE_ROOT_ADDRESS, NAME));
steps.add(getReadAttributeOperation(SLAVE_INTERFACE_ADDRESS, INET_ADDRESS));
masterRequest.protect();
response = slaveClient.execute(slaveRequest);
System.out.println(response);
ModelNode slaveReturnVal = validateResponse(response);
name = validateResponse(slaveReturnVal.get("step-1"));
Assert.assertEquals("slave", name.asString());
inetAddress = validateResponse(slaveReturnVal.get("step-2"));
Assert.assertEquals(ModelType.EXPRESSION, inetAddress.getType());
// Check we get the same thing via the master
response = masterClient.execute(slaveRequest);
returnVal = validateResponse(response);
Assert.assertEquals(returnVal, slaveReturnVal);
// Can't access the master via the slave
response = slaveClient.execute(masterRequest);
validateFailedResponse(response);
}
@Test
public void testCompositeCrossHostReadAccess() throws IOException {
ModelNode masterRequest = getEmptyOperation(COMPOSITE, null);
ModelNode steps = masterRequest.get(STEPS);
steps.add(getReadAttributeOperation(MASTER_ROOT_ADDRESS, NAME));
steps.add(getReadAttributeOperation(MASTER_INTERFACE_ADDRESS, INET_ADDRESS));
steps.add(getReadAttributeOperation(SLAVE_ROOT_ADDRESS, NAME));
steps.add(getReadAttributeOperation(SLAVE_INTERFACE_ADDRESS, INET_ADDRESS));
steps.add(getReadAttributeOperation(MAIN_RUNNING_SERVER_ADDRESS, NAME));
steps.add(getReadAttributeOperation(OTHER_RUNNING_SERVER_ADDRESS, NAME));
masterRequest.protect();
System.out.println(masterRequest);
ModelNode response = masterClient.execute(masterRequest);
System.out.println(response);
ModelNode returnVal = validateResponse(response);
ModelNode name = validateResponse(returnVal.get("step-1"));
Assert.assertEquals("master", name.asString());
ModelNode inetAddress = validateResponse(returnVal.get("step-2"));
Assert.assertEquals(ModelType.EXPRESSION, inetAddress.getType());
name = validateResponse(returnVal.get("step-3"));
Assert.assertEquals("slave", name.asString());
inetAddress = validateResponse(returnVal.get("step-4"));
Assert.assertEquals(ModelType.EXPRESSION, inetAddress.getType());
name = validateResponse(returnVal.get("step-5"));
Assert.assertEquals("main-one", name.asString());
name = validateResponse(returnVal.get("step-6"));
Assert.assertEquals("other-two", name.asString());
// Can't access the master via the slave
response = slaveClient.execute(masterRequest);
validateFailedResponse(response);
}
@Test
public void testDomainWriteAccess() throws IOException {
// Start with writes of the root resource
final ModelNode addSchemaLocRequest = SchemaLocationAddHandler.getAddSchemaLocationOperation(ROOT_ADDRESS, "uri", "location");
ModelNode response = masterClient.execute(addSchemaLocRequest);
validateResponse(response);
response = masterClient.execute(getReadAttributeOperation(ROOT_ADDRESS, SCHEMA_LOCATIONS));
ModelNode returnVal = validateResponse(response);
Assert.assertTrue(hasTestSchemaLocation(returnVal));
// Now try a resource below root
final ModelNode addServerGroupRequest = Util.getEmptyOperation(ADD, TEST_SERVER_GROUP_ADDRESS);
addServerGroupRequest.get(PROFILE).set("default");
addServerGroupRequest.get(SOCKET_BINDING_GROUP).set("standard-sockets");
response = masterClient.execute(addServerGroupRequest);
validateResponse(response);
response = masterClient.execute(getReadAttributeOperation(TEST_SERVER_GROUP_ADDRESS, PROFILE));
returnVal = validateResponse(response);
Assert.assertEquals("default", returnVal.asString());
// Slave can't write
response = slaveClient.execute(addSchemaLocRequest);
validateFailedResponse(response);
response = slaveClient.execute(addServerGroupRequest);
validateFailedResponse(response);
}
@Test
public void testCompositeDomainWriteAccess() throws IOException {
ModelNode masterRequest = getEmptyOperation(COMPOSITE, null);
ModelNode steps = masterRequest.get(STEPS);
steps.add(SchemaLocationAddHandler.getAddSchemaLocationOperation(ROOT_ADDRESS, "uri", "location"));
// Now try a resource below root
final ModelNode addServerGroupRequest = Util.getEmptyOperation(ADD, TEST_SERVER_GROUP_ADDRESS);
addServerGroupRequest.get(PROFILE).set("default");
addServerGroupRequest.get(SOCKET_BINDING_GROUP).set("standard-sockets");
steps.add(addServerGroupRequest);
masterRequest.protect();
ModelNode response = masterClient.execute(masterRequest);
System.out.println(response);
validateResponse(response);
response = masterClient.execute(getReadAttributeOperation(ROOT_ADDRESS, SCHEMA_LOCATIONS));
ModelNode returnVal = validateResponse(response);
Assert.assertTrue(hasTestSchemaLocation(returnVal));
response = masterClient.execute(getReadAttributeOperation(TEST_SERVER_GROUP_ADDRESS, PROFILE));
returnVal = validateResponse(response);
Assert.assertEquals("default", returnVal.asString());
// Slave can't write
response = slaveClient.execute(masterRequest);
validateFailedResponse(response);
}
private boolean hasTestSchemaLocation(ModelNode returnVal) {
Assert.assertEquals(ModelType.LIST, returnVal.getType());
for (Property prop : returnVal.asPropertyList()) {
if ("uri".equals(prop.getName()) && "location".equals(prop.getValue().asString())) {
return true;
}
}
return false;
}
private static ModelNode getReadAttributeOperation(ModelNode address, String attribute) {
ModelNode result = getEmptyOperation(READ_ATTRIBUTE_OPERATION, address);
result.get(NAME).set(attribute);
return result;
}
private static ModelNode getEmptyOperation(String operationName, ModelNode address) {
ModelNode op = new ModelNode();
op.get(OP).set(operationName);
if (address != null) {
op.get(OP_ADDR).set(address);
}
else {
// Just establish the standard structure; caller can fill in address later
op.get(OP_ADDR);
}
return op;
}
}