/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2000-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
/*
* @(#)DestinationConfig.java 1.26 06/28/07
*/
package com.sun.messaging.jmq.jmsserver.management.mbeans;
import java.util.Date;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanParameterInfo;
import javax.management.MBeanNotificationInfo;
import javax.management.AttributeChangeNotification;
import javax.management.MBeanException;
import javax.management.InvalidAttributeValueException;
import com.sun.messaging.jms.management.server.*;
import com.sun.messaging.jmq.jmsserver.Globals;
import com.sun.messaging.jmq.jmsserver.core.Destination;
import com.sun.messaging.jmq.jmsserver.management.util.DestinationUtil;
import com.sun.messaging.jmq.jmsserver.util.BrokerException;
import com.sun.messaging.jmq.util.ClusterDeliveryPolicy;
import com.sun.messaging.jmq.util.SizeString;
import com.sun.messaging.jmq.util.admin.DestinationInfo;
import com.sun.messaging.jmq.util.log.Logger;
public class DestinationConfig extends MQMBeanReadWrite {
private Destination d = null;
private static MBeanAttributeInfo[] attrs = {
new MBeanAttributeInfo(DestinationAttributes.CONSUMER_FLOW_LIMIT,
Long.class.getName(),
mbr.getString(mbr.I_DST_ATTR_CONSUMER_FLOW_LIMIT),
true,
true,
false),
new MBeanAttributeInfo(DestinationAttributes.LOCAL_ONLY,
Boolean.class.getName(),
mbr.getString(mbr.I_DST_ATTR_LOCAL_ONLY),
true,
false,
false),
new MBeanAttributeInfo(DestinationAttributes.LIMIT_BEHAVIOR,
String.class.getName(),
mbr.getString(mbr.I_DST_ATTR_LIMIT_BEHAVIOR),
true,
true,
false),
new MBeanAttributeInfo(DestinationAttributes.LOCAL_DELIVERY_PREFERRED,
Boolean.class.getName(),
mbr.getString(mbr.I_DST_ATTR_LOCAL_DELIVERY_PREFERRED),
true,
true,
false),
new MBeanAttributeInfo(DestinationAttributes.MAX_BYTES_PER_MSG,
Long.class.getName(),
mbr.getString(mbr.I_DST_ATTR_MAX_BYTES_PER_MSG),
true,
true,
false),
new MBeanAttributeInfo(DestinationAttributes.MAX_NUM_ACTIVE_CONSUMERS,
Integer.class.getName(),
mbr.getString(mbr.I_DST_ATTR_MAX_NUM_ACTIVE_CONSUMERS),
true,
true,
false),
new MBeanAttributeInfo(DestinationAttributes.MAX_NUM_BACKUP_CONSUMERS,
Integer.class.getName(),
mbr.getString(mbr.I_DST_ATTR_MAX_NUM_BACKUP_CONSUMERS),
true,
true,
false),
new MBeanAttributeInfo(DestinationAttributes.MAX_NUM_MSGS,
Long.class.getName(),
mbr.getString(mbr.I_DST_ATTR_MAX_NUM_MSGS),
true,
true,
false),
new MBeanAttributeInfo(DestinationAttributes.MAX_NUM_PRODUCERS,
Integer.class.getName(),
mbr.getString(mbr.I_DST_ATTR_MAX_NUM_PRODUCERS),
true,
true,
false),
new MBeanAttributeInfo(DestinationAttributes.MAX_TOTAL_MSG_BYTES,
Long.class.getName(),
mbr.getString(mbr.I_DST_ATTR_MAX_TOTAL_MSG_BYTES),
true,
true,
false),
new MBeanAttributeInfo(DestinationAttributes.NAME,
String.class.getName(),
mbr.getString(mbr.I_DST_ATTR_NAME),
true,
false,
false),
new MBeanAttributeInfo(DestinationAttributes.TYPE,
String.class.getName(),
mbr.getString(mbr.I_DST_ATTR_TYPE),
true,
false,
false),
new MBeanAttributeInfo(DestinationAttributes.USE_DMQ,
Boolean.class.getName(),
mbr.getString(mbr.I_DST_ATTR_USE_DMQ),
true,
true,
false),
new MBeanAttributeInfo(DestinationAttributes.VALIDATE_XML_SCHEMA_ENABLED,
Boolean.class.getName(),
mbr.getString(mbr.I_DST_ATTR_VALIDATE_XML_SCHEMA_ENABLED),
true,
true,
false),
new MBeanAttributeInfo(DestinationAttributes.XML_SCHEMA_URI_LIST,
String.class.getName(),
mbr.getString(mbr.I_DST_ATTR_XML_SCHEMA_URI_LIST),
true,
true,
false),
new MBeanAttributeInfo(DestinationAttributes.RELOAD_XML_SCHEMA_ON_FAILURE,
Boolean.class.getName(),
mbr.getString(mbr.I_DST_ATTR_RELOAD_XML_SCHEMA_ON_FAILURE),
true,
true,
false)
};
private static MBeanParameterInfo[] pauseSignature = {
new MBeanParameterInfo("pauseType", String.class.getName(),
mbr.getString(mbr.I_DST_OP_PAUSE_PARAM_PAUSE_TYPE))
};
private static MBeanOperationInfo[] ops = {
new MBeanOperationInfo(DestinationOperations.COMPACT,
mbr.getString(mbr.I_DST_OP_COMPACT),
null,
Void.TYPE.getName(),
MBeanOperationInfo.ACTION),
new MBeanOperationInfo(DestinationOperations.PAUSE,
mbr.getString(mbr.I_DST_OP_PAUSE_ALL),
null,
Void.TYPE.getName(),
MBeanOperationInfo.ACTION),
new MBeanOperationInfo(DestinationOperations.PAUSE,
mbr.getString(mbr.I_DST_OP_PAUSE),
pauseSignature,
Void.TYPE.getName(),
MBeanOperationInfo.ACTION),
new MBeanOperationInfo(DestinationOperations.PURGE,
mbr.getString(mbr.I_DST_OP_PURGE),
null,
Void.TYPE.getName(),
MBeanOperationInfo.ACTION),
new MBeanOperationInfo(DestinationOperations.RESUME,
mbr.getString(mbr.I_DST_OP_RESUME),
null,
Void.TYPE.getName(),
MBeanOperationInfo.ACTION)
};
private static String[] attrChangeTypes = {
AttributeChangeNotification.ATTRIBUTE_CHANGE
};
private static MBeanNotificationInfo[] notifs = {
new MBeanNotificationInfo(
attrChangeTypes,
AttributeChangeNotification.class.getName(),
mbr.getString(mbr.I_ATTR_CHANGE_NOTIFICATION)
)
};
public DestinationConfig(Destination dest) {
super();
this.d = dest;
}
public void setConsumerFlowLimit(Long l) throws MBeanException {
try {
checkLongNegOneAndUp(l, DestinationAttributes.CONSUMER_FLOW_LIMIT);
d.setMaxPrefetch(l.intValue());
d.update();
} catch (Exception e) {
handleSetterException(
DestinationAttributes.CONSUMER_FLOW_LIMIT, e);
}
}
public Long getConsumerFlowLimit() {
DestinationInfo di = DestinationUtil.getDestinationInfo(d);
return (new Long(di.maxPrefetch));
}
public Boolean getLocalOnly() {
DestinationInfo di = DestinationUtil.getDestinationInfo(d);
if (di.isDestinationLocal()) {
return (Boolean.TRUE);
}
return (Boolean.FALSE);
}
public Boolean isLocalOnly() {
return (getLocalOnly());
}
public void setLimitBehavior(String s) throws MBeanException {
try {
checkLimitBehavior(s);
d.setLimitBehavior(DestinationUtil.toInternalDestLimitBehavior(s));
d.update();
} catch (Exception e) {
handleSetterException(
DestinationAttributes.LIMIT_BEHAVIOR, e);
}
}
public String getLimitBehavior() {
DestinationInfo di = DestinationUtil.getDestinationInfo(d);
return (DestinationUtil.toExternalDestLimitBehavior(di.destLimitBehavior));
}
private void checkLimitBehavior(String s) throws InvalidAttributeValueException {
if (s.equals(DestinationLimitBehavior.FLOW_CONTROL) ||
s.equals(DestinationLimitBehavior.REMOVE_OLDEST) ||
s.equals(DestinationLimitBehavior.REJECT_NEWEST) ||
s.equals(DestinationLimitBehavior.REMOVE_LOW_PRIORITY)) {
return;
}
throw new InvalidAttributeValueException(
"Invalid value for Destination LimitBehavior specified: " + s);
}
public void setLocalDeliveryPreferred(Boolean b) throws MBeanException {
try {
int cdp;
if (b.booleanValue()) {
cdp = ClusterDeliveryPolicy.LOCAL_PREFERRED;
} else {
cdp = ClusterDeliveryPolicy.DISTRIBUTED;
}
d.setClusterDeliveryPolicy(cdp);
d.update();
} catch (Exception e) {
handleSetterException(
DestinationAttributes.LOCAL_DELIVERY_PREFERRED, e);
}
}
public Boolean getLocalDeliveryPreferred() {
DestinationInfo di = DestinationUtil.getDestinationInfo(d);
if (di.destCDP == ClusterDeliveryPolicy.LOCAL_PREFERRED) {
return (Boolean.TRUE);
}
return (Boolean.FALSE);
}
public void setMaxBytesPerMsg(Long l) throws MBeanException {
try {
checkLongNegOneAndUp(l, DestinationAttributes.MAX_BYTES_PER_MSG);
SizeString ss = new SizeString();
ss.setBytes(l.longValue());
d.setMaxByteSize(ss);
d.update();
} catch (Exception e) {
handleSetterException(
DestinationAttributes.MAX_BYTES_PER_MSG, e);
}
}
public Long getMaxBytesPerMsg() {
DestinationInfo di = DestinationUtil.getDestinationInfo(d);
return (checkLongUnlimitedZero(new Long(di.maxMessageSize)));
}
public void setMaxNumActiveConsumers(Integer i) throws MBeanException {
try {
checkIntNegOneAndUp(i, DestinationAttributes.MAX_NUM_ACTIVE_CONSUMERS);
d.setMaxActiveConsumers(i.intValue());
d.update();
} catch (Exception e) {
handleSetterException(
DestinationAttributes.MAX_NUM_ACTIVE_CONSUMERS, e);
}
}
public Integer getMaxNumActiveConsumers() {
DestinationInfo di = DestinationUtil.getDestinationInfo(d);
return (new Integer(di.maxActiveConsumers));
}
public void setMaxNumBackupConsumers(Integer i) throws MBeanException {
try {
checkIntNegOneAndUp(i, DestinationAttributes.MAX_NUM_BACKUP_CONSUMERS);
d.setMaxFailoverConsumers(i.intValue());
d.update();
} catch (Exception e) {
handleSetterException(
DestinationAttributes.MAX_NUM_BACKUP_CONSUMERS, e);
}
}
public Integer getMaxNumBackupConsumers() {
DestinationInfo di = DestinationUtil.getDestinationInfo(d);
return (new Integer(di.maxFailoverConsumers));
}
public void setMaxNumMsgs(Long l) throws MBeanException {
try {
checkLongNegOneAndUp(l, DestinationAttributes.MAX_NUM_MSGS);
d.setCapacity(l.intValue());
d.update();
} catch (Exception e) {
handleSetterException(
DestinationAttributes.MAX_NUM_MSGS, e);
}
}
public Long getMaxNumMsgs() {
DestinationInfo di = DestinationUtil.getDestinationInfo(d);
return (checkLongUnlimitedZero(new Long(di.maxMessages)));
}
public void setMaxNumProducers(Integer i) throws MBeanException {
try {
checkIntNegOneAndUp(i, DestinationAttributes.MAX_NUM_PRODUCERS);
d.setMaxProducers(i.intValue());
d.update();
} catch (Exception e) {
handleSetterException(
DestinationAttributes.MAX_NUM_PRODUCERS, e);
}
}
public Integer getMaxNumProducers() {
DestinationInfo di = DestinationUtil.getDestinationInfo(d);
return (new Integer(di.maxProducers));
}
public void setMaxTotalMsgBytes(Long l) throws MBeanException {
try {
checkLongNegOneAndUp(l, DestinationAttributes.MAX_TOTAL_MSG_BYTES);
SizeString ss = new SizeString();
ss.setBytes(l.longValue());
d.setByteCapacity(ss);
d.update();
} catch (Exception e) {
handleSetterException(
DestinationAttributes.MAX_TOTAL_MSG_BYTES, e);
}
}
public Long getMaxTotalMsgBytes() {
DestinationInfo di = DestinationUtil.getDestinationInfo(d);
return (checkLongUnlimitedZero(new Long(di.maxMessageBytes)));
}
public String getName() {
return (d.getDestinationName());
}
public String getType() {
return (d.isQueue() ?
DestinationType.QUEUE : DestinationType.TOPIC);
}
public void setUseDMQ(Boolean b) throws MBeanException {
try {
d.setUseDMQ(b.booleanValue());
d.update();
} catch (Exception e) {
handleSetterException(
DestinationAttributes.USE_DMQ, e);
}
}
public Boolean getUseDMQ() {
DestinationInfo di = DestinationUtil.getDestinationInfo(d);
return (Boolean.valueOf(di.useDMQ));
}
public void setValidateXMLSchemaEnabled(Boolean b) throws MBeanException {
try {
d.setValidateXMLSchemaEnabled(b.booleanValue());
d.update();
} catch (Exception e) {
handleSetterException(
DestinationAttributes.VALIDATE_XML_SCHEMA_ENABLED, e);
}
}
public Boolean getValidateXMLSchemaEnabled() {
return (Boolean.valueOf(d.validateXMLSchemaEnabled()));
}
public void setXMLSchemaURIList(String s) throws MBeanException {
try {
d.setXMLSchemaUriList(s);
d.update();
} catch (Exception e) {
handleSetterException(
DestinationAttributes.XML_SCHEMA_URI_LIST, e);
}
}
public String getXMLSchemaURIList() {
return (d.getXMLSchemaUriList());
}
public void setReloadXMLSchemaOnFailure(Boolean b) throws MBeanException {
try {
d.setReloadXMLSchemaOnFailure(b.booleanValue());
d.update();
} catch (Exception e) {
handleSetterException(
DestinationAttributes.RELOAD_XML_SCHEMA_ON_FAILURE, e);
}
}
public Boolean getReloadXMLSchemaOnFailure() {
return (Boolean.valueOf(d.reloadXMLSchemaOnFailure()));
}
public void compact() throws MBeanException {
try {
if (!d.isPaused()) {
String msg = rb.getString(rb.E_DESTINATION_NOT_PAUSED);
String errMsg = rb.getString(rb.X_COMPACT_DST_EXCEPTION,
getName(), msg);
throw (new BrokerException(errMsg));
}
d.compact();
} catch (Exception e) {
handleOperationException(DestinationOperations.COMPACT, e);
}
}
public void pause() throws MBeanException {
pause(DestinationPauseType.ALL);
}
public void pause(String pauseType) throws MBeanException {
try {
DestinationUtil.checkPauseType(pauseType);
logger.log(Logger.INFO, rb.I_PAUSING_DST_WITH_PAUSE_TYPE,
getType() + ":" + getName(),
pauseType);
int pauseVal = DestinationUtil.toInternalPauseType(pauseType);
d.pauseDestination(pauseVal);
} catch (Exception e) {
handleOperationException(DestinationOperations.PAUSE, e);
}
}
public void purge() throws MBeanException {
try {
String criteria_str = Globals.getBrokerResources().getKString(
rb.I_ALL_PURGE_CRITERIA);
logger.log(Logger.INFO, rb.I_PURGING_DESTINATION, getName(),
criteria_str);
d.purgeDestination();
} catch (Exception e) {
handleOperationException(DestinationOperations.PURGE, e);
}
}
public void resume() throws MBeanException {
try {
logger.log(Logger.INFO, rb.I_RESUMING_DST, getName());
d.resumeDestination();
} catch (Exception e) {
handleOperationException(DestinationOperations.RESUME, e);
}
}
public String getMBeanName() {
return ("DestinationConfig");
}
public String getMBeanDescription() {
return (mbr.getString(mbr.I_DST_CFG_DESC));
}
public MBeanAttributeInfo[] getMBeanAttributeInfo() {
return (attrs);
}
public MBeanOperationInfo[] getMBeanOperationInfo() {
return (ops);
}
public MBeanNotificationInfo[] getMBeanNotificationInfo() {
return (notifs);
}
public void notifyDestinationAttrUpdated(int attr, Object oldVal, Object newVal) {
String attrName;
attrName = DestinationUtil.getAttrNameFromDestinationInfoAttr(attr);
if (attrName != null) {
notifyAttrChange(attrName, newVal, oldVal);
} else {
logger.log(Logger.WARNING,
getMBeanDescription()
+
": Unknown attribute updated in destination "
+ d.toString());
}
}
/*
* There are 3 attributes that represent 'unlimited' as the value
* zero (0) internally:
*
* MaxNumMsgs
* MaxTotalMsgBytes
* MaxBytesPerMsg
*
* This internal value is always zero even if we set it to -1.
* For these attributes (internally, at least), setting them to
* 0 or -1 is equivalent i.e. both mean unlimited.
*
* To be consistent, it is necessary to intercept get requests
* on these attributes and return -1 whenever we see 0.
* This is done similarly in imqcmd.
*
* It is important to no blatantly use this method everywhere
* because for some attributes, 0 does not mean unlimited.
*/
private Long checkLongUnlimitedZero(Long l) {
if (l.longValue() == 0) {
return (new Long(-1));
}
return (l);
}
private void checkLongNegOneAndUp(Long l, String attrName)
throws InvalidAttributeValueException {
if (l.longValue() >= -1) {
return;
}
throw new InvalidAttributeValueException(
"Invalid value for attribute "
+ attrName
+ ": "
+ l
+ ". Please use a positive number or -1");
}
private void checkIntNegOneAndUp(Integer i, String attrName)
throws InvalidAttributeValueException {
if (i.intValue() >= -1) {
return;
}
throw new InvalidAttributeValueException(
"Invalid value for attribute "
+ attrName
+ ": "
+ i
+ ". Please use a positive number or -1");
}
private void notifyAttrChange(String attrName, Object newVal, Object oldVal) {
sendNotification(
new AttributeChangeNotification(this, sequenceNumber++, new Date().getTime(),
"Attribute change", attrName, newVal.getClass().getName(),
oldVal, newVal));
}
}