コード例 #1
0
  private Message handleSecurityMessage(CommandMessage message) {
    GraniteConfig config = GraniteContext.getCurrentInstance().getGraniteConfig();

    Message response = null;

    if (!config.hasSecurityService())
      log.warn(
          "Ignored security operation (no security settings in granite-config.xml): %s", message);
    else if (!config.getSecurityService().acceptsContext())
      log.info(
          "Ignored security operation (security service does not handle this kind of granite context)",
          message);
    else {
      SecurityService securityService = config.getSecurityService();
      try {
        if (message.isLoginOperation())
          securityService.login(
              message.getBody(), (String) message.getHeader(Message.CREDENTIALS_CHARSET_HEADER));
        else securityService.logout();
      } catch (Exception e) {
        if (e instanceof SecurityServiceException)
          log.debug(e, "Could not process security operation: %s", message);
        else log.error(e, "Could not process security operation: %s", message);
        response = new ErrorMessage(message, e, true);
      }
    }

    if (response == null) {
      response = new AcknowledgeMessage(message, true);
      // For SDK 2.0.1_Hotfix2.
      if (message.isSecurityOperation()) response.setBody("success");
    }

    return response;
  }
コード例 #2
0
  private Message handleUnsubscribeMessage(
      final ChannelFactory<?> channelFactory, CommandMessage message) {
    Channel channel = getChannel(channelFactory, (String) message.getClientId());
    if (channel == null) return handleUnknownClientMessage(message);

    AsyncMessage reply = null;

    ServiceAdapter adapter = adapterFactory.getServiceAdapter(message);

    reply = (AcknowledgeMessage) adapter.manage(channel, message);

    postManage(channel);

    if (!(reply instanceof ErrorMessage)) {
      // Remove subscription message in distributed data (clustering).
      try {
        DistributedData gdd = graniteConfig.getDistributedDataFactory().getInstance();
        if (gdd != null) {
          String subscriptionId =
              (String) message.getHeader(AsyncMessage.DESTINATION_CLIENT_ID_HEADER);
          log.debug(
              "Removing subscription message from channel info: %s - %s",
              channel.getId(), subscriptionId);
          gdd.removeSubcription(channel.getId(), subscriptionId);
        }
      } catch (Exception e) {
        log.error(
            e,
            "Could not remove subscription from distributed data: %s - %s",
            channel.getId(),
            message.getHeader(AsyncMessage.DESTINATION_CLIENT_ID_HEADER));
      }
    }

    reply.setDestination(message.getDestination());
    reply.setClientId(channel.getId());
    reply.getHeaders().putAll(message.getHeaders());

    return reply;
  }
コード例 #3
0
ファイル: MessageService.java プロジェクト: CHATTG1/sofa
  /**
   * Processes subscription related <code>CommandMessage</code>s. Subclasses that perform additional
   * custom subscription management should invoke <code>super.manageSubscriptions()</code> if they
   * choose to override this method.
   *
   * @param command The <code>CommandMessage</code> to process.
   */
  protected Message manageSubscriptions(CommandMessage command) {
    Message replyMessage = null;

    MessageDestination destination = (MessageDestination) getDestination(command);
    SubscriptionManager subscriptionManager = destination.getSubscriptionManager();

    Object clientId = command.getClientId();
    String endpointId = (String) command.getHeader(Message.ENDPOINT_HEADER);

    String subtopicString = (String) command.getHeader(AsyncMessage.SUBTOPIC_HEADER_NAME);

    ServiceAdapter adapter = destination.getAdapter();

    if (command.getOperation() == CommandMessage.SUBSCRIBE_OPERATION) {
      String selectorExpr = (String) command.getHeader(CommandMessage.SELECTOR_HEADER);

      getMessageBroker().inspectChannel(command, destination);

      // Give MessagingAdapter a chance to block the subscribe.
      if ((adapter instanceof MessagingAdapter)) {
        MessagingSecurityConstraintManager manager =
            ((MessagingAdapter) adapter).getSecurityConstraintManager();
        if (manager != null) manager.assertSubscribeAuthorization();
      }

      try {
        /*
         * This allows parallel add/remove subscribe calls (protected by the
         * concurrent hash table) but prevents us from doing any table mods
         * when the getSubscriptionState method is active
         */
        subscribeLock.readLock().lock();

        if (adapter.handlesSubscriptions()) {
          replyMessage = (Message) adapter.manage(command);
        } else {
          testSelector(selectorExpr, command);
        }
        /*
         * Even if the adapter is managing the subscription, we still need to
         * register this with the subscription manager so that we can match the
         * endpoint with the clientId.  I am not sure I like this though because
         * now the subscription is registered both with the adapter and with our
         * system so keeping them in sync is potentially problematic.   Also, it
         * seems like the adapter should have the option to manage endpoints themselves?
         */

        // Extract the maxFrequency that might have been specified by the client.
        int maxFrequency = processMaxFrequencyHeader(command);
        subscriptionManager.addSubscriber(
            clientId, selectorExpr, subtopicString, endpointId, maxFrequency);
      } finally {
        subscribeLock.readLock().unlock();
      }

      if (replyMessage == null) replyMessage = new AcknowledgeMessage();
    } else if (command.getOperation() == CommandMessage.UNSUBSCRIBE_OPERATION) {
      // Give MessagingAdapter a chance to block the unsubscribe, as long as
      // the subscription has not been invalidated.
      if ((adapter instanceof MessagingAdapter)
          && command.getHeader(CommandMessage.SUBSCRIPTION_INVALIDATED_HEADER) == null) {
        MessagingSecurityConstraintManager manager =
            ((MessagingAdapter) adapter).getSecurityConstraintManager();
        if (manager != null) manager.assertSubscribeAuthorization();
      }

      String selectorExpr = (String) command.getHeader(CommandMessage.SELECTOR_HEADER);

      try {
        subscribeLock.readLock().lock();

        if (adapter.handlesSubscriptions()) {
          replyMessage = (Message) adapter.manage(command);
        }
        subscriptionManager.removeSubscriber(clientId, selectorExpr, subtopicString, endpointId);
      } finally {
        subscribeLock.readLock().unlock();
      }

      if (replyMessage == null) replyMessage = new AcknowledgeMessage();
    } else if (command.getOperation() == CommandMessage.MULTI_SUBSCRIBE_OPERATION) {
      getMessageBroker().inspectChannel(command, destination);

      // Give MessagingAdapter a chance to block the multi subscribe.
      if ((adapter instanceof MessagingAdapter)) {
        MessagingSecurityConstraintManager manager =
            ((MessagingAdapter) adapter).getSecurityConstraintManager();
        if (manager != null) manager.assertSubscribeAuthorization();
      }

      try {
        /*
         * This allows parallel add/remove subscribe calls (protected by the
         * concurrent hash table) but prevents us from doing any table mods
         * when the getSubscriptionState method is active
         */
        subscribeLock.readLock().lock();

        if (adapter.handlesSubscriptions()) {
          replyMessage = (Message) adapter.manage(command);
        }

        // Deals with legacy collection setting
        Object[] adds =
            getObjectArrayFromHeader(command.getHeader(CommandMessage.ADD_SUBSCRIPTIONS));
        Object[] rems =
            getObjectArrayFromHeader(command.getHeader(CommandMessage.REMOVE_SUBSCRIPTIONS));

        if (adds != null) {
          // Extract the maxFrequency that might have been specified
          // by the client for every subscription (selector/subtopic).
          int maxFrequency = processMaxFrequencyHeader(command);
          for (int i = 0; i < adds.length; i++) {
            // Use the maxFrequency by default.
            int maxFrequencyPerSubscription = maxFrequency;
            String ss = (String) adds[i];
            int ix = ss.indexOf(CommandMessage.SUBTOPIC_SEPARATOR);
            if (ix != -1) {
              String subtopic = (ix == 0 ? null : ss.substring(0, ix));
              String selector = null;
              String selectorAndMaxFrequency =
                  ss.substring(ix + CommandMessage.SUBTOPIC_SEPARATOR.length());
              if (selectorAndMaxFrequency.length() != 0) {
                int ix2 = selectorAndMaxFrequency.indexOf(CommandMessage.SUBTOPIC_SEPARATOR);
                if (ix2 != -1) {
                  selector = (ix2 == 0 ? null : selectorAndMaxFrequency.substring(0, ix2));
                  String maxFrequencyString =
                      selectorAndMaxFrequency.substring(
                          ix2 + CommandMessage.SUBTOPIC_SEPARATOR.length());
                  if (maxFrequencyString.length() != 0) {
                    // Choose the minimum of Consumer level maxFrequency and subscription level
                    // maxFrequency.
                    int maxFrequencyCandidate = Integer.parseInt(maxFrequencyString);
                    maxFrequencyPerSubscription =
                        maxFrequencyPerSubscription == 0
                            ? maxFrequencyCandidate
                            : Math.min(maxFrequencyPerSubscription, maxFrequencyCandidate);
                  }
                }
              }
              subscriptionManager.addSubscriber(
                  clientId, selector, subtopic, endpointId, maxFrequencyPerSubscription);
            }
            // invalid message
          }
        }

        if (rems != null) {
          for (int i = 0; i < rems.length; i++) {
            String ss = (String) rems[i];
            int ix = ss.indexOf(CommandMessage.SUBTOPIC_SEPARATOR);
            if (ix != -1) {
              String subtopic = (ix == 0 ? null : ss.substring(0, ix));
              String selector = null;
              String selectorAndMaxFrequency =
                  ss.substring(ix + CommandMessage.SUBTOPIC_SEPARATOR.length());
              if (selectorAndMaxFrequency.length() != 0) {
                int ix2 = selectorAndMaxFrequency.indexOf(CommandMessage.SUBTOPIC_SEPARATOR);
                if (ix2 != -1)
                  selector = ix2 == 0 ? null : selectorAndMaxFrequency.substring(0, ix2);
              }
              subscriptionManager.removeSubscriber(clientId, selector, subtopic, endpointId);
            }
          }
        }
      } finally {
        subscribeLock.readLock().unlock();
      }

      if (replyMessage == null) replyMessage = new AcknowledgeMessage();
    } else if (command.getOperation() == CommandMessage.POLL_OPERATION) {
      // This code path handles poll messages sent by Consumer.receive().
      // This API should not trigger server side waits, so we invoke poll
      // and if there are no queued messages for this Consumer instance we
      // return an empty acknowledgement immediately.
      MessageClient client = null;
      try {
        client = subscriptionManager.getMessageClient(clientId, endpointId);

        if (client != null) {
          if (adapter.handlesSubscriptions()) {
            List missedMessages = (List) adapter.manage(command);
            if (missedMessages != null && !missedMessages.isEmpty()) {
              MessageBroker broker = getMessageBroker();
              for (Iterator iter = missedMessages.iterator(); iter.hasNext(); )
                broker.routeMessageToMessageClient((Message) iter.next(), client);
            }
          }
          FlushResult flushResult = client.getFlexClient().poll(client);
          List messagesToReturn = (flushResult != null) ? flushResult.getMessages() : null;
          if (messagesToReturn != null && !messagesToReturn.isEmpty()) {
            replyMessage = new CommandMessage(CommandMessage.CLIENT_SYNC_OPERATION);
            replyMessage.setBody(messagesToReturn.toArray());
          } else {
            replyMessage = new AcknowledgeMessage();
          }
          // Adaptive poll wait is never used in responses to Consumer.receive() calls.
        } else {
          ServiceException se = new ServiceException();
          se.setCode(NOT_SUBSCRIBED_CODE);
          se.setMessage(NOT_SUBSCRIBED, new Object[] {destination.getId()});
          throw se;
        }
      } finally {
        subscriptionManager.releaseMessageClient(client);
      }
    } else {
      ServiceException se = new ServiceException();
      se.setMessage(UNKNOWN_COMMAND, new Object[] {new Integer(command.getOperation())});
      throw se;
    }

    return replyMessage;
  }
コード例 #4
0
ファイル: MessageService.java プロジェクト: CHATTG1/sofa
 private int processMaxFrequencyHeader(CommandMessage command) {
   Object maxFrequencyHeader = command.getHeader(CommandMessage.MAX_FREQUENCY_HEADER);
   if (maxFrequencyHeader != null) return ((Integer) maxFrequencyHeader).intValue();
   return 0;
 }