Ejemplo n.º 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);
    }
  }
Ejemplo n.º 2
0
  protected void createUdpReceiver(UdpReceiverFactory factory, AsyncHttpContext asyncHttpContext) {
    OutputStream os = null;
    try {
      Message connectMessage = asyncHttpContext.getConnectMessage();

      if (udpReceiver == null || udpReceiver.isClosed())
        udpReceiver = factory.newReceiver(this, asyncHttpContext.getRequest(), connectMessage);

      AsyncMessage reply = udpReceiver.acknowledge(connectMessage);

      HttpServletRequest request = asyncHttpContext.getRequest();
      HttpServletResponse response = asyncHttpContext.getResponse();

      GraniteContext context =
          HttpGraniteContext.createThreadIntance(
              gravity.getGraniteConfig(), gravity.getServicesConfig(), null, request, response);
      ((AMFContextImpl) context.getAMFContext())
          .setCurrentAmf3Message(asyncHttpContext.getConnectMessage());

      GravityServletUtil.serialize(
          gravity,
          response,
          new AsyncMessage[] {reply},
          ContentType.forMimeType(request.getContentType()));
    } catch (ServletException e) {
      log.error(e, "Could not send UDP connect acknowledgement to channel: %s", this);
    } catch (IOException e) {
      log.error(e, "Could not send UDP connect acknowledgement to channel: %s", this);
    } finally {
      try {
        GraniteContext.release();
      } catch (Exception e) {
        // should never happen...
      }

      // Close output stream.
      try {
        if (os != null) {
          try {
            os.close();
          } catch (IOException e) {
            log.warn(e, "Could not close output stream (ignored)");
          }
        }
      } finally {
        releaseAsyncHttpContext(asyncHttpContext);
      }
    }
  }
Ejemplo n.º 3
0
  public Principal login(Object credentials, String charset) {
    List<String> decodedCredentials = Arrays.asList(decodeBase64Credentials(credentials, charset));

    HttpGraniteContext context = (HttpGraniteContext) GraniteContext.getCurrentInstance();
    HttpServletRequest httpRequest = context.getRequest();

    String user = decodedCredentials.get(0);
    String password = decodedCredentials.get(1);
    Authentication auth = new UsernamePasswordAuthenticationToken(user, password);
    Principal principal = null;

    ApplicationContext ctx =
        WebApplicationContextUtils.getWebApplicationContext(
            httpRequest.getSession().getServletContext());
    if (ctx != null) {
      AbstractAuthenticationManager authenticationManager =
          BeanFactoryUtils.beanOfTypeIncludingAncestors(ctx, AbstractAuthenticationManager.class);
      try {
        Authentication authentication = authenticationManager.authenticate(auth);
        SecurityContext securityContext = SecurityContextHolder.getContext();
        securityContext.setAuthentication(authentication);
        principal = authentication;
        SecurityContextHolder.setContext(securityContext);
        saveSecurityContextInSession(securityContext, 0);

        endLogin(credentials, charset);
      } catch (AuthenticationException e) {
        handleAuthenticationExceptions(e);
      }
    }

    log.debug("User %s logged in", user);

    return principal;
  }
Ejemplo n.º 4
0
  public Externalizer getExternalizer(String type) {
    Externalizer externalizer =
        getElementByType(
            type,
            EXTERNALIZER_FACTORY,
            externalizersByType,
            externalizersByInstanceOf,
            externalizersByAnnotatedWith,
            scannedExternalizers);
    if (externalizer != null) return externalizer;

    if ("java".equals(GraniteContext.getCurrentInstance().getClientType())) {
      // Force use of number externalizers when serializing from/to a Java client
      if (Long.class.getName().equals(type)) return LONG_EXTERNALIZER;
      else if (BigInteger.class.getName().equals(type)) return BIGINTEGER_EXTERNALIZER;
      else if (BigDecimal.class.getName().equals(type)) return BIGDECIMAL_EXTERNALIZER;
      else {
        try {
          Class<?> clazz = TypeUtil.forName(type);
          if (Map.class.isAssignableFrom(clazz) && !Externalizable.class.isAssignableFrom(clazz))
            return MAP_EXTERNALIZER;
        } catch (Exception e) {

        }
      }
    }

    return null;
  }
Ejemplo n.º 5
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;
  }
Ejemplo n.º 6
0
 protected SecurityContext loadSecurityContextFromSession() {
   HttpGraniteContext context = (HttpGraniteContext) GraniteContext.getCurrentInstance();
   HttpServletRequest request = context.getRequest();
   return (SecurityContext)
       request
           .getSession()
           .getAttribute(HttpSessionContextIntegrationFilter.SPRING_SECURITY_CONTEXT_KEY);
 }
Ejemplo n.º 7
0
 public GraniteContext initThread(String sessionId, String clientType) {
   GraniteContext context = GraniteContext.getCurrentInstance();
   if (context == null)
     context =
         SimpleGraniteContext.createThreadInstance(
             graniteConfig, servicesConfig, sessionId, applicationMap, clientType);
   return context;
 }
Ejemplo n.º 8
0
  protected AbstractChannel(
      GravityInternal gravity,
      String id,
      ChannelFactory<? extends Channel> factory,
      String clientType) {
    if (id == null) throw new NullPointerException("id cannot be null");

    this.id = id;
    GraniteContext graniteContext = GraniteContext.getCurrentInstance();
    this.clientType = clientType;
    this.sessionId = graniteContext != null ? graniteContext.getSessionId() : null;
    this.gravity = gravity;
    this.factory = factory;

    this.publisher = new AsyncPublisher(this);
    this.receiver = new AsyncReceiver(this);
  }
Ejemplo n.º 9
0
  public void logout() {
    HttpGraniteContext context = (HttpGraniteContext) GraniteContext.getCurrentInstance();
    HttpSession session = context.getSession(false);
    if (session != null
        && session.getAttribute(HttpSessionContextIntegrationFilter.SPRING_SECURITY_CONTEXT_KEY)
            != null) session.invalidate();

    SecurityContextHolder.clearContext();
  }
Ejemplo n.º 10
0
 public static String getClassName(Class<?> clazz) {
   if (Map.class.isAssignableFrom(clazz) && !Externalizable.class.isAssignableFrom(clazz)) {
     Externalizer externalizer =
         GraniteContext.getCurrentInstance().getGraniteConfig().getExternalizer(clazz.getName());
     if (externalizer == null) return "";
   }
   RemoteClass alias = clazz.getAnnotation(RemoteClass.class);
   return alias != null ? alias.value() : clazz.getName();
 }
Ejemplo n.º 11
0
 protected JavaClassDescriptor(Class<?> type) {
   GraniteConfig config = GraniteContext.getCurrentInstance().getGraniteConfig();
   this.type = type;
   this.name = getClassName(type);
   this.externalizer = config.getExternalizer(type.getName());
   this.converters = config.getConverters();
   this.encoding = findEncoding(type);
   this.properties = introspectProperties();
 }
Ejemplo n.º 12
0
  public Object authorize(AbstractSecurityContext context) throws Exception {
    log.debug("Authorize: %s", context);
    log.debug(
        "Is %s secured? %b",
        context.getDestination().getId(), context.getDestination().isSecured());

    startAuthorization(context);

    HttpGraniteContext graniteContext = (HttpGraniteContext) GraniteContext.getCurrentInstance();

    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

    SecurityContext securityContextBefore = null;
    int securityContextHashBefore = 0;
    if (graniteContext.getRequest().getAttribute(FILTER_APPLIED) == null) {
      securityContextBefore = loadSecurityContextFromSession();
      if (securityContextBefore == null) securityContextBefore = SecurityContextHolder.getContext();
      else securityContextHashBefore = securityContextBefore.hashCode();
      SecurityContextHolder.setContext(securityContextBefore);
      authentication = securityContextBefore.getAuthentication();
    }

    if (context.getDestination().isSecured()) {
      if (!isAuthenticated(authentication)
          || authentication instanceof AnonymousAuthenticationToken) {
        log.debug("Is not authenticated!");
        throw SecurityServiceException.newNotLoggedInException("User not logged in");
      }
      if (!userCanAccessService(context, authentication)) {
        log.debug("Access denied for: %s", authentication.getName());
        throw SecurityServiceException.newAccessDeniedException("User not in required role");
      }
    }

    try {
      Object returnedObject =
          securityInterceptor != null
              ? securityInterceptor.invoke(context)
              : endAuthorization(context);

      return returnedObject;
    } catch (AccessDeniedException e) {
      throw SecurityServiceException.newAccessDeniedException(e.getMessage());
    } catch (InvocationTargetException e) {
      handleAuthorizationExceptions(e);
      throw e;
    } finally {
      if (graniteContext.getRequest().getAttribute(FILTER_APPLIED) == null) {
        // Do this only when not already filtered by Spring Security
        SecurityContext securityContextAfter = SecurityContextHolder.getContext();
        SecurityContextHolder.clearContext();
        saveSecurityContextInSession(securityContextAfter, securityContextHashBefore);
      }
    }
  }
Ejemplo n.º 13
0
 protected void saveSecurityContextInSession(
     SecurityContext securityContext, int securityContextHashBefore) {
   if (securityContext.hashCode() != securityContextHashBefore
       && !(securityContext.getAuthentication() instanceof AnonymousAuthenticationToken)) {
     HttpGraniteContext context = (HttpGraniteContext) GraniteContext.getCurrentInstance();
     HttpServletRequest request = context.getRequest();
     request
         .getSession()
         .setAttribute(
             HttpSessionContextIntegrationFilter.SPRING_SECURITY_CONTEXT_KEY, securityContext);
   }
 }
Ejemplo n.º 14
0
  private Object getSessionAttribute(String attributeName) {
    Object result = null;

    // try to get session attribute from GraniteDS context
    GraniteContext graniteContext = GraniteContext.getCurrentInstance();
    if (graniteContext != null) {
      result = graniteContext.getSessionMap().get(attributeName);
    } else {
      // try to get session attribute from current request context holder session
      ServletRequestAttributes requestAttributes =
          (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
      if (requestAttributes != null) {
        HttpSession session = requestAttributes.getRequest().getSession();
        result = session.getAttribute(attributeName);
      }
    }
    if (result == null) {
      throw new InvalidSessionException("Error getting session attribute: " + attributeName);
    } else {
      return result;
    }
  }
Ejemplo n.º 15
0
 public void invalidateSession() {
   try {
     releaseRecord();
   } catch (RecordUnlockedException e) {
     // do nothing
   }
   GraniteContext graniteContext = GraniteContext.getCurrentInstance();
   if (graniteContext != null && graniteContext instanceof HttpGraniteContext) {
     HttpGraniteContext httpGraniteContext = (HttpGraniteContext) graniteContext;
     HttpServletRequest request = httpGraniteContext.getRequest();
     HttpSession session = request.getSession();
     session.invalidate();
   }
 }
  @Override
  protected ServiceException getServiceException(
      Message request, Destination destination, String method, Throwable t) {
    if (t == null) throw new NullPointerException("Parameter t cannot be null");

    Map<String, Object> extendedData = new HashMap<String, Object>();

    if (t instanceof ServiceException) {
      ((ServiceException) t).getExtendedData().putAll(extendedData);
      return (ServiceException) t;
    }

    List<Throwable> causes = new ArrayList<Throwable>();
    for (Throwable cause = t; cause != null; cause = getCause(cause)) causes.add(cause);

    String detail =
        "\n"
            + "- destination: "
            + (destination != null ? destination.getId() : "")
            + "\n"
            + "- method: "
            + method
            + "\n"
            + "- exception: "
            + t.toString()
            + "\n";

    for (int i = causes.size() - 1; i >= 0; i--) {
      Throwable cause = causes.get(i);
      for (ExceptionConverter ec :
          GraniteContext.getCurrentInstance().getGraniteConfig().getExceptionConverters()) {
        if (ec.accepts(cause, t)) return ec.convert(cause, detail, extendedData);
      }
    }

    if (getLogException()) log.error(t, "Could not process remoting message: %s", request);

    // Default exception handler
    ServiceException se =
        new ServiceException(
            t.getClass().getSimpleName() + ".Call.Failed", t.getMessage(), detail, t);
    se.getExtendedData().putAll(extendedData);
    return se;
  }
  @Test
  public void testLazyLoading() {
    TransactionDefinition def = new DefaultTransactionDefinition();

    TransactionStatus tx = txManager.getTransaction(def);
    Person person = new Person();
    entityManager.persist(person);
    txManager.commit(tx);

    tx = txManager.getTransaction(def);
    person = entityManager.find(Person.class, person.getId());
    txManager.commit(tx);

    Object result = initializeObject(person, new String[] {"contacts"});

    ClassGetter classGetter =
        GraniteContext.getCurrentInstance().getGraniteConfig().getClassGetter();
    Assert.assertTrue(
        "Collection initialized", classGetter.isInitialized(result, "contacts", null));
  }
Ejemplo n.º 18
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;
  }
Ejemplo n.º 19
0
  public boolean runReceived(AsyncHttpContext asyncHttpContext) {

    boolean httpAsParam = (asyncHttpContext != null);
    LinkedList<AsyncMessage> messages = null;
    OutputStream os = null;

    try {
      receivedQueueLock.lock();
      try {
        // Do we have any pending messages?
        if (receivedQueue.isEmpty()) return false;

        // Do we have a valid http context?
        if (asyncHttpContext == null) {
          asyncHttpContext = acquireAsyncHttpContext();
          if (asyncHttpContext == null) return false;
        }

        // Both conditions are ok, get all pending messages.
        messages = receivedQueue;
        receivedQueue = new LinkedList<AsyncMessage>();
      } finally {
        receivedQueueLock.unlock();
      }

      HttpServletRequest request = asyncHttpContext.getRequest();
      HttpServletResponse response = asyncHttpContext.getResponse();

      // Set response messages correlation ids to connect request message id.
      String correlationId = asyncHttpContext.getConnectMessage().getMessageId();
      AsyncMessage[] messagesArray = new AsyncMessage[messages.size()];
      int i = 0;
      for (AsyncMessage message : messages) {
        message.setCorrelationId(correlationId);
        messagesArray[i++] = message;
      }

      // Setup serialization context (thread local)
      Gravity gravity = getGravity();
      GraniteContext context =
          HttpGraniteContext.createThreadIntance(
              gravity.getGraniteConfig(), gravity.getServicesConfig(), null, request, response);
      ((AMFContextImpl) context.getAMFContext())
          .setCurrentAmf3Message(asyncHttpContext.getConnectMessage());

      // Write messages to response output stream.

      response.setStatus(HttpServletResponse.SC_OK);
      response.setContentType(AMF0Message.CONTENT_TYPE);
      response.setDateHeader("Expire", 0L);
      response.setHeader("Cache-Control", "no-store");

      os = response.getOutputStream();
      ObjectOutput amf3Serializer = context.getGraniteConfig().newAMF3Serializer(os);

      log.debug("<< [MESSAGES for channel=%s] %s", this, messagesArray);

      amf3Serializer.writeObject(messagesArray);

      os.flush();
      response.flushBuffer();

      return true; // Messages were delivered, http context isn't valid anymore.
    } catch (IOException e) {
      log.warn(e, "Could not send messages to channel: %s (retrying later)", this);

      GravityConfig gravityConfig = getGravity().getGravityConfig();
      if (messages != null && gravityConfig.isRetryOnError()) {
        receivedQueueLock.lock();
        try {
          if (receivedQueue.size() + messages.size()
              > gravityConfig.getMaxMessagesQueuedPerChannel()) {
            log.warn(
                "Channel %s has reached its maximum queue capacity %s (throwing %s messages)",
                this, gravityConfig.getMaxMessagesQueuedPerChannel(), messages.size());
          } else receivedQueue.addAll(0, messages);
        } finally {
          receivedQueueLock.unlock();
        }
      }

      return true; // Messages weren't delivered, but http context isn't valid anymore.
    } finally {

      // Cleanup serialization context (thread local)
      try {
        GraniteContext.release();
      } catch (Exception e) {
        // should never happen...
      }

      // Close output stream.
      try {
        if (os != null) {
          try {
            os.close();
          } catch (IOException e) {
            log.warn(e, "Could not close output stream (ignored)");
          }
        }
      } finally {
        // Cleanup http context (only if this method wasn't explicitly called with a non null
        // AsyncHttpContext from the servlet).
        if (!httpAsParam) releaseAsyncHttpContext(asyncHttpContext);
      }
    }
  }
Ejemplo n.º 20
0
  private Message handleSubscribeMessage(
      final ChannelFactory<?> channelFactory,
      final CommandMessage message,
      final boolean saveMessageInSession) {

    final GraniteContext context = GraniteContext.getCurrentInstance();

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

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

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

            String subscriptionId =
                (String) message.getHeader(AsyncMessage.DESTINATION_CLIENT_ID_HEADER);
            if (subscriptionId == null) {
              subscriptionId = UUIDUtil.randomUUID();
              message.setHeader(AsyncMessage.DESTINATION_CLIENT_ID_HEADER, subscriptionId);
            }

            DistributedData gdd = graniteConfig.getDistributedDataFactory().getInstance();
            if (gdd != null) {
              if (!gdd.hasChannelId(channel.getId())) {
                gdd.addChannelId(
                    channel.getId(),
                    channel.getFactory().getClass().getName(),
                    context.getClientType());
                log.debug("Stored channel %s in distributed data", channel.getId());
              }

              if (Boolean.TRUE
                  .toString()
                  .equals(destination.getProperties().get("session-selector"))) {
                String selector = gdd.getDestinationSelector(destination.getId());
                log.debug("Session selector found: %s", selector);
                if (selector != null) message.setHeader(CommandMessage.SELECTOR_HEADER, selector);
              }
            }

            ServiceAdapter adapter = adapterFactory.getServiceAdapter(message);

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

            postManage(channel);

            if (saveMessageInSession && !(reply instanceof ErrorMessage)) {
              // Save subscription message in distributed data (clustering).
              try {
                if (gdd != null) {
                  log.debug(
                      "Saving new subscription message for channel: %s - %s",
                      channel.getId(), message);
                  gdd.addSubcription(channel.getId(), message);
                }
              } catch (Exception e) {
                log.error(
                    e,
                    "Could not add subscription in distributed data: %s - %s",
                    channel.getId(),
                    subscriptionId);
              }
            }

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

            if (gdd != null && message.getDestination() != null) {
              gdd.setDestinationClientId(message.getDestination(), channel.getId());
              gdd.setDestinationSubscriptionId(message.getDestination(), subscriptionId);
            }

            return reply;
          }
        };

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

    // 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);
    }
  }
Ejemplo n.º 21
0
 public void releaseThread() {
   GraniteContext.release();
 }
Ejemplo n.º 22
0
  @After
  public void tearDown() throws Exception {
    interceptor.after(requestMessage, responseMessage);

    GraniteContext.release();
  }
Ejemplo n.º 23
0
  public Message handleMessage(
      final ChannelFactory<?> channelFactory, final Message message, boolean skipInterceptor) {

    AMF3MessageInterceptor interceptor = null;
    if (!skipInterceptor)
      interceptor =
          GraniteContext.getCurrentInstance().getGraniteConfig().getAmf3MessageInterceptor();

    Message reply = null;
    boolean publish = false;

    try {
      if (interceptor != null) interceptor.before(message);

      if (message instanceof CommandMessage) {
        CommandMessage command = (CommandMessage) message;

        switch (command.getOperation()) {
          case CommandMessage.LOGIN_OPERATION:
          case CommandMessage.LOGOUT_OPERATION:
            return handleSecurityMessage(command);

          case CommandMessage.CLIENT_PING_OPERATION:
            return handlePingMessage(channelFactory, command);
          case CommandMessage.CONNECT_OPERATION:
            return handleConnectMessage(channelFactory, command);
          case CommandMessage.DISCONNECT_OPERATION:
            return handleDisconnectMessage(channelFactory, command);
          case CommandMessage.SUBSCRIBE_OPERATION:
            return handleSubscribeMessage(channelFactory, command);
          case CommandMessage.UNSUBSCRIBE_OPERATION:
            return handleUnsubscribeMessage(channelFactory, command);

          default:
            throw new UnsupportedOperationException("Unsupported command operation: " + command);
        }
      }

      reply = handlePublishMessage(channelFactory, (AsyncMessage) message);
      publish = true;
    } finally {
      if (interceptor != null) interceptor.after(message, reply);
    }

    if (reply != null) {
      GraniteContext context = GraniteContext.getCurrentInstance();
      if (context.getSessionId() != null) {
        reply.setHeader("org.granite.sessionId", context.getSessionId());
        if (publish
            && context instanceof ServletGraniteContext
            && ((ServletGraniteContext) context).getSession(false) != null) {
          long serverTime = new Date().getTime();
          ((ServletGraniteContext) context)
              .getSession()
              .setAttribute(GraniteContext.SESSION_LAST_ACCESSED_TIME_KEY, serverTime);
          reply.setHeader("org.granite.time", serverTime);
          reply.setHeader(
              "org.granite.sessionExp",
              ((ServletGraniteContext) context).getSession().getMaxInactiveInterval());
        }
      }
    }

    return reply;
  }
  @Override
  public List<Property> findOrderedFields(
      final Class<?> clazz, boolean returnSettersWhenAvailable) {
    List<Property> fields =
        !dynamicClass
            ? (returnSettersWhenAvailable
                ? orderedSetterFields.get(clazz)
                : orderedFields.get(clazz))
            : null;

    if (fields == null) {
      if (dynamicClass) {
        Introspector.flushFromCaches(clazz);
      }
      PropertyDescriptor[] propertyDescriptors = TypeUtil.getProperties(clazz);
      Converters converters =
          ((ConvertersConfig) GraniteContext.getCurrentInstance().getGraniteConfig())
              .getConverters();

      fields = new ArrayList<Property>();

      List<Property> idVersionFields = new ArrayList<Property>();

      Set<String> allFieldNames = new HashSet<String>();
      for (Class<?> c = clazz; c != null; c = c.getSuperclass()) {

        List<Property> newFields = new ArrayList<Property>();

        // Standard declared fields.
        for (Field field : c.getDeclaredFields()) {
          if (!allFieldNames.contains(field.getName())
              && !Modifier.isTransient(field.getModifiers())
              && !Modifier.isStatic(field.getModifiers())
              && !field.isAnnotationPresent(Exclude.class)
              && !GrailsExternalizer.isIgnored(field)) {

            boolean found = false;
            if (returnSettersWhenAvailable && propertyDescriptors != null) {
              for (PropertyDescriptor pd : propertyDescriptors) {
                if (pd.getName().equals(field.getName()) && pd.getWriteMethod() != null) {
                  if ("id".equals(field.getName()) || "version".equals(field.getName())) {
                    if (c == clazz) {
                      idVersionFields.add(
                          new MethodProperty(
                              converters,
                              field.getName(),
                              pd.getWriteMethod(),
                              pd.getReadMethod()));
                    }
                  } else {
                    newFields.add(
                        new MethodProperty(
                            converters, field.getName(), pd.getWriteMethod(), pd.getReadMethod()));
                  }
                  found = true;
                  break;
                }
              }
            }
            if (!found) {
              if ("id".equals(field.getName()) || "version".equals(field.getName())) {
                idVersionFields.add(new FieldProperty(converters, field));
              } else {
                newFields.add(new FieldProperty(converters, field));
              }
            }
          }
          allFieldNames.add(field.getName());
        }

        // Getter annotated  by @ExternalizedProperty.
        if (propertyDescriptors != null) {
          for (PropertyDescriptor property : propertyDescriptors) {
            Method getter = property.getReadMethod();
            if (getter != null
                && getter.isAnnotationPresent(Include.class)
                && getter.getDeclaringClass().equals(c)
                && !allFieldNames.contains(property.getName())
                && !GrailsExternalizer.isIgnored(property)) {

              newFields.add(new MethodProperty(converters, property.getName(), null, getter));
              allFieldNames.add(property.getName());
            }
          }
        }

        if (isRoot(c)) {
          newFields.addAll(idVersionFields);
        }

        Collections.sort(
            newFields,
            new Comparator<Property>() {
              public int compare(Property o1, Property o2) {
                return o1.getName().compareTo(o2.getName());
              }
            });

        fields.addAll(0, newFields);
      }

      if (!dynamicClass) {
        List<Property> previousFields =
            (returnSettersWhenAvailable ? orderedSetterFields : orderedFields)
                .putIfAbsent(clazz, fields);
        if (previousFields != null) {
          fields = previousFields;
        }
      }
    }

    return fields;
  }
Ejemplo n.º 25
0
  public boolean runReceived(AsyncHttpContext asyncHttpContext) {

    GravityInternal gravity = getGravity();

    if (asyncHttpContext != null && gravity.hasUdpReceiverFactory()) {
      UdpReceiverFactory factory = gravity.getUdpReceiverFactory();

      if (factory.isUdpConnectRequest(asyncHttpContext.getConnectMessage())) {
        createUdpReceiver(factory, asyncHttpContext);
        return true;
      }

      if (udpReceiver != null) {
        if (!udpReceiver.isClosed()) udpReceiver.close(false);
        udpReceiver = null;
      }
    }

    boolean httpAsParam = (asyncHttpContext != null);
    LinkedList<AsyncMessage> messages = null;
    OutputStream os = null;

    try {
      receivedQueueLock.lock();
      try {
        // Do we have any pending messages?
        if (receivedQueue.isEmpty()) return false;

        // Do we have a valid http context?
        if (asyncHttpContext == null) {
          asyncHttpContext = acquireAsyncHttpContext();
          if (asyncHttpContext == null) return false;
        }

        // Both conditions are ok, get all pending messages.
        messages = receivedQueue;
        receivedQueue = new LinkedList<AsyncMessage>();
      } finally {
        receivedQueueLock.unlock();
      }

      HttpServletRequest request = asyncHttpContext.getRequest();
      HttpServletResponse response = asyncHttpContext.getResponse();

      // Set response messages correlation ids to connect request message id.
      String correlationId = asyncHttpContext.getConnectMessage().getMessageId();
      AsyncMessage[] messagesArray = new AsyncMessage[messages.size()];
      int i = 0;
      for (AsyncMessage message : messages) {
        message.setCorrelationId(correlationId);
        messagesArray[i++] = message;
      }

      // Setup serialization context (thread local)
      GraniteContext context =
          HttpGraniteContext.createThreadIntance(
              gravity.getGraniteConfig(), gravity.getServicesConfig(), null, request, response);
      ((AMFContextImpl) context.getAMFContext())
          .setCurrentAmf3Message(asyncHttpContext.getConnectMessage());

      // Write messages to response output stream.
      GravityServletUtil.serialize(
          gravity, response, messagesArray, ContentType.forMimeType(request.getContentType()));

      return true; // Messages were delivered, http context isn't valid anymore.
    } catch (ServletException e) {
      log.error(e, "Configuration error for channel: %s", getId());

      return true;
    } catch (IOException e) {
      log.warn(e, "Could not send messages to channel: %s (retrying later)", getId());

      GravityConfig gravityConfig = getGravity().getGravityConfig();
      if (gravityConfig.isRetryOnError()) {
        receivedQueueLock.lock();
        try {
          if (receivedQueue.size() + messages.size()
              > gravityConfig.getMaxMessagesQueuedPerChannel()) {
            log.warn(
                "Channel %s has reached its maximum queue capacity %s (throwing %s messages)",
                getId(), gravityConfig.getMaxMessagesQueuedPerChannel(), messages.size());
          } else receivedQueue.addAll(0, messages);
        } finally {
          receivedQueueLock.unlock();
        }
      }

      return true; // Messages weren't delivered, but http context isn't valid anymore.
    } finally {
      // Cleanup serialization context (thread local)
      try {
        GraniteContext.release();
      } catch (Exception e) {
        // should never happen...
      }

      // Close output stream.
      try {
        if (os != null) {
          try {
            os.close();
          } catch (IOException e) {
            log.warn(e, "Could not close output stream (ignored)");
          }
        }
      } finally {
        // Cleanup http context (only if this method wasn't explicitly called with a non null
        // AsyncHttpContext from the servlet).
        if (!httpAsParam) releaseAsyncHttpContext(asyncHttpContext);
      }
    }
  }