Re: Finding the base reference for an application
[Sorry for the delay, I had been sick for a few days] Rob: at least one of the reverse proxies is an Apache, but I don't have any control over the mod_proxy configuration. There might be others on the other side, too. The sysadmins seem to like the Apache default with the mangled headers, although I don't really understand why either. But it seems to be one of those topics they don't really want to discuss (which makes me question it less verbally but more mentally :-) ). David: if you use Apache 2 you can turn the host mangling off: http://httpd.apache.org/docs/2.0/mod/mod_proxy.html#proxypreservehost I was hoping there is some hook in the Restlet engine to do a reverse mangling right when the request comes in, but maybe I'll just leave my hacks for now and hope it's not going to fall apart in the next maintenance cycle. Peter Rob Heittman wrote: Well, that's partly why I complicated the situation with a hostname change, port change, and a URI prefix change (because the URI part I can't deal with via the host header alone). But -- assuming the only difference is the hostname -- it's a question of who's doing the configuring of the creative proxy setup. If the proxy admin and server admin are the same person or can collaborate, then what you describe is fine. But here, couldn't I maybe just use IP forwarding/NAT, and avoid proxying at all ... ? If the proxy admin can't count on the server admin to accept the external hostnames, then the proxy admin would definitely want the host header rewritten to something the server would understand internally. For your EC2 node cluster can you just use a DNS round robin? One nice thing about RESTful services is that it typically doesn't matter a hoot which node responds. If you have a fairly dynamic DNS that can take a bad (or under-maintenance) node out of rotation, that can do a good job for a lot of simple cases. I know vanishingly little about EC2 though ... don't even know if nodes have discrete IPs :-) On Fri, Apr 24, 2009 at 8:57 PM, David Fogel carrotsa...@gmail.com wrote: Hi Rob- Okay, I think I'm getting the idea of what you're using the proxy for. But in the situation you describe of routing an external domain temporarily to some internal desktop server, couldn't you use virtual hosts to do the routing in the desktop, and use the original external domain? i.e. couldn't you have, on your internal desktop, a virtual host set up for demosomething.solertium.com? Why does the code need to know anything at all about mydesktophost.internal.solertium.com:8182? Sorry for all the grilling, but like I said, we've been trying to figure out a good architecture for deploying our restlet-osgi stuff on a cluster of amazon EC2 nodes, (and Amazon won't be coming out with their built-in load-balancing feature until later in the summmer- curses!), and so I'm in the midst of diving into networking sysadmin stuff that I know too little about... -Dave -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=1900649 -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=1901113 -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=1991049
Re: Time to live for classpath references
Thanks, I'll try that -- at least you saved me from finding the hack myself :-) Is there an RFE to vote upon? I think controlling the caches can be quite important, especially if you have lots of small objects. I'd personally even go as far as having a parameter on the constructor of directory that toggles infinite caching. If the resource is truly static with a URI encoding its revision, then you will never need the cache expiry. Peter Rob Heittman wrote: We still do this: http://gogoego.googlecode.com/svn/trunk/modules/com.solertium.util.restlet/src/com/solertium/util/restlet/ClapCacheDirectory.java If there's a better way, I'd love to adopt it too. On Thu, Feb 19, 2009 at 11:29 PM, Peter Becker pbec...@itee.uq.edu.au wrote: Hello, I'm using the CLAP protocol to get static content such as JavaScript delivered. I'd like to have those expire way down in the future since I use URLs that encode the file version and some of the JS libraries I use create quite a few hits to the server. I'm using Restlet 1.1.2 with the Restlet engine. I've tried a number of things, but nothing seems to work. What I am currently doing is this: public static void main(String[] args) throws Exception { Component component = new Component(); component.getServers().add(Protocol.HTTP, configuration.getHttpPort()); component.getClients().add(Protocol.CLAP).getContext().getParameters().add(timeToLive,604800); component.getDefaultHost().attach(new Pronto()); component.start(); } and in createRoot() I have a Router to which I attach a directory like this: router.attach(/javascript, new Directory(getContext(), LocalReference.createClapReference(LocalReference.CLAP_THREAD, /javascript))); I can't see any relevant header in the responses, though -- somehow setting the parameter doesn't seem to have any impact. Am I missing something? BTW: the Server header says Noelios-Restlet-Engine/1.1..2, which I suppose has a dot too many. Regards, Peter -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=1196339 -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=1198252 -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=1211667
Time to live for classpath references
Hello, I'm using the CLAP protocol to get static content such as JavaScript delivered. I'd like to have those expire way down in the future since I use URLs that encode the file version and some of the JS libraries I use create quite a few hits to the server. I'm using Restlet 1.1.2 with the Restlet engine. I've tried a number of things, but nothing seems to work. What I am currently doing is this: public static void main(String[] args) throws Exception { Component component = new Component(); component.getServers().add(Protocol.HTTP, configuration.getHttpPort()); component.getClients().add(Protocol.CLAP).getContext().getParameters().add(timeToLive,604800); component.getDefaultHost().attach(new Pronto()); component.start(); } and in createRoot() I have a Router to which I attach a directory like this: router.attach(/javascript, new Directory(getContext(), LocalReference.createClapReference(LocalReference.CLAP_THREAD, /javascript))); I can't see any relevant header in the responses, though -- somehow setting the parameter doesn't seem to have any impact. Am I missing something? BTW: the Server header says Noelios-Restlet-Engine/1.1..2, which I suppose has a dot too many. Regards, Peter -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=1196339
Re: Managing a JPA/Hibernate session
Paul, correct me if I am wrong, but I believe your solution suffers from the same problem as mine: if there is still data to fetch during the processing of a representation object (as it happens on the write(..) method of the TemplateRepresentation of the Freemarker extension), then you will get exceptions from the persistence layer. By using the ConnectorService the JPA sessions lives long enough to include the call to the write(..) method. Peter Paul Austin wrote: Below is my solution which is based on a similar ServletFilter from the SpringFramework. You will need to set the entityManagerFactory before using this. I normall have that configured in spring and get a reference to this filter bean from the context. package com.revolsys.restlet; import java.util.Map; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.PersistenceException; import org.apache.log4j.Logger; import org.restlet.Filter; import org.restlet.data.Request; import org.restlet.data.Response; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.orm.jpa.EntityManagerFactoryUtils; import org.springframework.orm.jpa.EntityManagerHolder; import org.springframework.transaction.support.TransactionSynchronizationManager; public class OpenEntityManagerFilter extends Filter { private static final Logger logger = Logger.getLogger(OpenEntityManagerFilter.class); private EntityManagerFactory entityManagerFactory; protected int beforeHandle(Request request, Response response) { if (TransactionSynchronizationManager.hasResource(entityManagerFactory)) { request.getAttributes().put(this.toString(), Boolean.TRUE); } else { logger.debug(Opening JPA EntityManager in OpenEntityManagerFilter); try { EntityManager em = entityManagerFactory.createEntityManager(); TransactionSynchronizationManager.bindResource(entityManagerFactory, new EntityManagerHolder(em)); } catch (PersistenceException ex) { throw new DataAccessResourceFailureException( Could not create JPA EntityManager, ex); } } return super.beforeHandle(request, response); } protected void afterHandle(Request request, Response response) { MapString, Object attributes = request.getAttributes(); if (attributes.get(this.toString()) != Boolean.TRUE) { EntityManagerHolder emHolder = (EntityManagerHolder)TransactionSynchronizationManager.unbindResource(entityManagerFactory); logger.debug(Closing JPA EntityManager in OpenEntityManagerFilter); EntityManagerFactoryUtils.closeEntityManager(emHolder.getEntityManager()); } } public EntityManagerFactory getEntityManagerFactory() { return entityManagerFactory; } public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) { this.entityManagerFactory = entityManagerFactory; } } On Wed, Feb 18, 2009 at 6:45 AM, Jerome Louvel jerome.lou...@noelios.comwrote: Hi guys, This is such a hook available. See the ConnectorService#afterSend method: http://www.restlet.org/documentation/snapshot/api/org/restlet/service/ConnectorService.html#afterSend(org.restlet.resource.Representhttp://www.restlet.org/documentation/snapshot/api/org/restlet/service/ConnectorService.html#afterSend%28org.restlet.resource.Represent ation) Hope this helps! Best regards, Jerome Louvel -- Restlet ~ Founder and Lead developer ~ http://www.restlet.org Noelios Technologies ~ Co-founder ~ http://www.noelios.com -Message d'origine- De : Michael Terrington [mailto:mich...@terrington.id.au] Envoye : mercredi 18 fevrier 2009 12:23 A : discuss@restlet.tigris.org Objet : Re: Managing a JPA/Hibernate session Hi Peter, I recently encountered this problem myself. I ended up creating a Representation wrapper that would close my EM after the call to write. The code [1] is part of restlet-jpa [2]. Regards, Michael. [1] - http://trac.sarugo.org/restlet- jpa/browser/trunk/src/main/java/org/sarugo/restlet/jpa/TransactionFilter.java [2] - http://trac.sarugo.org/restlet-jpa/ On Wed, Feb 18, 2009 at 10:22 AM, Peter Becker pbec...@itee.uq.edu.au wrote: Hello, I'm using Restlet above a JPA persistence layer with Hibernate as provider. That works reasonably well, but unfortunately I haven't found a way to handle the persistence sessions properly. What I would like to see is that a new session is opened whenever needed and is closed after all request processing is done. This is my current attempt: public class EntityManagerFilter extends Filter implements EntityManagerSource { private final EntityManagerFactory emf; private final ThreadLocalEntityManager entityManagerTL = new ThreadLocalEntityManager(); public EntityManagerFilter(Context context, Restlet
RE: Managing a JPA/Hibernate session
Thanks Jerome, that was what I was looking for. I just replaced the type and the afterHandle with afterSend and it seems all works as I wanted. For the record: it gets attached on the Application instance via setConnectorService(..) -- didn't take too long to find, but it might be a good addition for the JavaDoc of that class ;-) Cheers, Peter Jerome Louvel wrote: Hi guys, This is such a hook available. See the ConnectorService#afterSend method: http://www.restlet.org/documentation/snapshot/api/org/restlet/service/ConnectorService.html#afterSend(org.restlet.resource.Represent ation) Hope this helps! Best regards, Jerome Louvel -- Restlet ~ Founder and Lead developer ~ http://www.restlet.org Noelios Technologies ~ Co-founder ~ http://www.noelios.com -Message d'origine- De : Michael Terrington [mailto:mich...@terrington.id.au] Envoye : mercredi 18 fevrier 2009 12:23 A : discuss@restlet.tigris.org Objet : Re: Managing a JPA/Hibernate session Hi Peter, I recently encountered this problem myself. I ended up creating a Representation wrapper that would close my EM after the call to write. The code [1] is part of restlet-jpa [2]. Regards, Michael. [1] - [http://trac.sarugo.org/restlet- jpa/browser/trunk/src/main/java/org/sarugo/restlet/jpa/TransactionFilter.java [2] - http://trac.sarugo.org/restlet-jpa/ On Wed, Feb 18, 2009 at 10:22 AM, Peter Becker pbec...@itee.uq.edu.au wrote: Hello, I'm using Restlet above a JPA persistence layer with Hibernate as provider. That works reasonably well, but unfortunately I haven't found a way to handle the persistence sessions properly. What I would like to see is that a new session is opened whenever needed and is closed after all request processing is done. This is my current attempt: public class EntityManagerFilter extends Filter implements EntityManagerSource { private final EntityManagerFactory emf; private final ThreadLocalEntityManager entityManagerTL = new ThreadLocalEntityManager(); public EntityManagerFilter(Context context, Restlet next, EntityManagerFactory emf) { super(context, next); this.emf = emf; } public EntityManagerFilter(Context context, EntityManagerFactory emf) { super(context); this.emf = emf; } public EntityManagerFilter(EntityManagerFactory emf) { this.emf = emf; } public EntityManager getEntityManager() { // we lazily initialize in case the entity manager is not actually needed // by a request EntityManager entityManager = entityManagerTL.get(); if(entityManager == null) { entityManager = emf.createEntityManager(); entityManagerTL.set(entityManager); } return entityManager; } @Override protected void afterHandle(Request request, Response response) { EntityManager entityManager = entityManagerTL.get(); if(entityManager!=null) { entityManagerTL.remove(); assert entityManager.isOpen(): Entity manager should only be closed here but must have been closed elsewhere; entityManager.close(); } super.afterHandle(request, response); } } This filter is attached as the root of the application, forwarding to the router that does the main dispatch. The approach works to some extent, but with a huge but: most of the time I produce TemplateRepresentations to render data with Freemarker. The processing of those templates happens after the afterHandle(..) method of the filter, which means that the session is closed and if the template uses anything that is not eagerly fetched and the Java code hasn't used it will get an exception from the persistence layer. That is actually a pretty common case since a lot of the details of objects is needed only in the template rendering. Currently I work around that problem by explicitly loading objects in Java code. I'd rather solve that problem properly, but I can't find a hook that gets called after the write(..) method of the representations. Long intro, short question: Is there such thing? Thanks, Peter -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=1182479 -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=1185212 -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=1186386 -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=1189311
Managing a JPA/Hibernate session
Hello, I'm using Restlet above a JPA persistence layer with Hibernate as provider. That works reasonably well, but unfortunately I haven't found a way to handle the persistence sessions properly. What I would like to see is that a new session is opened whenever needed and is closed after all request processing is done. This is my current attempt: public class EntityManagerFilter extends Filter implements EntityManagerSource { private final EntityManagerFactory emf; private final ThreadLocalEntityManager entityManagerTL = new ThreadLocalEntityManager(); public EntityManagerFilter(Context context, Restlet next, EntityManagerFactory emf) { super(context, next); this.emf = emf; } public EntityManagerFilter(Context context, EntityManagerFactory emf) { super(context); this.emf = emf; } public EntityManagerFilter(EntityManagerFactory emf) { this.emf = emf; } public EntityManager getEntityManager() { // we lazily initialize in case the entity manager is not actually needed // by a request EntityManager entityManager = entityManagerTL.get(); if(entityManager == null) { entityManager = emf.createEntityManager(); entityManagerTL.set(entityManager); } return entityManager; } @Override protected void afterHandle(Request request, Response response) { EntityManager entityManager = entityManagerTL.get(); if(entityManager!=null) { entityManagerTL.remove(); assert entityManager.isOpen(): Entity manager should only be closed here but must have been closed elsewhere; entityManager.close(); } super.afterHandle(request, response); } } This filter is attached as the root of the application, forwarding to the router that does the main dispatch. The approach works to some extent, but with a huge but: most of the time I produce TemplateRepresentations to render data with Freemarker. The processing of those templates happens after the afterHandle(..) method of the filter, which means that the session is closed and if the template uses anything that is not eagerly fetched and the Java code hasn't used it will get an exception from the persistence layer. That is actually a pretty common case since a lot of the details of objects is needed only in the template rendering. Currently I work around that problem by explicitly loading objects in Java code. I'd rather solve that problem properly, but I can't find a hook that gets called after the write(..) method of the representations. Long intro, short question: Is there such thing? Thanks, Peter -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=1182479