// Make sure command has a messageId
checkMessageId(command);
String destId = command.getDestination();
AsyncMessage replyMessage = null;
Service service = null;
String serviceId = null;
Object commandResult = null;
boolean serviced = false;
// Forward login and logout commands to AuthenticationService
if (command.getOperation() == CommandMessage.LOGIN_OPERATION
|| command.getOperation() == CommandMessage.LOGOUT_OPERATION)
serviceId = "authentication-service";
else
serviceId = (String)destinationToService.get(destId);
service = (Service)services.get(serviceId);
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(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 (serviceId.equals("authentication-service"))
{
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 (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))).booleanValue();
// 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();
// No destination with id ''{0}'' is registered with any service.
lme.setMessage(NO_SERVICE_FOR_DEST, new Object[] {destId});
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: " +