blob: 1de857d2249e5bd46b40144dd5613f7eed8f79be [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.configuration.store;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.UUID;
import org.mockito.ArgumentCaptor;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.apache.qpid.server.BrokerOptions;
import org.apache.qpid.server.configuration.IllegalConfigurationException;
import org.apache.qpid.server.configuration.updater.TaskExecutor;
import org.apache.qpid.server.logging.EventLogger;
import org.apache.qpid.server.logging.LogRecorder;
import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.model.ConfiguredObjectFactory;
import org.apache.qpid.server.model.Port;
import org.apache.qpid.server.model.Protocol;
import org.apache.qpid.server.model.State;
import org.apache.qpid.server.model.SystemContext;
import org.apache.qpid.server.model.VirtualHost;
import org.apache.qpid.server.store.ConfiguredObjectRecord;
import org.apache.qpid.server.store.ConfiguredObjectRecordImpl;
import org.apache.qpid.server.store.DurableConfigurationStore;
import org.apache.qpid.server.store.handler.ConfiguredObjectRecordHandler;
import org.apache.qpid.test.utils.QpidTestCase;
public class ManagementModeStoreHandlerTest extends QpidTestCase
{
private ManagementModeStoreHandler _handler;
private BrokerOptions _options;
private DurableConfigurationStore _store;
private ConfiguredObjectRecord _root;
private ConfiguredObjectRecord _portEntry;
private UUID _rootId, _portEntryId;
private SystemContext _systemContext;
protected void setUp() throws Exception
{
super.setUp();
_rootId = UUID.randomUUID();
_portEntryId = UUID.randomUUID();
_store = mock(DurableConfigurationStore.class);
_systemContext = new SystemContext(new TaskExecutor(), new ConfiguredObjectFactory(), mock(
EventLogger.class), mock(LogRecorder.class), new BrokerOptions());
ConfiguredObjectRecord systemContextRecord = _systemContext.asObjectRecord();
_root = new ConfiguredObjectRecordImpl(_rootId, Broker.class.getSimpleName(), Collections.<String,Object>emptyMap(), Collections.singletonMap(SystemContext.class.getSimpleName(), systemContextRecord));
_portEntry = mock(ConfiguredObjectRecord.class);
when(_portEntry.getId()).thenReturn(_portEntryId);
when(_portEntry.getParents()).thenReturn(Collections.singletonMap(Broker.class.getSimpleName(), _root));
when(_portEntry.getType()).thenReturn(Port.class.getSimpleName());
final ArgumentCaptor<ConfiguredObjectRecordHandler> recovererArgumentCaptor = ArgumentCaptor.forClass(ConfiguredObjectRecordHandler.class);
doAnswer(
new Answer()
{
@Override
public Object answer(final InvocationOnMock invocation) throws Throwable
{
ConfiguredObjectRecordHandler recoverer = recovererArgumentCaptor.getValue();
if(recoverer.handle(_root))
{
recoverer.handle(_portEntry);
}
return null;
}
}
).when(_store).visitConfiguredObjectRecords(recovererArgumentCaptor.capture());
_options = new BrokerOptions();
_handler = new ManagementModeStoreHandler(_store, _options);
_handler.openConfigurationStore(_systemContext,Collections.<String,Object>emptyMap());
}
private ConfiguredObjectRecord getRootEntry()
{
BrokerFinder brokerFinder = new BrokerFinder();
_handler.visitConfiguredObjectRecords(brokerFinder);
return brokerFinder.getBrokerRecord();
}
private ConfiguredObjectRecord getEntry(UUID id)
{
RecordFinder recordFinder = new RecordFinder(id);
_handler.visitConfiguredObjectRecords(recordFinder);
return recordFinder.getFoundRecord();
}
private Collection<UUID> getChildrenIds(ConfiguredObjectRecord record)
{
ChildFinder childFinder = new ChildFinder(record);
_handler.visitConfiguredObjectRecords(childFinder);
return childFinder.getChildIds();
}
public void testGetRootEntryWithEmptyOptions()
{
ConfiguredObjectRecord root = getRootEntry();
assertEquals("Unexpected root id", _rootId, root.getId());
assertEquals("Unexpected children", Collections.singleton(_portEntryId), getChildrenIds(root));
}
public void testGetRootEntryWithHttpPortOverriden()
{
_options.setManagementModeHttpPortOverride(9090);
_handler = new ManagementModeStoreHandler(_store, _options);
_handler.openConfigurationStore(_systemContext,Collections.<String,Object>emptyMap());
ConfiguredObjectRecord root = getRootEntry();
assertEquals("Unexpected root id", _rootId, root.getId());
Collection<UUID> childrenIds = getChildrenIds(root);
assertEquals("Unexpected children size", 2, childrenIds.size());
assertTrue("Store port entry id is not found", childrenIds.contains(_portEntryId));
}
public void testGetRootEntryWithRmiPortOverriden()
{
_options.setManagementModeRmiPortOverride(9090);
_handler = new ManagementModeStoreHandler(_store, _options);
_handler.openConfigurationStore(_systemContext,Collections.<String,Object>emptyMap());
ConfiguredObjectRecord root = getRootEntry();
assertEquals("Unexpected root id", _rootId, root.getId());
Collection<UUID> childrenIds = getChildrenIds(root);
assertEquals("Unexpected children size", 3, childrenIds.size());
assertTrue("Store port entry id is not found", childrenIds.contains(_portEntryId));
}
public void testGetRootEntryWithConnectorPortOverriden()
{
_options.setManagementModeJmxPortOverride(9090);
_handler = new ManagementModeStoreHandler(_store, _options);
_handler.openConfigurationStore(_systemContext,Collections.<String,Object>emptyMap());
ConfiguredObjectRecord root = getRootEntry();
assertEquals("Unexpected root id", _rootId, root.getId());
Collection<UUID> childrenIds = getChildrenIds(root);
assertEquals("Unexpected children size", 2, childrenIds.size());
assertTrue("Store port entry id is not found", childrenIds.contains(_portEntryId));
}
public void testGetRootEntryWithManagementPortsOverriden()
{
_options.setManagementModeHttpPortOverride(1000);
_options.setManagementModeRmiPortOverride(2000);
_options.setManagementModeJmxPortOverride(3000);
_handler = new ManagementModeStoreHandler(_store, _options);
_handler.openConfigurationStore(_systemContext,Collections.<String,Object>emptyMap());
ConfiguredObjectRecord root = getRootEntry();
assertEquals("Unexpected root id", _rootId, root.getId());
Collection<UUID> childrenIds = getChildrenIds(root);
assertEquals("Unexpected children size", 4, childrenIds.size());
assertTrue("Store port entry id is not found", childrenIds.contains(_portEntryId));
}
public void testGetEntryByRootId()
{
ConfiguredObjectRecord root = getEntry(_rootId);
assertEquals("Unexpected root id", _rootId, root.getId());
assertEquals("Unexpected children", Collections.singleton(_portEntryId), getChildrenIds(root));
}
public void testGetEntryByPortId()
{
ConfiguredObjectRecord portEntry = getEntry(_portEntryId);
assertEquals("Unexpected entry id", _portEntryId, portEntry.getId());
assertTrue("Unexpected children", getChildrenIds(portEntry).isEmpty());
assertEquals("Unexpected state", State.QUIESCED, portEntry.getAttributes().get(Port.STATE));
}
public void testGetEntryByCLIConnectorPortId()
{
_options.setManagementModeJmxPortOverride(9090);
_handler = new ManagementModeStoreHandler(_store, _options);
_handler.openConfigurationStore(_systemContext,Collections.<String,Object>emptyMap());
UUID optionsPort = getOptionsPortId();
ConfiguredObjectRecord portEntry = getEntry(optionsPort);
assertCLIPortEntry(portEntry, optionsPort, Protocol.JMX_RMI);
}
public void testGetEntryByCLIHttpPortId()
{
_options.setManagementModeHttpPortOverride(9090);
_handler = new ManagementModeStoreHandler(_store, _options);
_handler.openConfigurationStore(_systemContext,Collections.<String,Object>emptyMap());
UUID optionsPort = getOptionsPortId();
ConfiguredObjectRecord portEntry = getEntry(optionsPort);
assertCLIPortEntry(portEntry, optionsPort, Protocol.HTTP);
}
public void testHttpPortEntryIsQuiesced()
{
Map<String, Object> attributes = new HashMap<String, Object>();
attributes.put(Port.PROTOCOLS, Collections.singleton(Protocol.HTTP));
when(_portEntry.getAttributes()).thenReturn(attributes);
_options.setManagementModeHttpPortOverride(9090);
_handler = new ManagementModeStoreHandler(_store, _options);
_handler.openConfigurationStore(_systemContext,Collections.<String,Object>emptyMap());
ConfiguredObjectRecord portEntry = getEntry(_portEntryId);
assertEquals("Unexpected state", State.QUIESCED, portEntry.getAttributes().get(Port.STATE));
}
public void testRmiPortEntryIsQuiesced()
{
Map<String, Object> attributes = new HashMap<String, Object>();
attributes.put(Port.PROTOCOLS, Collections.singleton(Protocol.RMI));
when(_portEntry.getAttributes()).thenReturn(attributes);
_options.setManagementModeRmiPortOverride(9090);
_handler = new ManagementModeStoreHandler(_store, _options);
_handler.openConfigurationStore(_systemContext,Collections.<String,Object>emptyMap());
ConfiguredObjectRecord portEntry = getEntry(_portEntryId);
assertEquals("Unexpected state", State.QUIESCED, portEntry.getAttributes().get(Port.STATE));
}
public void testConnectorPortEntryIsQuiesced()
{
Map<String, Object> attributes = new HashMap<String, Object>();
attributes.put(Port.PROTOCOLS, Collections.singleton(Protocol.JMX_RMI));
when(_portEntry.getAttributes()).thenReturn(attributes);
_options.setManagementModeRmiPortOverride(9090);
_handler = new ManagementModeStoreHandler(_store, _options);
_handler.openConfigurationStore(_systemContext,Collections.<String,Object>emptyMap());
ConfiguredObjectRecord portEntry = getEntry(_portEntryId);
assertEquals("Unexpected state", State.QUIESCED, portEntry.getAttributes().get(Port.STATE));
}
public void testVirtualHostEntryIsNotQuiescedByDefault()
{
virtualHostEntryQuiescedStatusTestImpl(false);
}
public void testVirtualHostEntryIsQuiescedWhenRequested()
{
virtualHostEntryQuiescedStatusTestImpl(true);
}
private void virtualHostEntryQuiescedStatusTestImpl(boolean mmQuiesceVhosts)
{
UUID virtualHostId = UUID.randomUUID();
Map<String, Object> attributes = new HashMap<String, Object>();
attributes.put(VirtualHost.TYPE, "STANDARD");
final ConfiguredObjectRecord virtualHost = new ConfiguredObjectRecordImpl(virtualHostId, VirtualHost.class.getSimpleName(), attributes, Collections.singletonMap(Broker.class.getSimpleName(), _root));
final ArgumentCaptor<ConfiguredObjectRecordHandler> recovererArgumentCaptor = ArgumentCaptor.forClass(ConfiguredObjectRecordHandler.class);
doAnswer(
new Answer()
{
@Override
public Object answer(final InvocationOnMock invocation) throws Throwable
{
ConfiguredObjectRecordHandler recoverer = recovererArgumentCaptor.getValue();
if(recoverer.handle(_root))
{
if(recoverer.handle(_portEntry))
{
recoverer.handle(virtualHost);
}
}
return null;
}
}
).when(_store).visitConfiguredObjectRecords(recovererArgumentCaptor.capture());
State expectedState = mmQuiesceVhosts ? State.QUIESCED : null;
if(mmQuiesceVhosts)
{
_options.setManagementModeQuiesceVirtualHosts(mmQuiesceVhosts);
}
_handler = new ManagementModeStoreHandler(_store, _options);
_handler.openConfigurationStore(_systemContext,Collections.<String,Object>emptyMap());
ConfiguredObjectRecord hostEntry = getEntry(virtualHostId);
Map<String, Object> hostAttributes = new HashMap<String, Object>(hostEntry.getAttributes());
assertEquals("Unexpected state", expectedState, hostAttributes.get(VirtualHost.STATE));
hostAttributes.remove(VirtualHost.STATE);
assertEquals("Unexpected attributes", attributes, hostAttributes);
}
@SuppressWarnings("unchecked")
private void assertCLIPortEntry(ConfiguredObjectRecord portEntry, UUID optionsPort, Protocol protocol)
{
assertEquals("Unexpected entry id", optionsPort, portEntry.getId());
assertTrue("Unexpected children", getChildrenIds(portEntry).isEmpty());
Map<String, Object> attributes = portEntry.getAttributes();
assertEquals("Unexpected name", "MANAGEMENT-MODE-PORT-" + protocol.name(), attributes.get(Port.NAME));
assertEquals("Unexpected protocol", Collections.singleton(protocol), new HashSet<Protocol>(
(Collection<Protocol>) attributes.get(Port.PROTOCOLS)));
}
public void testSavePort()
{
_options.setManagementModeHttpPortOverride(1000);
_options.setManagementModeRmiPortOverride(2000);
_options.setManagementModeJmxPortOverride(3000);
_handler = new ManagementModeStoreHandler(_store, _options);
_handler.openConfigurationStore(_systemContext,Collections.<String,Object>emptyMap());
Map<String, Object> attributes = new HashMap<String, Object>();
attributes.put(Port.NAME, "TEST");
ConfiguredObjectRecord
configurationEntry = new ConfiguredObjectRecordImpl(_portEntryId, Port.class.getSimpleName(), attributes,
Collections.singletonMap(Broker.class.getSimpleName(), getRootEntry()));
_handler.create(configurationEntry);
verify(_store).create(any(ConfiguredObjectRecord.class));
}
public void testSaveRoot()
{
_options.setManagementModeHttpPortOverride(1000);
_options.setManagementModeRmiPortOverride(2000);
_options.setManagementModeJmxPortOverride(3000);
_handler = new ManagementModeStoreHandler(_store, _options);
_handler.openConfigurationStore(_systemContext,Collections.<String,Object>emptyMap());
ConfiguredObjectRecord root = getRootEntry();
Map<String, Object> attributes = new HashMap<String, Object>();
attributes.put(Broker.NAME, "TEST");
ConfiguredObjectRecord
configurationEntry = new ConfiguredObjectRecordImpl(_rootId, Broker.class.getSimpleName(), attributes,root.getParents());
_handler.update(false, configurationEntry);
verify(_store).update(anyBoolean(), any(ConfiguredObjectRecord.class));
}
public void testSaveCLIHttpPort()
{
_options.setManagementModeHttpPortOverride(1000);
_handler = new ManagementModeStoreHandler(_store, _options);
_handler.openConfigurationStore(_systemContext,Collections.<String,Object>emptyMap());
UUID portId = getOptionsPortId();
Map<String, Object> attributes = new HashMap<String, Object>();
attributes.put(Port.NAME, "TEST");
ConfiguredObjectRecord
configurationEntry = new ConfiguredObjectRecordImpl(portId, Port.class.getSimpleName(), attributes,
Collections.singletonMap(Broker.class.getSimpleName(),
getRootEntry()));
try
{
_handler.update(false, configurationEntry);
fail("Exception should be thrown on trying to save CLI port");
}
catch (IllegalConfigurationException e)
{
// pass
}
}
public void testRemove()
{
_options.setManagementModeHttpPortOverride(1000);
_handler = new ManagementModeStoreHandler(_store, _options);
_handler.openConfigurationStore(_systemContext,Collections.<String,Object>emptyMap());
ConfiguredObjectRecord record = new ConfiguredObjectRecord()
{
@Override
public UUID getId()
{
return _portEntryId;
}
@Override
public String getType()
{
return Port.class.getSimpleName();
}
@Override
public Map<String, Object> getAttributes()
{
return Collections.emptyMap();
}
@Override
public Map<String, ConfiguredObjectRecord> getParents()
{
return null;
}
};
_handler.remove(record);
verify(_store).remove(record);
}
public void testRemoveCLIPort()
{
_options.setManagementModeHttpPortOverride(1000);
_handler = new ManagementModeStoreHandler(_store, _options);
_handler.openConfigurationStore(_systemContext,Collections.<String,Object>emptyMap());
UUID portId = getOptionsPortId();
ConfiguredObjectRecord record = mock(ConfiguredObjectRecord.class);
when(record.getId()).thenReturn(portId);
try
{
_handler.remove(record);
fail("Exception should be thrown on trying to remove CLI port");
}
catch (IllegalConfigurationException e)
{
// pass
}
}
private UUID getOptionsPortId()
{
ConfiguredObjectRecord root = getRootEntry();
assertEquals("Unexpected root id", _rootId, root.getId());
Collection<UUID> childrenIds = getChildrenIds(root);
childrenIds.remove(_portEntryId);
UUID optionsPort = childrenIds.iterator().next();
return optionsPort;
}
private class BrokerFinder implements ConfiguredObjectRecordHandler
{
private ConfiguredObjectRecord _brokerRecord;
private int _version;
@Override
public void begin(final int configVersion)
{
_version = configVersion;
}
@Override
public boolean handle(final ConfiguredObjectRecord object)
{
if(object.getType().equals(Broker.class.getSimpleName()))
{
_brokerRecord = object;
return false;
}
return true;
}
@Override
public int end()
{
return _version;
}
public ConfiguredObjectRecord getBrokerRecord()
{
return _brokerRecord;
}
}
private class RecordFinder implements ConfiguredObjectRecordHandler
{
private final UUID _id;
private ConfiguredObjectRecord _foundRecord;
private int _version;
private RecordFinder(final UUID id)
{
_id = id;
}
@Override
public void begin(final int configVersion)
{
_version = configVersion;
}
@Override
public boolean handle(final ConfiguredObjectRecord object)
{
if(object.getId().equals(_id))
{
_foundRecord = object;
return false;
}
return true;
}
@Override
public int end()
{
return _version;
}
public ConfiguredObjectRecord getFoundRecord()
{
return _foundRecord;
}
}
private class ChildFinder implements ConfiguredObjectRecordHandler
{
private final Collection<UUID> _childIds = new HashSet<UUID>();
private final ConfiguredObjectRecord _parent;
private int _version;
private ChildFinder(final ConfiguredObjectRecord parent)
{
_parent = parent;
}
@Override
public void begin(final int configVersion)
{
_version = configVersion;
}
@Override
public boolean handle(final ConfiguredObjectRecord object)
{
if(object.getParents() != null)
{
for(ConfiguredObjectRecord parent : object.getParents().values())
{
if(parent.getId().equals(_parent.getId()))
{
_childIds.add(object.getId());
}
}
}
return true;
}
@Override
public int end()
{
return _version;
}
public Collection<UUID> getChildIds()
{
return _childIds;
}
}
}