Search in sources :

Example 1 with IMQBasicConnection

use of com.sun.messaging.jmq.jmsserver.service.imq.IMQBasicConnection in project openmq by eclipse-ee4j.

the class AdminDataHandler method sendReply.

/**
 * Send a reply to an administration command message.
 *
 * @param con Connection cmd_msg came in on
 * @param cmd_msg Administrative command message from client
 * @param reply_msg Broker's reply to cmd_msg.
 */
public SysMessageID sendReply(IMQConnection con, Packet cmd_msg, Packet reply_msg) {
    try {
        // We send message to the ReplyTo destination
        String destination = cmd_msg.getReplyTo();
        if (destination == null) {
            // Programming error. No need to I18N
            logger.log(Logger.ERROR, rb.E_INTERNAL_BROKER_ERROR, "Administration message has no ReplyTo destination. Not replying.");
            return null;
        }
        reply_msg.setDestination(destination);
        reply_msg.setIsQueue(true);
        // Make sure message is not persistent, in a transaction, or ACK'd
        reply_msg.setPersistent(false);
        reply_msg.setTransactionID(0);
        reply_msg.setSendAcknowledge(false);
        // Set port number and IP of packet
        if (con instanceof IMQBasicConnection) {
            reply_msg.setPort(((IMQBasicConnection) con).getLocalPort());
        }
        reply_msg.setIP(Globals.getBrokerInetAddress().getAddress());
        // Set sequence number and timestamp on packet. This is typically
        // done by writePacket(), but since we're simulating an incomming
        // packet we must to it now.
        reply_msg.updateTimestamp();
        reply_msg.updateSequenceNumber();
        // Turn off auto-generation of timestamp and sequence for this packet
        // This ensures the values we just set are never overwritten.
        reply_msg.generateTimestamp(false);
        reply_msg.generateSequenceNumber(false);
        if (DEBUG) {
            try {
                logger.log(Logger.DEBUG, "AdminDataHandler: REPLY: " + reply_msg + ": " + reply_msg.getProperties());
            } catch (IOException | ClassNotFoundException e) {
                // Programming error. No need to I18N
                logger.logStack(Logger.WARNING, rb.E_INTERNAL_BROKER_ERROR, "Admin: Could not extract properties from pkt", e);
            }
        }
        SysMessageID mid = reply_msg.getSysMessageID();
        // DataHandler's handle method will treat this as a message being
        // sent by a client.
        // XXX REVISIT 08/30/00 dipol: can 'con' be null to indicate
        // message is originating from an internal source?
        super.handle(con, reply_msg, true);
        return mid;
    } catch (Exception e) {
        logger.logStack(Logger.ERROR, rb.E_INTERNAL_BROKER_ERROR, "Could not reply to administrative message.", e);
    }
    return null;
}
Also used : SysMessageID(com.sun.messaging.jmq.io.SysMessageID) IOException(java.io.IOException) IMQBasicConnection(com.sun.messaging.jmq.jmsserver.service.imq.IMQBasicConnection) IOException(java.io.IOException) BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException)

Example 2 with IMQBasicConnection

use of com.sun.messaging.jmq.jmsserver.service.imq.IMQBasicConnection in project openmq by eclipse-ee4j.

the class DestinationList method destroyConnections.

private static void destroyConnections(Set destroyConns, int reason, String reasonstr) {
    ConnectionManager cm = Globals.getConnectionManager();
    Iterator cnitr = destroyConns.iterator();
    while (cnitr.hasNext()) {
        IMQBasicConnection conn = (IMQBasicConnection) cm.getConnection((ConnectionUID) cnitr.next());
        if (conn == null) {
            continue;
        }
        Globals.getLogger().log(Logger.INFO, "Destroying connection " + conn + " because " + reasonstr);
        if (DEBUG) {
            conn.dump();
        }
        conn.destroyConnection(true, reason, reasonstr);
        conn.waitForRelease(Globals.getConfig().getLongProperty(Globals.IMQ + "." + conn.getService().getName() + ".destroy_timeout", 30) * 1000);
    }
}
Also used : ConnectionManager(com.sun.messaging.jmq.jmsserver.service.ConnectionManager) ConnectionUID(com.sun.messaging.jmq.jmsserver.service.ConnectionUID) IMQBasicConnection(com.sun.messaging.jmq.jmsserver.service.imq.IMQBasicConnection)

Example 3 with IMQBasicConnection

use of com.sun.messaging.jmq.jmsserver.service.imq.IMQBasicConnection in project openmq by eclipse-ee4j.

the class MigrateStoreHandler method handle.

/**
 * Handle the incomming administration message.
 *
 * @param con The Connection the message came in on.
 * @param cmd_msg The administration message
 * @param cmd_props The properties from the administration message
 */
@Override
public boolean handle(IMQConnection con, Packet cmd_msg, Hashtable cmd_props) {
    boolean noop = true;
    int status = Status.OK;
    String errMsg = "";
    if (DEBUG) {
        logger.log(Logger.INFO, this.getClass().getName() + ": " + "Request migrate this broker''s store: " + cmd_props);
    }
    String brokerID = (String) cmd_props.get(MessageType.JMQ_BROKER_ID);
    String partition = (String) cmd_props.get(MessageType.JMQ_MIGRATESTORE_PARTITION);
    if (partition == null) {
        if (brokerID != null) {
            logger.log(Logger.INFO, BrokerResources.I_ADMIN_MIGRATESTORE_TO, brokerID);
        } else {
            logger.log(Logger.INFO, BrokerResources.I_ADMIN_MIGRATESTORE);
        }
    } else {
        logger.log(Logger.INFO, "XXXAdmin request migrate this broker's store partition " + partition + " to broker " + brokerID);
    }
    HAMonitorService hamonitor = Globals.getHAMonitorService();
    if (hamonitor != null && hamonitor.inTakeover()) {
        status = Status.NOT_MODIFIED;
        errMsg = rb.getString(rb.E_CANNOT_PROCEED_TAKEOVER_IN_PROCESS);
        logger.log(Logger.ERROR, this.getClass().getName() + ": " + errMsg);
    }
    if (status == Status.OK) {
        if (partition == null && Globals.getHAEnabled()) {
            status = Status.NOT_MODIFIED;
            errMsg = rb.getKString(rb.E_OPERATION_NOT_SUPPORTED_IN_HA, MessageType.getString(MessageType.MIGRATESTORE_BROKER));
            logger.log(Logger.ERROR, errMsg);
        }
    }
    if (status == Status.OK) {
        if (Globals.isJMSRAManagedBroker()) {
            status = Status.NOT_MODIFIED;
            errMsg = "Can not process migration store request because this broker's life cycle is JMSRA managed";
            logger.log(Logger.ERROR, this.getClass().getName() + ": " + errMsg);
        }
    }
    UID partitionID = null;
    if (status == Status.OK) {
        if (partition != null) {
            try {
                long v = Long.parseLong(partition);
                partitionID = new UID(v);
            } catch (Exception e) {
                partitionID = null;
                status = Status.NOT_MODIFIED;
                errMsg = "XXXCan not process migration partition " + partition + " request because unable to parse " + partition + ": " + e;
                logger.log(Logger.ERROR, errMsg);
            }
        }
    }
    if (status == Status.OK) {
        if (partitionID != null && brokerID == null) {
            status = Status.NOT_MODIFIED;
            errMsg = "XXXCan not process migration partition " + partitionID + " request because brokerID not specified";
            logger.log(Logger.ERROR, errMsg);
        }
    }
    if (status == Status.OK) {
        if (partitionID != null && !(DL.isPartitionMode() && DL.isPartitionMigratable())) {
            status = Status.NOT_MODIFIED;
            errMsg = "XXXCan not process migration partition " + partitionID + " request because partition mode not enabled";
            logger.log(Logger.ERROR, errMsg);
        }
    }
    if (status == Status.OK) {
        if (partitionID != null) {
            DestinationList dl = DL.getDestinationList(partitionID);
            if (dl == null) {
                status = Status.NOT_MODIFIED;
                errMsg = "XXXCan not process migration partition " + partitionID + " request because partition " + partitionID + " not found";
                logger.log(Logger.ERROR, errMsg);
            } else if (dl.getPartitionedStore().isPrimaryPartition()) {
                status = Status.NOT_MODIFIED;
                errMsg = "XXXCan not process migration partition " + partitionID + " request because partition " + partitionID + " is the primary partition";
                logger.log(Logger.ERROR, errMsg);
            }
        }
    }
    if (status == Status.OK) {
        if (brokerID == null) {
            try {
                brokerID = getBrokerID();
            } catch (Throwable t) {
                status = Status.NOT_MODIFIED;
                errMsg = "Unable to get a connected broker to takeover this broker's store: " + t.getMessage();
                if ((t instanceof OperationNotAllowedException) && ((OperationNotAllowedException) t).getOperation().equals(MessageType.getString(MessageType.MIGRATESTORE_BROKER))) {
                    logger.log(logger.ERROR, errMsg);
                } else {
                    logger.logStack(logger.ERROR, errMsg, t);
                }
            }
        }
    }
    if (status != Status.OK) {
        sendReply(con, cmd_msg, brokerID, null, errMsg, status, null);
        return true;
    }
    try {
        BrokerStateHandler.setExclusiveRequestLock(ExclusiveRequest.MIGRATE_STORE);
    } catch (Throwable t) {
        status = Status.PRECONDITION_FAILED;
        if (t instanceof BrokerException) {
            status = ((BrokerException) t).getStatusCode();
        }
        errMsg = MessageType.getString(MessageType.MIGRATESTORE_BROKER) + ": " + Status.getString(status) + " - " + t.getMessage();
        logger.log(Logger.ERROR, errMsg);
        status = Status.NOT_MODIFIED;
    }
    try {
        if (partitionID != null) {
            migratePartition(con, cmd_msg, partitionID, brokerID);
            return true;
        }
        Long syncTimeout = null;
        final BrokerStateHandler bsh = Globals.getBrokerStateHandler();
        if (status == Status.OK) {
            try {
                syncTimeout = (Long) cmd_props.get(MessageType.JMQ_MIGRATESTORE_SYNC_TIMEOUT);
                ClusterManager cm = Globals.getClusterManager();
                BrokerMQAddress self = (BrokerMQAddress) cm.getMQAddress();
                BrokerMQAddress master = (cm.getMasterBroker() == null ? null : (BrokerMQAddress) cm.getMasterBroker().getBrokerURL());
                if (self.equals(master)) {
                    throw new BrokerException(rb.getKString(rb.E_CHANGE_MASTER_BROKER_FIRST, MessageType.getString(MessageType.MIGRATESTORE_BROKER)), Status.NOT_ALLOWED);
                }
            } catch (Throwable t) {
                status = Status.PRECONDITION_FAILED;
                if (t instanceof BrokerException) {
                    status = ((BrokerException) t).getStatusCode();
                }
                errMsg = MessageType.getString(MessageType.MIGRATESTORE_BROKER) + ": " + Status.getString(status) + " - " + t.getMessage();
                logger.log(Logger.ERROR, errMsg);
                status = Status.NOT_MODIFIED;
            }
        }
        SysMessageID replyMessageID = null;
        String replyStatusStr = null;
        try {
            // shutdown if !noop
            String hostport = null;
            if (status == Status.OK) {
                try {
                    noop = false;
                    hostport = bsh.takeoverME(brokerID, syncTimeout, con);
                } catch (BrokerException ex) {
                    status = ex.getStatusCode();
                    if (status == Status.BAD_REQUEST || status == Status.NOT_ALLOWED || status == Status.NOT_MODIFIED || status == Status.UNAVAILABLE || status == Status.PRECONDITION_FAILED) {
                        status = Status.PRECONDITION_FAILED;
                        if (ex instanceof OperationNotAllowedException) {
                            if (((OperationNotAllowedException) ex).getOperation().equals(MessageType.getString(MessageType.MIGRATESTORE_BROKER))) {
                                status = Status.NOT_MODIFIED;
                                noop = true;
                            }
                        }
                        errMsg = Globals.getBrokerResources().getKString(BrokerResources.E_FAIL_MIGRATESTORE_NOT_MIGRATED, ex.getMessage());
                        if (noop) {
                            logger.log(Logger.ERROR, errMsg);
                        } else {
                            logger.logStack(Logger.ERROR, errMsg, ex);
                        }
                    } else {
                        status = Status.EXPECTATION_FAILED;
                        errMsg = Globals.getBrokerResources().getKString(BrokerResources.E_FAIL_TAKEOVERME, brokerID, ex.getMessage());
                        logger.logStack(Logger.ERROR, errMsg, ex);
                    }
                }
            }
            if (status == Status.OK) {
                try {
                    Globals.getClusterBroadcast().stopClusterIO(false, true, null);
                } catch (Throwable t) {
                    logger.logStack(Logger.WARNING, "Failed to stop cluster IO", t);
                }
            }
            List ret = sendReply(con, cmd_msg, brokerID, hostport, errMsg, status, null);
            replyMessageID = (SysMessageID) ret.get(0);
            replyStatusStr = (String) ret.get(1);
        } finally {
            final SysMessageID mid = replyMessageID;
            final String statusStr = replyStatusStr;
            if (!noop) {
                try {
                    if (con instanceof IMQBasicConnection) {
                        IMQBasicConnection ipCon = (IMQBasicConnection) con;
                        ipCon.flushControl(1000);
                    }
                    try {
                        Globals.getServiceManager().stopNewConnections(ServiceType.NORMAL);
                    } catch (Exception e) {
                        logger.logStack(logger.WARNING, rb.getKString(rb.W_STOP_SERVICE_FAIL, ServiceType.getServiceTypeString(ServiceType.NORMAL), e.getMessage()), e);
                    }
                    try {
                        Globals.getServiceManager().stopNewConnections(ServiceType.ADMIN);
                    } catch (Exception e) {
                        logger.logStack(logger.WARNING, rb.getKString(rb.W_STOP_SERVICE_FAIL, ServiceType.getServiceTypeString(ServiceType.ADMIN), e.getMessage()), e);
                    }
                    BrokerStateHandler.setShuttingDown(true);
                    bsh.prepareShutdown(false, true);
                    waitForHandlersToComplete(20);
                    if (mid == null) {
                        logger.log(Logger.INFO, BrokerResources.I_ADMIN_SHUTDOWN_REQUEST);
                        bsh.initiateShutdown("admin", 0, false, 0, true);
                        return true;
                    }
                    final String waitstr = rb.getKString(rb.I_WAIT_ADMIN_RECEIVE_REPLY, MessageType.getString(MessageType.MIGRATESTORE_BROKER_REPLY) + "[" + statusStr + "]");
                    final long totalwait = Globals.getConfig().getIntProperty(MAX_WAIT_ADMIN_CLIENT_PROP, DEFAULT_MAX_WAIT_ADMIN_CLIENT) * 1000L;
                    final IMQConnection conn = con;
                    Executors.newSingleThreadExecutor().execute(new Runnable() {

                        @Override
                        public void run() {
                            try {
                                long waited = 0L;
                                while (conn.getConnectionState() < Connection.STATE_CLEANED && waited < totalwait) {
                                    logger.log(logger.INFO, waitstr);
                                    try {
                                        Thread.sleep(500);
                                        waited += 500L;
                                    } catch (Exception e) {
                                    /* ignore */
                                    }
                                }
                                logger.log(Logger.INFO, BrokerResources.I_ADMIN_SHUTDOWN_REQUEST);
                                bsh.initiateShutdown("admin-migratestore-shutdown", 0, false, 0, true);
                            } catch (Throwable t) {
                                bsh.initiateShutdown("admin-migratestore-shutdown::[" + t.toString() + "]", 0, false, 0, true);
                            }
                        }
                    });
                } catch (Throwable t) {
                    bsh.initiateShutdown("admin-migratestore-shutdown:[" + t.toString() + "]", 0, false, 0, true);
                }
            }
        }
    } finally {
        BrokerStateHandler.unsetExclusiveRequestLock(ExclusiveRequest.MIGRATE_STORE);
    }
    return true;
}
Also used : BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException) BrokerStateHandler(com.sun.messaging.jmq.jmsserver.BrokerStateHandler) DestinationList(com.sun.messaging.jmq.jmsserver.core.DestinationList) IMQBasicConnection(com.sun.messaging.jmq.jmsserver.service.imq.IMQBasicConnection) OperationNotAllowedException(com.sun.messaging.jmq.jmsserver.util.OperationNotAllowedException) OperationNotAllowedException(com.sun.messaging.jmq.jmsserver.util.OperationNotAllowedException) BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException) BrokerMQAddress(com.sun.messaging.jmq.jmsserver.core.BrokerMQAddress) UID(com.sun.messaging.jmq.util.UID) IMQConnection(com.sun.messaging.jmq.jmsserver.service.imq.IMQConnection) SysMessageID(com.sun.messaging.jmq.io.SysMessageID) DestinationList(com.sun.messaging.jmq.jmsserver.core.DestinationList) ArrayList(java.util.ArrayList) List(java.util.List)

Example 4 with IMQBasicConnection

use of com.sun.messaging.jmq.jmsserver.service.imq.IMQBasicConnection in project openmq by eclipse-ee4j.

the class GoodbyeHandler method handle.

/**
 * Method to handle goodbye messages
 */
@Override
public boolean handle(IMQConnection con, Packet msg) throws BrokerException {
    Hashtable props = null;
    try {
        props = msg.getProperties();
    } catch (Exception ex) {
        logger.logStack(Logger.WARNING, "GOODBY Packet.getProperties()", ex);
        props = new Hashtable();
    }
    boolean notAuthenticated = !con.isAuthenticated();
    if (con.isValid() && notAuthenticated) {
        logger.log(Logger.WARNING, Globals.getBrokerResources().getKString(BrokerResources.W_RECEIVED_GOODBYE_UNAUTHENTICATED_CONN, con.getConnectionUID().longValue() + "[" + con.getRemoteConnectionString() + "]"));
    }
    Boolean blockprop = (props != null ? (Boolean) props.get("JMQBlock") : null);
    boolean block = (blockprop != null && blockprop.booleanValue());
    // send the reply (if necessary)
    con.stopConnection();
    if (block) {
        con.cleanupConnection();
    }
    boolean destroy = false;
    if (msg.getSendAcknowledge()) {
        Packet pkt = new Packet(con.useDirectBuffers());
        pkt.setPacketType(PacketType.GOODBYE_REPLY);
        pkt.setConsumerID(msg.getConsumerID());
        Hashtable hash = new Hashtable();
        hash.put("JMQStatus", Integer.valueOf(Status.OK));
        if (((IMQBasicConnection) con).getDumpPacket() || ((IMQBasicConnection) con).getDumpOutPacket()) {
            hash.put("JMQReqID", msg.getSysMessageID().toString());
        }
        pkt.setProperties(hash);
        con.sendControlMessage(pkt);
        // increase timeout
        if (con.isBlocking()) {
            if (con instanceof IMQBasicConnection) {
                IMQBasicConnection ipCon = (IMQBasicConnection) con;
                ipCon.flushControl(timeout);
            }
            destroy = true;
        } else {
            con.setDestroyReason(Globals.getBrokerResources().getKString(BrokerResources.M_CLIENT_SHUTDOWN));
            GoodbyeTask.addConnection(con.getConnectionUID(), Globals.getBrokerResources().getKString(BrokerResources.M_CLIENT_SHUTDOWN));
        }
    } else {
        destroy = true;
    }
    if (destroy) {
        con.destroyConnection(false, /* no reply */
        GoodbyeReason.CLIENT_CLOSED, Globals.getBrokerResources().getKString(BrokerResources.M_CLIENT_SHUTDOWN));
    }
    return true;
}
Also used : Packet(com.sun.messaging.jmq.io.Packet) IMQBasicConnection(com.sun.messaging.jmq.jmsserver.service.imq.IMQBasicConnection) BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException)

Example 5 with IMQBasicConnection

use of com.sun.messaging.jmq.jmsserver.service.imq.IMQBasicConnection in project openmq by eclipse-ee4j.

the class HelloHandler method handle.

/**
 * Method to handle HELLO messages
 */
@Override
public boolean handle(IMQConnection con, Packet msg) throws BrokerException {
    if (DEBUG) {
        logger.log(Logger.DEBUGHIGH, "HelloHandler: handle() [ Received Hello Message]");
    }
    String reason = null;
    Hashtable hello_props = null;
    try {
        hello_props = msg.getProperties();
    } catch (Exception ex) {
        logger.logStack(Logger.WARNING, "HELLO Packet.getProperties()", ex);
        hello_props = new Hashtable();
    }
    boolean alreadyStarted = con.isStarted();
    boolean alreadyAuthenticated = con.isAuthenticated();
    int requestedProtocol = 0;
    int highestProtocol = con.getHighestSupportedProtocol();
    int lowestProtocol = PacketType.VERSION1;
    String expectedClusterID = null;
    UID expectedSessionID = null;
    ConnectionUID oldCID = null;
    Integer bufsize = null;
    String destprov = null;
    if (hello_props != null) {
        Integer level = (Integer) hello_props.get("JMQProtocolLevel");
        String clientv = (String) hello_props.get("JMQVersion");
        if (DEBUG) {
            logger.log(logger.INFO, "HelloHandler.handle(): Client[" + clientv + ", " + level + "] " + con);
        }
        if (level == null) {
            requestedProtocol = PacketType.VERSION1;
        } else {
            requestedProtocol = level.intValue();
        }
        bufsize = (Integer) hello_props.get("JMQSize");
        if (bufsize == null) {
            // XXX try old protocol
            bufsize = (Integer) hello_props.get("JMQRBufferSize");
        }
        // Retrieve HA related properties
        Long longUID = (Long) hello_props.get("JMQStoreSession");
        if (longUID != null) {
            expectedSessionID = new UID(longUID.longValue());
        }
        expectedClusterID = (String) hello_props.get("JMQClusterID");
        Boolean reconnectable = (Boolean) hello_props.get("JMQReconnectable");
        Boolean haclient = (Boolean) hello_props.get("JMQHAClient");
        if (Globals.getHAEnabled() && haclient != null && haclient.booleanValue()) {
            reconnectable = haclient;
        }
        String s = (String) hello_props.get("JMQUserAgent");
        if (s != null) {
            con.addClientData(IMQConnection.USER_AGENT, s);
        }
        // currently private property
        destprov = (String) hello_props.get("JMQDestinationProvider");
        longUID = (Long) hello_props.get("JMQConnectionID");
        if (longUID != null) {
            logger.log(Logger.DEBUG, "Have old connectionUID");
            oldCID = new ConnectionUID(longUID.longValue());
            logger.log(Logger.INFO, BrokerResources.I_RECONNECTING, oldCID);
            logger.log(Logger.DEBUG, "Checking for active connection");
            Connection oldcon = Globals.getConnectionManager().getConnection(oldCID);
            DUMP("Before connection Destroy");
            if (oldcon != null) {
                logger.log(Logger.DEBUG, "Destroying old connection " + oldCID);
                oldcon.destroyConnection(true, GoodbyeReason.ADMIN_KILLED_CON, "Destroying old connection with same connectionUID " + oldCID + " - reconnect is happening before connection was reaped");
            }
            /*
                 * LKS DUMP();
                 *
                 * logger.log(Logger.DEBUG,"Updating connection in id list " + "["+oldcid + "," + uid + "]"); // old code
                 * con.setConnectionUID(oldcid); Globals.getConnectionManager().updateConnectionUID( oldcid, uid);
                 * //Globals.getConnectionManager().updateConnectionUID( // uid, oldcid);
                 */
            DUMP("After Connection Destroy");
        }
        con.getConnectionUID().setCanReconnect(reconnectable != null && reconnectable.booleanValue());
        Long interval = (Long) hello_props.get("JMQInterval");
        // LKS - XXX just override for testing
        long itime = (interval == null ? ConnectionManager.DEFAULT_RECONNECT_INTERVAL : interval.longValue());
        con.setReconnectInterval(itime);
    } else {
        requestedProtocol = PacketType.VERSION1;
    }
    int supportedProtocol = 0;
    if (requestedProtocol > highestProtocol) {
        supportedProtocol = highestProtocol;
    } else if (requestedProtocol < lowestProtocol) {
        supportedProtocol = lowestProtocol;
    } else {
        supportedProtocol = requestedProtocol;
    }
    con.setClientProtocolVersion(supportedProtocol);
    if (bufsize != null) {
        logger.log(Logger.DEBUG, "Received JMQRBufferSize -" + bufsize);
        con.setFlowCount(bufsize.intValue());
    }
    Packet pkt = new Packet(con.useDirectBuffers());
    pkt.setPacketType(PacketType.HELLO_REPLY);
    pkt.setConsumerID(msg.getConsumerID());
    Hashtable hash = new Hashtable();
    reason = "unavailable";
    int status = Status.UNAVAILABLE;
    // protocol, then use the IP in the message packet.
    if (con.getRemoteIP() == null) {
        con.setRemoteIP(msg.getIP());
    }
    if ((alreadyAuthenticated || alreadyStarted) && !msg.getIndempotent()) {
        // handle ibit
        status = Status.ERROR;
        reason = "Connection reuse not allowed";
        if (alreadyAuthenticated) {
            logger.log(Logger.WARNING, "Internal Error: " + " received HELLO on already authenticated connection " + con.getRemoteConnectionString() + " " + con.getConnectionUID());
        } else {
            logger.log(Logger.WARNING, "Internal Error: " + " received HELLO on already started connection " + con.getRemoteConnectionString() + " " + con.getConnectionUID());
        }
    } else if (requestedProtocol != supportedProtocol) {
        // Bad protocol level.
        logger.log(Logger.WARNING, rb.W_BAD_PROTO_VERSION, Integer.toString(requestedProtocol), Integer.toString(supportedProtocol));
        reason = "bad version";
        status = Status.BAD_VERSION;
    } else if (con.getConnectionState() != Connection.STATE_UNAVAILABLE) {
        /**
         * connection may not be able to be created e.g: licensing, being destroyed (e.g due to timeout)
         */
        if (con.setConnectionState(Connection.STATE_INITIALIZED)) {
            reason = null;
            status = Status.OK;
        } else {
            status = Status.UNAVAILABLE;
        }
    } else {
        status = Status.UNAVAILABLE;
    }
    if (status == Status.OK && destprov != null) {
        if (((IMQService) con.getService()).getServiceType() == ServiceType.ADMIN) {
            status = Status.BAD_REQUEST;
            reason = "JMQDestinationProvider not supported on ADMIN service";
            logger.log(logger.WARNING, reason);
        } else if (!destprov.equals(CoreLifecycleSpi.GFMQ) && !destprov.equals(CoreLifecycleSpi.CHMP)) {
            status = Status.UNSUPPORTED_TYPE;
            reason = "Unsupported JMQDestinationProvider " + destprov;
            logger.log(logger.WARNING, reason);
        } else if (destprov.equals(CoreLifecycleSpi.CHMP) && Globals.getCorePlugin(destprov) == null) {
            status = Status.UNSUPPORTED_TYPE;
            reason = destprov + " not enabled";
            logger.log(logger.WARNING, reason);
        }
    }
    UID brokerSessionID = Globals.getBrokerSessionID();
    if (brokerSessionID != null) {
        hash.put("JMQBrokerSessionID", Long.valueOf(brokerSessionID.longValue()));
    }
    // OK, handle the HA properties HERE
    String clusterID = null;
    UID sessionUID = null;
    ClusterManager cfg = Globals.getClusterManager();
    if (cfg != null) {
        clusterID = cfg.getClusterId();
        sessionUID = cfg.getStoreSessionUID();
        hash.put("JMQHA", Boolean.valueOf(cfg.isHA()));
        if (clusterID != null) {
            hash.put("JMQClusterID", clusterID);
        }
        if (sessionUID != null && !Globals.getDestinationList().isPartitionMode()) {
            hash.put("JMQStoreSession", Long.valueOf(sessionUID.longValue()));
        }
        String list = null;
        Iterator itr = null;
        if (((IMQService) con.getService()).getServiceType() != ServiceType.ADMIN) {
            itr = cfg.getKnownBrokers(false);
        } else {
            itr = cfg.getKnownBrokers(true);
        }
        Set s = new HashSet();
        // ok get rid of dups
        while (itr.hasNext()) {
            ClusteredBroker cb = (ClusteredBroker) itr.next();
            s.add(cb.getBrokerURL().toString());
        }
        // OK .. now convert to a string
        itr = s.iterator();
        while (itr.hasNext()) {
            if (list == null) {
                list = itr.next().toString();
            } else {
                list += "," + itr.next().toString();
            }
        }
        if (list != null) {
            hash.put("JMQBrokerList", list);
        }
    }
    HAMonitorService hamonitor = Globals.getHAMonitorService();
    if (hamonitor != null && hamonitor.inTakeover()) {
        if (((IMQService) con.getService()).getServiceType() != ServiceType.ADMIN) {
            status = Status.TIMEOUT;
            if (oldCID != null) {
                logger.log(logger.INFO, BrokerResources.W_IN_TAKEOVER_RECONNECT_LATER, oldCID);
            } else {
                logger.log(logger.INFO, BrokerResources.W_IN_TAKEOVER_RECONNECT_LATER, con.getConnectionUID());
            }
        }
    }
    // first we want to deal with a bad clusterid
    if (clusterID != null && expectedClusterID != null && !clusterID.equals(expectedClusterID)) {
        status = Status.BAD_REQUEST;
    } else if (expectedSessionID != null && sessionUID != null && expectedSessionID.equals(sessionUID)) {
    // cool we connected to the right broker
    // we already have the right owner
    } else if (expectedSessionID != null) {
        if (cfg == null) {
            // not running any cluster config
            logger.log(Logger.WARNING, BrokerResources.E_INTERNAL_BROKER_ERROR, "Internal Error: Received session on" + " non-clustered broker");
            status = Status.NOT_FOUND;
        } else {
            // OK, if we are here, we need to locate the right
            // broker for the session
            // 
            // Here are the steps we need to check:
            // 1. does this broker support the sessionUID
            // if not
            // 2. can we locate another broker with the sessionUID
            // 
            ClusteredBroker owner = null;
            // 
            // OK, see if this was a session UID we took over at some
            // point in the past
            Set s = cfg.getSupportedStoreSessionUIDs();
            if (s.contains(expectedSessionID)) {
                // yep, we took it over
                owner = cfg.getLocalBroker();
            }
            if (owner == null) {
                // this broker isnt supprting the session
                // see if the database indicates someone else has it
                String ownerString = cfg.lookupStoreSessionOwner(expectedSessionID);
                if (ownerString != null) {
                    owner = cfg.getBroker(ownerString);
                }
            }
            try {
                if (owner != null) {
                    ClusteredBroker creator = null;
                    String creatorString = cfg.getStoreSessionCreator(expectedSessionID);
                    if (creatorString != null) {
                        creator = cfg.getBroker(creatorString);
                    }
                    int stat = owner.getStatus();
                    if (BrokerStatus.getBrokerInDoubt(stat) || !BrokerStatus.getBrokerLinkIsUp(stat) || owner.getState() == BrokerState.FAILOVER_STARTED) {
                        status = Status.TIMEOUT;
                        logger.log(logger.INFO, Globals.getBrokerResources().getKString(BrokerResources.I_RECONNECT_OWNER_INDOUBT, expectedSessionID, owner));
                    } else if (!owner.isLocalBroker()) {
                        status = Status.MOVED_PERMANENTLY;
                        hash.put("JMQStoreOwner", owner.getBrokerURL().toString());
                        logger.log(logger.INFO, Globals.getBrokerResources().getKString(BrokerResources.I_RECONNECT_OWNER_NOTME, expectedSessionID, owner));
                    } else if (creator == null) {
                        // XXX
                        status = Status.NOT_FOUND;
                        logger.log(logger.INFO, Globals.getBrokerResources().getKString(BrokerResources.I_RECONNECT_NOCREATOR, expectedSessionID));
                    } else if (creator.getState() == BrokerState.FAILOVER_STARTED) {
                        status = Status.TIMEOUT;
                        logger.log(logger.INFO, Globals.getBrokerResources().getKString(BrokerResources.I_RECONNECT_INTAKEOVER, expectedSessionID));
                    } else {
                        // local broker owns us - set owner for debugging only
                        // not required for protocol
                        hash.put("JMQStoreOwner", owner.getBrokerURL().toString());
                    }
                } else {
                    // didnt find owner
                    status = Status.NOT_FOUND;
                    logger.log(logger.INFO, Globals.getBrokerResources().getKString(BrokerResources.I_RECONNECT_OWNER_NOTFOUND, expectedSessionID));
                }
            } catch (Exception ex) {
                logger.log(Logger.WARNING, BrokerResources.W_RECONNECT_ERROR, expectedSessionID.toString(), ex);
                status = Status.NOT_FOUND;
            }
        }
    }
    if (!con.isAdminConnection() && Globals.getMemManager() != null) {
        hash.put("JMQSize", Integer.valueOf(Globals.getMemManager().getJMQSize()));
        hash.put("JMQBytes", Long.valueOf(Globals.getMemManager().getJMQBytes()));
        hash.put("JMQMaxMsgBytes", Long.valueOf(Globals.getMemManager().getJMQMaxMsgBytes()));
    }
    hash.put("JMQService", con.getService().getName());
    hash.put("JMQConnectionID", Long.valueOf(con.getConnectionUID().longValue()));
    hash.put("JMQProtocolLevel", Integer.valueOf(supportedProtocol));
    hash.put("JMQVersion", Globals.getVersion().getProductVersion());
    if (((IMQBasicConnection) con).getDumpPacket() || ((IMQBasicConnection) con).getDumpOutPacket()) {
        hash.put("JMQReqID", msg.getSysMessageID().toString());
    }
    try {
        sessionUID = con.attachStorePartition(expectedSessionID);
        if (Globals.getDestinationList().isPartitionMode()) {
            hash.put("JMQStoreSession", Long.valueOf(sessionUID.longValue()));
        }
    } catch (BrokerException e) {
        status = e.getStatusCode();
        reason = e.getMessage();
        if (status == Status.NOT_FOUND) {
            logger.log(logger.INFO, e.getMessage());
        } else {
            logger.logStack(logger.ERROR, e.getMessage(), e);
        }
    }
    hash.put("JMQStatus", Integer.valueOf(status));
    if (reason != null) {
        hash.put("JMQReason", reason);
    }
    pkt.setProperties(hash);
    con.sendControlMessage(pkt);
    // OK .. valid status messages are
    if (status != Status.OK && status != Status.MOVED_PERMANENTLY && status != Status.NOT_FOUND && status != Status.TIMEOUT) {
        // destroy the connection !!! (should be ok if destroy twice)
        con.closeConnection(true, GoodbyeReason.CON_FATAL_ERROR, Globals.getBrokerResources().getKString(BrokerResources.M_INIT_FAIL_CLOSE));
        connectionList.removeConnection(con.getConnectionUID(), false, GoodbyeReason.CON_FATAL_ERROR, Globals.getBrokerResources().getKString(BrokerResources.M_INIT_FAIL_CLOSE));
        return true;
    }
    status = Status.UNAVAILABLE;
    String authType = null;
    if (hello_props != null) {
        authType = (String) hello_props.get("JMQAuthType");
    }
    AccessController ac = con.getAccessController();
    pkt = new Packet(con.useDirectBuffers());
    pkt.setPacketType(PacketType.AUTHENTICATE_REQUEST);
    pkt.setConsumerID(msg.getConsumerID());
    hash = new Hashtable();
    hash.put("JMQSequence", Integer.valueOf(msg.getSequence()));
    hash.put("JMQChallenge", Boolean.TRUE);
    Properties props = new Properties();
    props.setProperty(Globals.IMQ + ".clientIP", msg.getIPString());
    props.setProperty(Globals.IMQ + ".connectionID", con.getConnectionUID().toString());
    byte[] req = null;
    try {
        AuthCacheData acd = ((IMQService) con.getService()).getAuthCacheData();
        req = ac.getChallenge(msg.getSequence(), props, acd.getCacheData(), authType);
        hash.put("JMQAuthType", ac.getAuthType());
        if (con.setConnectionState(Connection.STATE_AUTH_REQUESTED)) {
            status = Status.OK;
        }
    } catch (FailedLoginException e) {
        logger.log(Logger.WARNING, e.getMessage(), e);
        status = Status.FORBIDDEN;
    } catch (OutOfMemoryError err) {
        // packet is re-processed
        throw err;
    } catch (Throwable w) {
        logger.log(Logger.ERROR, Globals.getBrokerResources().getKString(BrokerResources.E_GET_CHALLENGE_FAILED) + " - " + w.getMessage(), w);
        status = Status.FORBIDDEN;
    }
    try {
        if (destprov != null && !destprov.equals(CoreLifecycleSpi.GFMQ)) {
            CoreLifecycleSpi clc = Globals.getCorePlugin(destprov);
            ((IMQBasicConnection) con).setPacketRouter(clc.getPacketRouter());
            con.setCoreLifecycle(clc);
        }
    } catch (Exception e) {
        status = Status.ERROR;
        logger.logStack(logger.ERROR, e.getMessage(), e);
    }
    hash.put("JMQStatus", Integer.valueOf(status));
    if (((IMQBasicConnection) con).getDumpPacket() || ((IMQBasicConnection) con).getDumpOutPacket()) {
        hash.put("JMQReqID", msg.getSysMessageID().toString());
    }
    pkt.setProperties(hash);
    if (req != null) {
        pkt.setMessageBody(req);
    }
    con.sendControlMessage(pkt);
    if (DEBUG) {
        logger.log(Logger.DEBUG, "HelloHandler: handle() [ sent challenge ]" + ":status=" + Status.getString(status));
    }
    if (status != Status.OK && status != Status.MOVED_PERMANENTLY && status != Status.NOT_FOUND && status != Status.TIMEOUT) {
        // destroy the connection !!! (should be ok if destroy twice)
        con.closeConnection(true, GoodbyeReason.CON_FATAL_ERROR, Globals.getBrokerResources().getKString(BrokerResources.M_INIT_FAIL_CLOSE));
        connectionList.removeConnection(con.getConnectionUID(), false, GoodbyeReason.CON_FATAL_ERROR, Globals.getBrokerResources().getKString(BrokerResources.M_INIT_FAIL_CLOSE));
    }
    return true;
}
Also used : BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException) CoreLifecycleSpi(com.sun.messaging.jmq.jmsserver.plugin.spi.CoreLifecycleSpi) IMQService(com.sun.messaging.jmq.jmsserver.service.imq.IMQService) IMQBasicConnection(com.sun.messaging.jmq.jmsserver.service.imq.IMQBasicConnection) HAMonitorService(com.sun.messaging.jmq.jmsserver.cluster.api.ha.HAMonitorService) IMQBasicConnection(com.sun.messaging.jmq.jmsserver.service.imq.IMQBasicConnection) Connection(com.sun.messaging.jmq.jmsserver.service.Connection) IMQConnection(com.sun.messaging.jmq.jmsserver.service.imq.IMQConnection) BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException) FailedLoginException(com.sun.messaging.jmq.auth.api.FailedLoginException) ConnectionUID(com.sun.messaging.jmq.jmsserver.service.ConnectionUID) UID(com.sun.messaging.jmq.util.UID) AccessController(com.sun.messaging.jmq.jmsserver.auth.AccessController) AuthCacheData(com.sun.messaging.jmq.jmsserver.auth.AuthCacheData) FailedLoginException(com.sun.messaging.jmq.auth.api.FailedLoginException) ConnectionUID(com.sun.messaging.jmq.jmsserver.service.ConnectionUID)

Aggregations

IMQBasicConnection (com.sun.messaging.jmq.jmsserver.service.imq.IMQBasicConnection)6 BrokerException (com.sun.messaging.jmq.jmsserver.util.BrokerException)4 Packet (com.sun.messaging.jmq.io.Packet)2 SysMessageID (com.sun.messaging.jmq.io.SysMessageID)2 BrokerStateHandler (com.sun.messaging.jmq.jmsserver.BrokerStateHandler)2 ConnectionUID (com.sun.messaging.jmq.jmsserver.service.ConnectionUID)2 IMQConnection (com.sun.messaging.jmq.jmsserver.service.imq.IMQConnection)2 UID (com.sun.messaging.jmq.util.UID)2 FailedLoginException (com.sun.messaging.jmq.auth.api.FailedLoginException)1 AccessController (com.sun.messaging.jmq.jmsserver.auth.AccessController)1 AuthCacheData (com.sun.messaging.jmq.jmsserver.auth.AuthCacheData)1 HAMonitorService (com.sun.messaging.jmq.jmsserver.cluster.api.ha.HAMonitorService)1 BrokerMQAddress (com.sun.messaging.jmq.jmsserver.core.BrokerMQAddress)1 DestinationList (com.sun.messaging.jmq.jmsserver.core.DestinationList)1 CoreLifecycleSpi (com.sun.messaging.jmq.jmsserver.plugin.spi.CoreLifecycleSpi)1 Connection (com.sun.messaging.jmq.jmsserver.service.Connection)1 ConnectionManager (com.sun.messaging.jmq.jmsserver.service.ConnectionManager)1 IMQService (com.sun.messaging.jmq.jmsserver.service.imq.IMQService)1 OperationNotAllowedException (com.sun.messaging.jmq.jmsserver.util.OperationNotAllowedException)1 IOException (java.io.IOException)1