Package org.hornetq.core.protocol.core.impl

Source Code of org.hornetq.core.protocol.core.impl.HornetQPacketHandler

/*
* Copyright 2009 Red Hat, Inc.
* Red Hat 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.hornetq.core.protocol.core.impl;

import static org.hornetq.core.protocol.core.impl.PacketImpl.CREATESESSION;
import static org.hornetq.core.protocol.core.impl.PacketImpl.CREATE_QUEUE;
import static org.hornetq.core.protocol.core.impl.PacketImpl.REATTACH_SESSION;

import org.hornetq.api.core.HornetQException;
import org.hornetq.api.core.HornetQExceptionType;
import org.hornetq.api.core.HornetQInternalErrorException;
import org.hornetq.core.protocol.core.Channel;
import org.hornetq.core.protocol.core.ChannelHandler;
import org.hornetq.core.protocol.core.CoreRemotingConnection;
import org.hornetq.core.protocol.core.Packet;
import org.hornetq.core.protocol.core.ServerSessionPacketHandler;
import org.hornetq.core.protocol.core.impl.wireformat.CreateQueueMessage;
import org.hornetq.core.protocol.core.impl.wireformat.CreateSessionMessage;
import org.hornetq.core.protocol.core.impl.wireformat.CreateSessionResponseMessage;
import org.hornetq.core.protocol.core.impl.wireformat.HornetQExceptionMessage;
import org.hornetq.core.protocol.core.impl.wireformat.ReattachSessionMessage;
import org.hornetq.core.protocol.core.impl.wireformat.ReattachSessionResponseMessage;
import org.hornetq.core.security.HornetQPrincipal;
import org.hornetq.core.server.HornetQLogger;
import org.hornetq.core.server.HornetQMessageBundle;
import org.hornetq.core.server.HornetQServer;
import org.hornetq.core.server.ServerSession;
import org.hornetq.core.version.Version;

/**
* A packet handler for all packets that need to be handled at the server level
*
* @author <a href="mailto:jmesnil@redhat.com">Jeff Mesnil</a>
* @author <a href="mailto:tim.fox@jboss.com">Tim Fox</a>
* @author <a href="ataylor@redhat.com">Andy Taylor</a>
*/
public class HornetQPacketHandler implements ChannelHandler
{
   private final HornetQServer server;

   private final Channel channel1;

   private final CoreRemotingConnection connection;

   private final CoreProtocolManager protocolManager;

   public HornetQPacketHandler(final CoreProtocolManager protocolManager,
                               final HornetQServer server,
                               final Channel channel1,
                               final CoreRemotingConnection connection)
   {
      this.protocolManager = protocolManager;

      this.server = server;

      this.channel1 = channel1;

      this.connection = connection;
   }

   public void handlePacket(final Packet packet)
   {
      byte type = packet.getType();

      switch (type)
      {
         case CREATESESSION:
         {
            CreateSessionMessage request = (CreateSessionMessage)packet;

            handleCreateSession(request);

            break;
         }
         case REATTACH_SESSION:
         {
            ReattachSessionMessage request = (ReattachSessionMessage)packet;

            handleReattachSession(request);

            break;
         }
         case CREATE_QUEUE:
         {
            // Create queue can also be fielded here in the case of a replicated store and forward queue creation

            CreateQueueMessage request = (CreateQueueMessage)packet;

            handleCreateQueue(request);

            break;
         }
         default:
         {
            HornetQLogger.LOGGER.invalidPacket(packet);
         }
      }
   }

   private void handleCreateSession(final CreateSessionMessage request)
   {
      boolean incompatibleVersion = false;
      Packet response;
      try
      {
         Version version = server.getVersion();
         int[] compatibleList = version.getCompatibleVersionList();
         boolean isCompatibleClient = false;
         for (int element : compatibleList)
         {
            if (element == request.getVersion())
            {
               isCompatibleClient = true;
               break;
            }
         }

         if (!isCompatibleClient)
         {
            HornetQLogger.LOGGER.incompatibleVersion(request.getVersion(), connection.getRemoteAddress(), version.getFullVersion());
            throw HornetQMessageBundle.BUNDLE.incompatibleCLientServer();
         }

         if (!server.isStarted())
         {
            throw HornetQMessageBundle.BUNDLE.serverNotStarted();
         }

         // XXX HORNETQ-720 Taylor commented out this test. Should be verified.
         /*if (!server.checkActivate())
         {
            throw new HornetQException(HornetQException.SESSION_CREATION_REJECTED,
                                       "Server will not accept create session requests");
         }*/


         if (connection.getClientVersion() == 0)
         {
            connection.setClientVersion(request.getVersion());
         }
         else if (connection.getClientVersion() != request.getVersion())
         {
            HornetQLogger.LOGGER.incompatibleVersionAfterConnect(request.getVersion(), connection.getClientVersion());
         }
        
         Channel channel = connection.getChannel(request.getSessionChannelID(), request.getWindowSize());

         HornetQPrincipal hornetQPrincipal = null;

         if(request.getUsername() == null)
         {
            hornetQPrincipal = connection.getDefaultHornetQPrincipal();
         }

         ServerSession session = server.createSession(request.getName(),
                                                      hornetQPrincipal == null?request.getUsername(): hornetQPrincipal.getUserName(),
                                                      hornetQPrincipal == null?request.getPassword(): hornetQPrincipal.getPassword(),
                                                      request.getMinLargeMessageSize(),
                                                      connection,
                                                      request.isAutoCommitSends(),
                                                      request.isAutoCommitAcks(),
                                                      request.isPreAcknowledge(),
                                                      request.isXA(),
                                                      request.getDefaultAddress(),
                                                      new CoreSessionCallback(request.getName(),
                                                                              protocolManager,
                                                                              channel));

         session.setSessionContext(server.getStorageManager().newContext(server.getExecutorFactory().getExecutor()));

         ServerSessionPacketHandler handler = new ServerSessionPacketHandler(session,
                                                                             server.getStorageManager(),
                                                                             channel);
         channel.setHandler(handler);

         // TODO - where is this removed?
         protocolManager.addSessionHandler(request.getName(), handler);

         response = new CreateSessionResponseMessage(server.getVersion().getIncrementingVersion());
      }
      catch (HornetQException e)
      {
         HornetQLogger.LOGGER.failedToCreateSession(e);
         response = new HornetQExceptionMessage(e);

         if (e.getType() == HornetQExceptionType.INCOMPATIBLE_CLIENT_SERVER_VERSIONS);
         {
            incompatibleVersion = true;
         }
      }
      catch (Exception e)
      {
         HornetQLogger.LOGGER.failedToCreateSession(e);

         response = new HornetQExceptionMessage(new HornetQInternalErrorException());
      }

      // send the exception to the client and destroy
      // the connection if the client and server versions
      // are not compatible
      if (incompatibleVersion)
      {
         channel1.sendAndFlush(response);
      }
      else
      {
         channel1.send(response);
      }
   }

   private void handleReattachSession(final ReattachSessionMessage request)
   {
      Packet response = null;

      try
      {

         if (!server.isStarted())
         {
            response = new ReattachSessionResponseMessage(-1, false);
         }

         HornetQLogger.LOGGER.debug("Reattaching request from " +  connection.getRemoteAddress());


         ServerSessionPacketHandler sessionHandler = protocolManager.getSessionHandler(request.getName());

         // HORNETQ-720 XXX ataylor?
         if (/*!server.checkActivate() || */ sessionHandler == null)
         {
            response = new ReattachSessionResponseMessage(-1, false);
         }
         else
         {
            if (sessionHandler.getChannel().getConfirmationWindowSize() == -1)
            {
               // Even though session exists, we can't reattach since confi window size == -1,
               // i.e. we don't have a resend cache for commands, so we just close the old session
               // and let the client recreate

               HornetQLogger.LOGGER.reattachRequestFailed(connection.getRemoteAddress());

               sessionHandler.closeListeners();
               sessionHandler.close();

               response = new ReattachSessionResponseMessage(-1, false);
            }
            else
            {
               // Reconnect the channel to the new connection
               int serverLastConfirmedCommandID = sessionHandler.transferConnection(connection,
                                                                                    request.getLastConfirmedCommandID());

               response = new ReattachSessionResponseMessage(serverLastConfirmedCommandID, true);
            }
         }
      }
      catch (Exception e)
      {
         HornetQLogger.LOGGER.failedToReattachSession(e);

         response = new HornetQExceptionMessage(new HornetQInternalErrorException());
      }

      channel1.send(response);
   }

   private void handleCreateQueue(final CreateQueueMessage request)
   {
      try
      {
         server.createQueue(request.getAddress(),
                            request.getQueueName(),
                            request.getFilterString(),
                            request.isDurable(),
                            request.isTemporary());
      }
      catch (Exception e)
      {
         HornetQLogger.LOGGER.failedToHandleCreateQueue(e);
      }
   }
}
TOP

Related Classes of org.hornetq.core.protocol.core.impl.HornetQPacketHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.