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); } }
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); } } }
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; }
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; }
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; }
protected SecurityContext loadSecurityContextFromSession() { HttpGraniteContext context = (HttpGraniteContext) GraniteContext.getCurrentInstance(); HttpServletRequest request = context.getRequest(); return (SecurityContext) request .getSession() .getAttribute(HttpSessionContextIntegrationFilter.SPRING_SECURITY_CONTEXT_KEY); }
public GraniteContext initThread(String sessionId, String clientType) { GraniteContext context = GraniteContext.getCurrentInstance(); if (context == null) context = SimpleGraniteContext.createThreadInstance( graniteConfig, servicesConfig, sessionId, applicationMap, clientType); return context; }
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); }
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(); }
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(); }
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(); }
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); } } }
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); } }
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; } }
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)); }
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; }
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); } } }
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); } }
public void releaseThread() { GraniteContext.release(); }
@After public void tearDown() throws Exception { interceptor.after(requestMessage, responseMessage); GraniteContext.release(); }
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; }
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); } } }