package org.jboss.mq.sm.file;
import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.io.InputStream;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import javax.jms.InvalidClientIDException;
import javax.jms.JMSException;
import javax.jms.JMSSecurityException;
import org.jboss.system.server.ServerConfigLocator;
import org.jboss.mq.DurableSubscriptionID;
import org.jboss.mq.SpyTopic;
import org.jboss.mq.SpyJMSException;
import org.jboss.mq.xml.XElement;
import org.jboss.mq.xml.XElementException;
import org.jboss.mq.sm.StateManager;
import org.jboss.mq.sm.AbstractStateManager;
public class DynamicStateManager extends AbstractStateManager implements DynamicStateManagerMBean
{
class DynamicDurableSubscription extends DurableSubscription
{
XElement element;
public DynamicDurableSubscription(XElement element) throws XElementException
{
super(
element.getField("ClientID"),
element.getField("Name"),
element.getField("TopicName"),
element.getOptionalField("Selector"));
this.element = element;
}
XElement getElement()
{
return element;
}
}
boolean hasSecurityManager = true;
XElement stateConfig = new XElement("StateManager");
private String stateFile = "jbossmq-state.xml";
private URL systemConfigURL;
public DynamicStateManager()
{
}
public StateManager getInstance()
{
return this;
}
protected void createService() throws Exception
{
systemConfigURL = ServerConfigLocator.locate().getServerConfigURL();
}
public void startService() throws Exception
{
loadConfig();
}
public String displayStateConfig() throws Exception
{
return stateConfig.toString();
}
public void setStateFile(String newStateFile)
{
stateFile = newStateFile.trim();
}
public String getStateFile()
{
return stateFile;
}
public boolean hasSecurityManager()
{
return hasSecurityManager;
}
public void setHasSecurityManager(boolean hasSecurityManager)
{
this.hasSecurityManager = hasSecurityManager;
}
public void loadConfig() throws IOException, XElementException
{
URL configURL = new URL(systemConfigURL, stateFile);
if (log.isDebugEnabled())
{
log.debug("Loading config from: " + configURL);
}
InputStream in = new BufferedInputStream(configURL.openStream());
try
{
synchronized (stateConfig)
{
stateConfig = XElement.createFrom(in);
}
}
finally
{
in.close();
}
}
public void saveConfig() throws IOException
{
URL configURL = new URL(systemConfigURL, stateFile);
if (configURL.getProtocol().equals("file"))
{
File file = new File(configURL.getFile());
if (log.isDebugEnabled())
{
log.debug("Saving config to: " + file);
}
PrintStream stream = new PrintStream(new FileOutputStream(file));
try
{
synchronized (stateConfig)
{
stream.print(stateConfig.toXML(true));
}
}
finally
{
stream.close();
}
}
else
{
log.error("Can not save configuration to non-file URL: " + configURL);
}
}
protected String getPreconfClientId(String login, String passwd) throws JMSException
{
try
{
synchronized (stateConfig)
{
Enumeration enumeration = stateConfig.getElementsNamed("Users/User");
while (enumeration.hasMoreElements())
{
XElement element = (XElement) enumeration.nextElement();
String name = element.getField("Name");
if (!name.equals(login))
{
continue; }
if (!hasSecurityManager)
{
String pw = element.getField("Password");
if (!passwd.equals(pw))
{
throw new JMSSecurityException("Bad password");
}
}
String clientId = null;
if (element.containsField("Id"))
{
clientId = element.getField("Id");
}
return clientId;
}
if (!hasSecurityManager)
throw new JMSSecurityException("This user does not exist");
else
return null;
}
}
catch (XElementException e)
{
log.error(e);
throw new JMSException("Invalid server user configuration.");
}
}
protected DurableSubscription getDurableSubscription(DurableSubscriptionID sub) throws JMSException
{
boolean debug = log.isDebugEnabled();
try
{
synchronized (stateConfig)
{
Enumeration enumeration = stateConfig.getElementsNamed("DurableSubscriptions/DurableSubscription");
while (enumeration.hasMoreElements())
{
XElement dur = (XElement) enumeration.nextElement();
if (dur.containsField("ClientID") && dur.getField("ClientID").equals(sub.getClientID()))
{
if (dur.getField("Name").equals(sub.getSubscriptionName()))
{
if (debug)
log.debug("Found a matching ClientID configuration section.");
return new DynamicDurableSubscription(dur);
}
}
}
return null;
}
}
catch (XElementException e)
{
JMSException newE = new SpyJMSException("Could not find durable subscription");
newE.setLinkedException(e);
throw newE;
}
}
protected void checkLoggedOnClientId(String clientID) throws JMSException
{
synchronized (stateConfig)
{
Enumeration enumeration = stateConfig.getElementsNamed("Users/User");
while (enumeration.hasMoreElements())
{
XElement element = (XElement) enumeration.nextElement();
try
{
if (element.containsField("Id") && element.getField("Id").equals(clientID))
{
throw new InvalidClientIDException("This loggedOnClientIds is password protected !");
}
}
catch (XElementException ignore)
{
}
}
}
}
protected void saveDurableSubscription(DurableSubscription ds) throws JMSException
{
try
{
synchronized (stateConfig)
{
if (ds instanceof DynamicDurableSubscription)
{
XElement s = ((DynamicDurableSubscription) ds).getElement();
if (s != null)
{
s.setField("TopicName", ds.getTopic()); s.setOptionalField("Selector", ds.getSelector()); }
else
{
throw new JMSException("Can not save a null subscription");
}
}
else
{
XElement dur = stateConfig.getElement("DurableSubscriptions");
XElement subscription = new XElement("DurableSubscription");
subscription.addField("ClientID", ds.getClientID());
subscription.addField("Name", ds.getName());
subscription.addField("TopicName", ds.getTopic());
subscription.setOptionalField("Selector", ds.getSelector());
dur.addElement(subscription);
}
saveConfig();
}
}
catch (XElementException e)
{
JMSException newE = new SpyJMSException("Could not save the durable subscription");
newE.setLinkedException(e);
throw newE;
}
catch (IOException e)
{
JMSException newE = new SpyJMSException("Could not save the durable subscription");
newE.setLinkedException(e);
throw newE;
}
}
protected void removeDurableSubscription(DurableSubscription ds) throws JMSException
{
try
{
synchronized (stateConfig)
{
XElement s = ((DynamicDurableSubscription) ds).getElement();
if (s != null)
{
s.removeFromParent();
saveConfig();
}
else
{
throw new JMSException("Can not remove a null subscription");
}
}
}
catch (XElementException e)
{
JMSException newE = new SpyJMSException("Could not remove the durable subscription");
newE.setLinkedException(e);
throw newE;
}
catch (IOException e)
{
JMSException newE = new SpyJMSException("Could not remove the durable subscription");
newE.setLinkedException(e);
throw newE;
}
}
public Collection getDurableSubscriptionIdsForTopic(SpyTopic topic) throws JMSException
{
Collection durableSubs = new ArrayList();
try
{
synchronized (stateConfig)
{
Enumeration enumeration = stateConfig.getElementsNamed("DurableSubscriptions/DurableSubscription");
while (enumeration.hasMoreElements())
{
XElement element = (XElement) enumeration.nextElement();
String clientId = element.getField("ClientID");
String name = element.getField("Name");
String topicName = element.getField("TopicName");
String selector = element.getOptionalField("Selector");
if (topic.getName().equals(topicName))
{
durableSubs.add(new DurableSubscriptionID(clientId, name, selector));
}
}
}
}
catch (XElementException e)
{
JMSException jmse = new JMSException("Error in statemanager xml");
jmse.setLinkedException(e);
throw jmse;
} return durableSubs;
}
public void addUser(String name, String password, String preconfID) throws Exception
{
if (findUser(name) != null)
throw new Exception("Can not add, user exist");
XElement users = stateConfig.getElement("Users");
XElement user = new XElement("User");
user.addField("Name", name);
user.addField("Password", password);
if (preconfID != null)
user.addField("Id", preconfID);
users.addElement(user);
saveConfig();
}
public void removeUser(String name) throws Exception
{
XElement user = findUser(name);
if (user == null)
throw new Exception("Cant remove user that does not exist");
user.removeFromParent();
String[] roles = getRoles(name);
if (roles != null)
{
for (int i = 0; i < roles.length; i++)
{
try
{
removeUserFromRole(roles[i], name);
}
catch (Exception ex)
{
}
}
}
saveConfig();
}
public void addRole(String name) throws Exception
{
if (findRole(name) != null)
throw new Exception("Cant add role, it already exists");
XElement roles = stateConfig.getElement("Roles");
XElement role = new XElement("Role");
role.setAttribute("name", name);
roles.addElement(role);
saveConfig();
}
public void removeRole(String name) throws Exception
{
XElement role = findRole(name);
if (role == null)
throw new Exception("Cant remove role that does not exist");
role.removeFromParent();
saveConfig();
}
public void addUserToRole(String roleName, String user) throws Exception
{
XElement role = findRole(roleName);
if (role == null)
throw new Exception("Cant add to role that does not exist");
if (findUser(user) == null)
throw new Exception("Cant add user to role, user does to exist");
if (findUserInRole(role, user) != null)
throw new Exception("Cant add user to role, user already part of role");
XElement u = new XElement("UserName");
u.setValue(user);
role.addElement(u);
saveConfig();
}
public void removeUserFromRole(String roleName, String user) throws Exception
{
XElement role = findRole(roleName);
if (role == null)
throw new Exception("Cant remove user from role that does not exist");
XElement u = findUserInRole(role, user);
if (u == null)
throw new Exception("Cant remove user from role, user does not exist");
u.removeFromParent();
saveConfig();
}
protected XElement findUser(String user) throws Exception
{
Enumeration enumeration = stateConfig.getElementsNamed("Users/User");
while (enumeration.hasMoreElements())
{
XElement element = (XElement) enumeration.nextElement();
if (element.getField("Name").equals(user))
return element;
}
return null;
}
protected XElement findRole(String role) throws Exception
{
Enumeration enumeration = stateConfig.getElementsNamed("Roles/Role");
while (enumeration.hasMoreElements())
{
XElement element = (XElement) enumeration.nextElement();
if (element.getAttribute("name").equals(role))
return element;
}
return null;
}
protected XElement findUserInRole(XElement role, String user) throws Exception
{
Enumeration enumeration = role.getElementsNamed("UserName");
while (enumeration.hasMoreElements())
{
XElement element = (XElement) enumeration.nextElement();
if (user.equals(element.getValue()))
return element;
}
return null;
}
public String[] getRoles(String user) throws Exception
{
ArrayList roles = new ArrayList();
Enumeration enumeration = stateConfig.getElementsNamed("Roles/Role");
while (enumeration.hasMoreElements())
{
XElement element = (XElement) enumeration.nextElement();
XElement u = findUserInRole(element, user);
if (u != null)
roles.add(element.getAttribute("name"));
}
return (String[]) roles.toArray(new String[roles.size()]);
}
public boolean validatePassword(String user, String inputPassword) throws Exception
{
boolean valid = false;
XElement u = findUser(user);
if (u != null)
{
String pw = u.getField("Password");
if (inputPassword != null && inputPassword.equals(pw))
valid = true;
}
return valid;
}
}