}
Long lsessionid = (Long)props.get("JMQSessionID");
Session session = null;
String err_reason = null;
Boolean blockprop = (Boolean)props.get("JMQBlock");
Consumer newc = null;
assert blockprop == null || msg.getPacketType() == PacketType.DELETE_CONSUMER
: msg;
boolean blockprop_bool = (blockprop != null && blockprop.booleanValue());
boolean isIndemp = msg.getIndempotent();
// OK ... set up the reply packet
Packet pkt = new Packet(con.useDirectBuffers());
pkt.setConsumerID(msg.getConsumerID()); // correlation ID
Hashtable hash = new Hashtable();
pkt.setPacketType(msg.getPacketType() + 1);
int status = Status.OK;
String warning = BrokerResources.W_ADD_CONSUMER_FAILED;
ConsumerUID uid = null;
Integer destType = null;
Integer oldid = null;
Subscription sub = null;
try {
con.suspend();
conPaused = true;
if (msg.getPacketType() == PacketType.ADD_CONSUMER) {
if (DEBUG) {
logger.log(Logger.DEBUGHIGH, "ConsumerHandler: handle() "
+ "[ Received AddConsumer message {0}]", msg.toString());
}
pkt.setPacketType(PacketType.ADD_CONSUMER_REPLY);
if (lsessionid == null) {
if (DEBUG)
logger.log(Logger.DEBUG,"not Raptor consumer packet (no session id)");
// assign session same # as consumer
SessionUID sessionID = new SessionUID(
con.getConnectionUID().longValue());
// single threaded .. we dont have to worry about
// someone else creating it
session = con.getSession(sessionID);
if (session == null) {
session = Session.createSession(sessionID,
con.getConnectionUID(), null);
con.attachSession(session);
}
} else {
SessionUID sessionID = new SessionUID(lsessionid.longValue());
session = con.getSession(sessionID);
if (session == null) {
throw new BrokerException("Internal Error: client set invalid"
+ " sessionUID " + sessionID + " session does not exist");
}
}
if (blockprop_bool) { // turn off all processing
session.pause("Consumer - Block flag");
sessionPaused = true;
}
/* XXX-LKS KLUDGE FOR 2.0 compatibility */
// for now, we just pass the consumer ID back on the old
// packet .. I need to revisit this in the future
oldid = (Integer)props.get("JMQConsumerID"); // old consumer ID
if (oldid != null)
hash.put("JMQOldConsumerID", oldid);
if (props == null) {
throw new BrokerException(Globals.getBrokerResources().getString(
BrokerResources.X_INTERNAL_EXCEPTION,"no properties in addConsumer "
+ "packet - client does not match protocol"));
}
Integer inttype = (Integer )props.get("JMQDestType");
int type = (inttype == null ? -1 : inttype.intValue());
if (type == -1) {
throw new BrokerException(Globals.getBrokerResources().getString(
BrokerResources.X_INTERNAL_EXCEPTION,"Client is not sending DestType, "
+ "unable to add interest"));
}
boolean queue = DestType.isQueue(type) ;
String destination = (String)props.get("JMQDestination");
String selector = (String)props.get("JMQSelector");
Boolean nolocal = (Boolean)props.get("JMQNoLocal");
String durablename = (String)props.get("JMQDurableName");
String clientid = getClientID(props, con);
Boolean reconnect = (Boolean)props.get("JMQReconnect");
Boolean share = (Boolean)props.get("JMQShare");
Integer size = (Integer)props.get("JMQSize");
if (queue && nolocal != null && nolocal.booleanValue()) {
Globals.getLogger().log(Logger.ERROR, BrokerResources.E_INTERNAL_BROKER_ERROR,
"NoLocal is not supported on Queue Receivers");
throw new BrokerException("Unsupported property on queues JMQNoLocal "
+ "is set to " + nolocal, Status.ERROR);
}
if (reconnect != null && reconnect.booleanValue()) {
Globals.getLogger().log(Logger.ERROR,
BrokerResources.E_INTERNAL_BROKER_ERROR,
"JMQReconnect not implemented");
}
if (share != null && share.booleanValue() &&
! ClientIDHandler.CAN_USE_SHARED_CONSUMERS) {
throw new BrokerException(
Globals.getBrokerResources().getKString(
BrokerResources.X_FEATURE_UNAVAILABLE,
Globals.getBrokerResources().getKString(
BrokerResources.M_SHARED_CONS), destination),
BrokerResources.X_FEATURE_UNAVAILABLE,
(Throwable) null,
Status.NOT_ALLOWED);
}
// see if we are a wildcard destination
DestinationUID dest_uid = null;
Destination d = null;
if (DestinationUID.isWildcard(destination)) { // dont create a destination
dest_uid = DestinationUID.getUID(destination, DestType.isQueue(type));
} else {
d = null;
while (true ) {
d = Destination.getDestination(destination,
type, true /* autocreate if possible*/,
!con.isAdminConnection());
if (d.isAutoCreated())
warning = BrokerResources.W_ADD_AUTO_CONSUMER_FAILED;
try {
if (d != null)
d.incrementRefCount();
} catch (BrokerException ex) {
continue; // was destroyed in process
} catch (IllegalStateException ex) {
throw new BrokerException(
Globals.getBrokerResources().getKString(
BrokerResources.X_SHUTTING_DOWN_BROKER),
BrokerResources.X_SHUTTING_DOWN_BROKER,
ex,
Status.ERROR);
}
break; // we got one
}
if (d == null) {
// unable to autocreate destination
status = Status.NOT_FOUND;
// XXX error
throw new BrokerException(
Globals.getBrokerResources().getKString(
BrokerResources.X_DESTINATION_NOT_FOUND, destination),
BrokerResources.X_DESTINATION_NOT_FOUND,
null,
Status.NOT_FOUND);
}
dest_uid = d.getDestinationUID();
}
// Must have a clientID to add a durable
if (durablename != null && clientid == null) {
throw new BrokerException(
Globals.getBrokerResources().getKString(
BrokerResources.X_NO_CLIENTID, durablename),
BrokerResources.X_NO_CLIENTID,
null,
Status.PRECONDITION_FAILED);
}
Consumer c = null;
try {
//LKS
Consumer[] retc = createConsumer( dest_uid, con,
session, selector, clientid,
durablename, (nolocal != null && nolocal.booleanValue()),
(size == null ? -1 : size.intValue()),
(share != null && share.booleanValue()),
msg.getSysMessageID().toString(), isIndemp, true);
c = retc[0];
newc = retc[1];
sub = (Subscription)retc[2];
if (c.getPrefetch() != -1 || size != null)
hash.put("JMQSize", c.getPrefetch());
} catch (SelectorFormatException ex) {
throw new BrokerException(
Globals.getBrokerResources().getKString(
BrokerResources.W_SELECTOR_PARSE, selector),
BrokerResources.W_SELECTOR_PARSE,
ex,
Status.BAD_REQUEST);
} catch (OutOfLimitsException ex) {
if (d != null && d.isQueue()) {
String args[] = { dest_uid.getName(),
String.valueOf(d.getActiveConsumerCount()),
String.valueOf(d.getFailoverConsumerCount()) };
throw new BrokerException(
Globals.getBrokerResources().getKString(
BrokerResources.X_S_QUEUE_ATTACH_FAILED, args),
BrokerResources.X_S_QUEUE_ATTACH_FAILED,
ex,
Status.CONFLICT);
} else { // durable
String args[] = { dest_uid.getName(),
durablename, clientid,
String.valueOf(ex.getLimit()) };
throw new BrokerException(
Globals.getBrokerResources().getKString(
BrokerResources.X_S_DUR_ATTACH_FAILED, args),
BrokerResources.X_S_DUR_ATTACH_FAILED,
ex,
Status.CONFLICT);
}
} finally {
if (d != null)
d.decrementRefCount();
}
// add the consumer to the session
Integer acktype = (Integer)props.get("JMQAckMode");
if (acktype != null) {
c.getConsumerUID().setAckType(acktype.intValue());
}
uid = c.getConsumerUID();
} else { // removing Interest
if (DEBUG) {
logger.log(Logger.DEBUGHIGH,
"ConsumerHandler: handle() [ Received DestroyConsumer message {0}]",
msg.toString());
}
warning = BrokerResources.W_DESTROY_CONSUMER_FAILED;
pkt.setPacketType(PacketType.DELETE_CONSUMER_REPLY);
String durableName = (String)props.get("JMQDurableName");
String clientID = getClientID(props, con);
Long cid = (Long)props.get("JMQConsumerID");
uid = (cid == null ? null : new ConsumerUID( cid.longValue()));
if (lsessionid != null) { // passed on in
SessionUID sessionID = new SessionUID(lsessionid.longValue());
session = con.getSession(sessionID);
} else {
session = Session.getSession(uid);
}
if (session == null && durableName == null && !isIndemp) {
if (con.getConnectionState() < Connection.STATE_CLOSED) {
logger.log(Logger.ERROR,"Internal error processing"+
" delete consumer\n"+
com.sun.messaging.jmq.jmsserver.util
.PacketUtil.dumpPacket(msg));
Session.dumpAll();
}
}
// retrieve the LastDelivered property
Integer bodytype = (Integer)props.get("JMQBodyType");
int btype = (bodytype == null ? 0 : bodytype.intValue());
SysMessageID lastid = null;
if (btype == PacketType.SYSMESSAGEID) {
int size = msg.getMessageBodySize();
if (size == 0) {
logger.log(Logger.INFO,"Warning, bad body in destroy consumer");
} else {
DataInputStream is = new DataInputStream(
msg.getMessageBodyStream());
lastid = new SysMessageID();
lastid.readID(is);
}
}
if (DEBUG && lastid != null) {
logger.log(Logger.DEBUG,"Sent lastID [" + lastid + "]"
+ " for consumer " + uid + Destination.get(lastid));
}
Boolean rAll = (Boolean)props.get("JMQRedeliverAll");
boolean redeliverAll = (rAll == null ? false : rAll.booleanValue());
if (!sessionPaused && session != null) {
sessionPaused = true;
session.pause("Consumer removeconsumer");
}
destroyConsumer(con, session, uid, durableName, clientID, lastid,
redeliverAll, isIndemp);
}
} catch (BrokerException ex) {
status = ex.getStatusCode();
String consumid = null;
String destination = null;
try {
destination = (String) props.get("JMQDestination");
if (destination == null && msg.getPacketType()
!= PacketType.ADD_CONSUMER)
destination = "";
if (oldid != null)
consumid = oldid.toString();
else
consumid = "";
} catch (Exception ex1) {}
String args[] = {consumid, con.getRemoteConnectionString(), destination};
err_reason = ex.getMessage();
if (ex.getStatusCode() == Status.PRECONDITION_FAILED
|| ex.getStatusCode() == Status.CONFLICT ) {
logger.log(Logger.WARNING, warning, args, ex);
} else if (ex.getStatusCode() == Status.BAD_REQUEST) {
// Probably a bad selector
logger.log(Logger.WARNING, warning, args, ex);
if (ex.getCause() != null) {
logger.log(Logger.INFO, ex.getCause().toString());
}
} else {
if (isIndemp && msg.getPacketType() == PacketType.DELETE_CONSUMER) {
logger.logStack(Logger.DEBUG, "Reprocessing Indempotent message for "
+ "{0} on destination {2} from {1}",args, ex);
status = Status.OK;
err_reason = null;
} else {
logger.logStack(Logger.WARNING, warning,args, ex);
}
}
} catch (IOException ex) {
logger.log(Logger.INFO,"Internal Error: unable to process "+
" consumer request " + msg, ex);
props = new Hashtable();
err_reason = ex.getMessage();
assert false;
} catch (SecurityException ex) {
status = Status.FORBIDDEN;
err_reason = ex.getMessage();
String destination = null;
String consumid = null;
try {
destination = (String) props.get("JMQDestination");
if (oldid != null)
consumid = oldid.toString();
} catch (Exception ex1) {}
logger.log(Logger.WARNING, warning, destination, consumid,ex);
} finally {
if (conPaused)
con.resume();
}
hash.put("JMQStatus", new Integer(status));
if (err_reason != null)
hash.put("JMQReason", err_reason);
if (uid != null) {
hash.put("JMQConsumerID", new Long(uid.longValue()));
if (DEBUG || logger.getLevel() <= Logger.DEBUG) {
if (props.get("JMQOldConsumerID") != null ) {
logger.log(Logger.INFO, "Consumer "+ uid+ ", JMQOldConsumerID:"+
props.get("JMQOldConsumerID"));
}
}
}
if (destType != null)
hash.put("JMQDestType", destType);
if (((IMQBasicConnection)con).getDumpPacket() ||
((IMQBasicConnection)con).getDumpOutPacket())
hash.put("JMQReqID", msg.getSysMessageID().toString());
pkt.setProperties(hash);
con.sendControlMessage(pkt);
if (sessionPaused)
session.resume("Consumer - session was paused");
if (sub != null)
sub.resume("Consumer - added to sub");
if (newc != null)