public AsyncMessage routeCommandToService()

in core/src/main/java/flex/messaging/MessageBroker.java [1383:1498]


    public AsyncMessage routeCommandToService(CommandMessage command, Endpoint endpoint) {
        // Make sure command has a messageId
        checkMessageId(command);

        String destId = command.getDestination();

        AsyncMessage replyMessage;
        Service service;
        String serviceId;
        Object commandResult = null;
        boolean serviced = false;
        boolean recreateHttpFlexSessionAfterLogin = false;

        // Forward login and logout commands to AuthenticationService
        int operation = command.getOperation();
        if (operation == CommandMessage.LOGIN_OPERATION || operation == CommandMessage.LOGOUT_OPERATION) {
            serviceId = AUTHENTICATION_SERVICE_ID;
            recreateHttpFlexSessionAfterLogin = securitySettings.isRecreateHttpSessionAfterLogin()
                    && operation == CommandMessage.LOGIN_OPERATION && FlexContext.getFlexSession() instanceof HttpFlexSession;
        } else {
            serviceId = destId != null ? destinationToService.get(destId) : null;
        }

        service = serviceId != null ? services.get(serviceId) : null;
        if (service != null) {
            // Before passing the message to the service, need to check
            // the security constraints.
            Destination destination = service.getDestination(destId);
            if (destination != null)
                inspectOperation(command, destination);

            try {
                extractRemoteCredentials(service, command);
                commandResult = service.serviceCommand(command);
                serviced = true;
            } catch (UnsupportedOperationException e) {
                ServiceException se = new ServiceException();
                se.setMessage(ERR_MSG_SERVICE_CMD_NOT_SUPPORTED, new Object[]{service.getClass().getName()});
                throw se;
            } catch (SecurityException se) {
                // when a LOGIN message causes a security exception, we want to continue processing here
                // to allow metadata to be sent to clients communicating with runtime destinations.
                // The result will be an error message with a login fault message as well as the metadata
                if (AUTHENTICATION_SERVICE_ID.equals(serviceId)) {
                    commandResult = se.createErrorMessage();
                    if (Log.isDebug())
                        Log.getLogger(LOG_CATEGORY).debug("Security error for message: " +
                                se.toString() + StringUtils.NEWLINE +
                                "  incomingMessage: " + command + StringUtils.NEWLINE +
                                "  errorReply: " + commandResult);
                    serviced = true;
                } else {
                    throw se;
                }
            }
        }

        if (recreateHttpFlexSessionAfterLogin)
            recreateHttpFlexSessionAfterLogin();

        if (commandResult == null) {
            replyMessage = new AcknowledgeMessage();
        } else if (commandResult instanceof AsyncMessage) {
            replyMessage = (AsyncMessage) commandResult;
        } else {
            replyMessage = new AcknowledgeMessage();
            replyMessage.setBody(commandResult);
        }

        // Update the replyMessage body with server configuration if the
        // operation is ping or login and make sure to return the FlexClient Id value.
        if (command.getOperation() == CommandMessage.CLIENT_PING_OPERATION
                || command.getOperation() == CommandMessage.LOGIN_OPERATION) {
            boolean needsConfig = false;
            if (command.getHeader(CommandMessage.NEEDS_CONFIG_HEADER) != null)
                needsConfig = ((Boolean) (command.getHeader(CommandMessage.NEEDS_CONFIG_HEADER)));

            // Send configuration information only if the client requested.
            if (needsConfig) {
                ConfigMap serverConfig = describeServices(endpoint);
                if (serverConfig.size() > 0)
                    replyMessage.setBody(serverConfig);
            }

            // Record the features available over this endpoint
            double msgVersion = endpoint.getMessagingVersion();
            if (msgVersion > 0)
                replyMessage.setHeader(CommandMessage.MESSAGING_VERSION, new Double(msgVersion));

            // Record the flex client ID
            FlexClient flexClient = FlexContext.getFlexClient();
            if (flexClient != null)
                replyMessage.setHeader(Message.FLEX_CLIENT_ID_HEADER, flexClient.getId());
        } else if (!serviced) {
            MessageException lme = new MessageException();
            // The supplied destination id is not registered with any service..
            lme.setMessage(ERR_MSG_NO_SERVICE_FOR_DEST);
            throw lme;
        }

        replyMessage.setCorrelationId(command.getMessageId());
        replyMessage.setClientId(command.getClientId());
        if (replyMessage.getBody() instanceof java.util.List) {
            replyMessage.setBody(((List) replyMessage.getBody()).toArray());
        }

        if (Log.isDebug())
            Log.getLogger(getLogCategory(command)).debug(
                    "Executed command: " +
                            (service == null ? "(default service)" : "service=" +
                                    service.getId()) + StringUtils.NEWLINE +
                            "  commandMessage: " + command + StringUtils.NEWLINE +
                            "  replyMessage: " + replyMessage + StringUtils.NEWLINE);

        return replyMessage;
    }