예제 #1
0
  private Message handlePublishMessage(
      final ChannelFactory<?> channelFactory, final AsyncMessage message, final Channel channel) {

    GraniteContext context = GraniteContext.getCurrentInstance();

    // Get and check destination.
    Destination destination =
        context
            .getServicesConfig()
            .findDestinationById(message.getClass().getName(), message.getDestination());

    if (destination == null) return getInvalidDestinationError(message);

    if (message.getMessageId() == null) message.setMessageId(UUIDUtil.randomUUID());
    message.setTimestamp(System.currentTimeMillis());
    if (channel != null) message.setClientId(channel.getId());

    GravityInvocationContext invocationContext =
        new GravityInvocationContext(message, destination) {
          @Override
          public Object invoke() throws Exception {
            // Publish...
            Channel fromChannel = channel;
            if (fromChannel == null)
              fromChannel = getChannel(channelFactory, (String) message.getClientId());
            if (fromChannel == null) return handleUnknownClientMessage(message);

            ServiceAdapter adapter = adapterFactory.getServiceAdapter(message);

            AsyncMessage reply = (AsyncMessage) adapter.invoke(fromChannel, message);

            reply.setDestination(message.getDestination());
            reply.setClientId(fromChannel.getId());

            return reply;
          }
        };

    // Check security 1 (destination).
    if (destination.getSecurizer() instanceof GravityDestinationSecurizer) {
      try {
        ((GravityDestinationSecurizer) destination.getSecurizer()).canPublish(invocationContext);
      } catch (Exception e) {
        return new ErrorMessage(message, e, true);
      }
    }

    // Check security 2 (security service).
    GraniteConfig config = context.getGraniteConfig();
    try {
      if (config.hasSecurityService() && config.getSecurityService().acceptsContext())
        return (Message) config.getSecurityService().authorize(invocationContext);

      return (Message) invocationContext.invoke();
    } catch (Exception e) {
      return new ErrorMessage(message, e, true);
    }
  }
예제 #2
0
  protected <C extends Channel> C createChannel(ChannelFactory<C> channelFactory, String clientId) {
    C channel = null;
    if (clientId != null) {
      channel = getChannel(channelFactory, clientId);
      if (channel != null) return channel;
    }

    String clientType = GraniteContext.getCurrentInstance().getClientType();
    channel = channelFactory.newChannel(UUIDUtil.randomUUID(), clientType);
    TimeChannel<C> timeChannel = new TimeChannel<C>(channel);
    for (int i = 0; channels.putIfAbsent(channel.getId(), timeChannel) != null; i++) {
      if (i >= 10)
        throw new RuntimeException("Could not find random new clientId after 10 iterations");
      channel.destroy(false);
      channel = channelFactory.newChannel(UUIDUtil.randomUUID(), clientType);
      timeChannel = new TimeChannel<C>(channel);
    }

    String channelId = channel.getId();

    // Save channel id in distributed data (clustering).
    try {
      DistributedData gdd = graniteConfig.getDistributedDataFactory().getInstance();
      if (gdd != null) {
        log.debug("Saving channel id in distributed data: %s", channelId);
        gdd.addChannelId(channelId, channelFactory.getClass().getName(), clientType);
      }
    } catch (Exception e) {
      log.error(e, "Could not add channel id in distributed data: %s", channelId);
    }

    // Initialize timer task.
    access(channelId);

    return channel;
  }