/*
* 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.store.berkeleydb.jmx;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import javax.management.JMException;
import javax.management.ObjectName;
import javax.management.openmbean.CompositeData;
import javax.management.openmbean.CompositeDataSupport;
import javax.management.openmbean.CompositeType;
import javax.management.openmbean.OpenDataException;
import javax.management.openmbean.OpenType;
import javax.management.openmbean.SimpleType;
import javax.management.openmbean.TabularData;
import javax.management.openmbean.TabularDataSupport;
import javax.management.openmbean.TabularType;
import org.apache.log4j.Logger;
import org.apache.qpid.AMQStoreException;
import org.apache.qpid.server.jmx.AMQManagedObject;
import org.apache.qpid.server.jmx.ManagedObject;
import org.apache.qpid.server.store.berkeleydb.BDBHAMessageStore;
/**
* Management mbean for BDB HA.
* <p>
* At runtime, the classloader loading this clas must have visibility of the other Qpid JMX classes. This is
* currently arranged through OSGI using the <b>fragment</b> feature so that this bundle shares the
* same classloader as broker-plugins-management-jmx. See the <b>Fragment-Host:</b> header within the MANIFEST.MF
* of this bundle.
* </p>
*/
public class BDBHAMessageStoreManagerMBean extends AMQManagedObject implements ManagedBDBHAMessageStore
{
private static final Logger LOGGER = Logger.getLogger(BDBHAMessageStoreManagerMBean.class);
private static final TabularType GROUP_MEMBERS_TABLE;
private static final CompositeType GROUP_MEMBER_ROW;
private static final OpenType<?>[] GROUP_MEMBER_ATTRIBUTE_TYPES;
static
{
try
{
GROUP_MEMBER_ATTRIBUTE_TYPES = new OpenType<?>[] {SimpleType.STRING, SimpleType.STRING};
final String[] itemNames = new String[] {BDBHAMessageStore.GRP_MEM_COL_NODE_NAME, BDBHAMessageStore.GRP_MEM_COL_NODE_HOST_PORT};
final String[] itemDescriptions = new String[] {"Unique node name", "Node host / port "};
GROUP_MEMBER_ROW = new CompositeType("GroupMember", "Replication group member",
itemNames,
itemDescriptions,
GROUP_MEMBER_ATTRIBUTE_TYPES );
GROUP_MEMBERS_TABLE = new TabularType("GroupMembers", "Replication group memebers",
GROUP_MEMBER_ROW,
new String[] {BDBHAMessageStore.GRP_MEM_COL_NODE_NAME});
}
catch (final OpenDataException ode)
{
throw new ExceptionInInitializerError(ode);
}
}
private final BDBHAMessageStore _store;
protected BDBHAMessageStoreManagerMBean(BDBHAMessageStore store, ManagedObject parent) throws JMException
{
super(ManagedBDBHAMessageStore.class, ManagedBDBHAMessageStore.TYPE, ((AMQManagedObject)parent).getRegistry());
LOGGER.debug("Creating BDBHAMessageStoreManagerMBean");
_store = store;
register();
}
@Override
public String getObjectInstanceName()
{
return ObjectName.quote(_store.getName());
}
@Override
public String getGroupName()
{
return _store.getGroupName();
}
@Override
public String getNodeName()
{
return _store.getNodeName();
}
@Override
public String getNodeHostPort()
{
return _store.getNodeHostPort();
}
@Override
public String getHelperHostPort()
{
return _store.getHelperHostPort();
}
@Override
public String getDurability() throws IOException, JMException
{
try
{
return _store.getDurability();
}
catch (RuntimeException e)
{
LOGGER.debug("Failed query replication policy", e);
throw new JMException(e.getMessage());
}
}
@Override
public boolean getCoalescingSync() throws IOException, JMException
{
return _store.isCoalescingSync();
}
@Override
public String getNodeState() throws IOException, JMException
{
try
{
return _store.getNodeState();
}
catch (RuntimeException e)
{
LOGGER.debug("Failed query node state", e);
throw new JMException(e.getMessage());
}
}
@Override
public boolean getDesignatedPrimary() throws IOException, JMException
{
try
{
return _store.isDesignatedPrimary();
}
catch (RuntimeException e)
{
LOGGER.debug("Failed query designated primary", e);
throw new JMException(e.getMessage());
}
}
@Override
public TabularData getAllNodesInGroup() throws IOException, JMException
{
final TabularDataSupport data = new TabularDataSupport(GROUP_MEMBERS_TABLE);
final List<Map<String, String>> members = _store.getGroupMembers();
for (Map<String, String> map : members)
{
CompositeData memberData = new CompositeDataSupport(GROUP_MEMBER_ROW, map);
data.put(memberData);
}
return data;
}
@Override
public void removeNodeFromGroup(String nodeName) throws JMException
{
try
{
_store.removeNodeFromGroup(nodeName);
}
catch (AMQStoreException e)
{
LOGGER.error("Failed to remove node " + nodeName + " from group", e);
throw new JMException(e.getMessage());
}
}
@Override
public void setDesignatedPrimary(boolean primary) throws JMException
{
try
{
_store.setDesignatedPrimary(primary);
}
catch (AMQStoreException e)
{
LOGGER.error("Failed to set node " + _store.getNodeName() + " as designated primary", e);
throw new JMException(e.getMessage());
}
}
@Override
public void updateAddress(String nodeName, String newHostName, int newPort) throws JMException
{
try
{
_store.updateAddress(nodeName, newHostName, newPort);
}
catch(AMQStoreException e)
{
LOGGER.error("Failed to update address for node " + nodeName + " to " + newHostName + ":" + newPort, e);
throw new JMException(e.getMessage());
}
}
@Override
public ManagedObject getParentObject()
{
return null;
}
}