Sling resource.getResourceResolver() Vs SlingHttpRequest.getResourceResolver - aem

In my project I am seeing in Sling model classes, the resource resolver is fetched in 2 ways
#Inject private Resource resource;
ResourceResolver resolver = resource.getResourceResolver();
Vs
#Inject #Self private SlingHttpServletRequest request;
ResourceResolver resolver = request.getResourceResolver();
While both are Sling implementations, is there any benefit of using one opposed other? Or are these 2 yield same resolver with no performance difference?

Resource#getResourceResolver returns the ResourceResolver with which the resource was retrieved from the repository. This retrieval will often happen in association with a request but that doesn't have to be the case.
SlingHttpServletRequest#getResourceResolver returns the ResourceResolver with which the requested resource was retrieved.
These resource resolvers may be the same but it depends on the way your Sling Model is instantiated.
For example, imagine an OSGi Service that is not directly associated with a request. It could be an event handler of some sort that executes once in a while and loads some resources. It could, for example, retrieve a ResourceResolver using a ResourceResolverFactory and a service-user mapping.
ResourceResolver serviceResourceResolver = resourceResolverFactory.getServiceResourceResolver(authenticationInfo);
Resource someResource = serviceResourceResolver.getResource("/path/to/resource");
someResource.adaptTo(MyModel.class);
In this case, you will not be able to inject a SlingHttpSerlvetRequest object so this will fail:
#Inject
#Self
private SlingHttpServletRequest request;
Generally speaking, there is, therefore, a difference in semantics.
If we look at the simple case where the resource you're adapting was retrieved in scope of a request, the following two ResourceResolver instances should be equivalent:
#Inject private Resource resource;
ResourceResolver resolver = resource.getResourceResolver();
and
#Inject #Self private SlingHttpServletRequest request;
ResourceResolver resolver = request.getResourceResolver();
The resolvers will have the same permissions as the user making the request.
When it comes to performance, I'm not aware of any documentation recommending one approach or the other.

Related

#ScriptVariable resourceResolver vs #SlingObject resourceResolver

Can anyone explain to me the difference between calling resourceResolver by annotating #ScriptVariable and by annotating #SlingObject? In what context do they behave differently?
The key difference is in the way the object is retrieved. #ScriptVariable and #SlingObject are injector-specific annotations. This means that you can use them to instruct Sling Models to use a particular injector.
The injector that recognises the #ScriptVariable annotation can inject objects available as Scripting Variables. In case ot the resourceResolver, it should be the one associated with the request. Same as slingRequest.getResourceResolver().
Looking at the code, the injector that kicks in on fields annotated with #SlingObject is a bit more interesting in that it will inspect the adaptable (from which your Sling Model is being adapted) and obtain the resolver accordingly:
If the adaptable is a Resource, it'll return resource.getResourceResolver(), i.e. the resolver originally used to load the resource. This may be quite aribtrary.
If the adaptable is a SlingHttpServletRequest, it'll return request.getResourceResolver(), i.e. the resolver instantiated by Sling in association with the request and the session of the user issuing the request.
If the adaptable itself is a ResourceResolver, it will be returned directly.
In some cases, the difference between the three will be negligible, but sometimes it will be important which resolver you choose. If your model is, for example, supposed to be used outside the scope of a request (imagine it's instantiated by an OSGi service that runs on a schedule and there's no incoming request), you'll be better off using resource or resourceResolver as an adaptable.

Jersey 2: filters and #Context injections

I've the following question:
ContainerRequestFilter is a singleton, but reading this:
Jaxrs-2_0 Oracle Spec
in chapter 9.2, they say:
Context is specific to a particular request but instances of certain JAX-RS components (providers and resource classes with a lifecycle other than per-request) may need to support multiple concurrent requests. When injecting an instance of one of the types listed in Section 9.2, the instance supplied MUST be capable of selecting the correct context for a particular request. Use of a thread-local proxy is a common way to achieve this.
In the chapter 9.2, the HttpServletRequest is not mentioned.
So the question is: is it safe in terms of concurrency to inject the HttpServletRequest inside a custom ContainRequestFilter?
I mean this:
#Provider
#PreMatching
public class AuthenticationFilter implements ContainerRequestFilter {
#Context private HttpServletRequest request;
#Override
public void filter(ContainerRequestContext requestContext) throws IOException {
// This is safe because every thread call the method with its requestContext
String path = requestContext.getUriInfo().getPath(true);
// Is this safe? The property request is injected by using #Context annotation (see above)
String toReturn = (String)request.getAttribute(name);
[...]
}
I did some empirical tests on my IDE in debug mode, sending with two different browsers two different and concurrent requests and it seems to work well; I noticed that the filter's instance is ever the same (it's a singleton), but the injected HttpServletRequest is different in the two cases.
I readed even this thread: How to access wicket session from Jersey-2 request filter? and it seems that my tests are confirmed.
But I still have doubts.
Confirm?
Yes it's safe. To understand the problem, you should understand how scopes work. In any framework that deals with scopes (and injection), the feature is implemented similarly. If an object is in a singleton scope and another object in a lesser scope needs to be injected, usually a proxy of the object will be injected instead. When a call is made on the object, it's actually a call on the proxy.
Though the spec may not mention the HttpServletRequest specifically, most JAX-RS implementation have support for this. With Jersey in particular, if this was not possible (meaning the object is not proxiable), then you would get an error message on startup with something like "not within a request scope". The reason is that the ContainerRequestFilter is created on app startup, and all the injections are handled at that time also. If the HttpServletRequest was not proxiable, it would fail to inject because on startup, there is no request scope context.
To confirm that it is not the actual HttpServletRequest and is a proxy, you can log the request.getClass(), and you will see that it is indeed a proxy.
If you are unfamiliar with this pattern, you can see this answer for an idea of how it works.
See Also:
Injecting Request Scoped Objects into Singleton Scoped Object with HK2 and Jersey

Does Guice Persist provide transaction scoped or application managed EntityManager?

We use Guice Persist to inject EntityManager in our project.
E.g.
public class MyDao{
#Inject
EntityManager em;
public void someMethod(){
//uses em instance
}
}
But it is unclear for us how injected instance of EntityManager is about to be used.
What type of EntityManager is this? (see e.g.: types of entity managers) Under the hood Guice Persist instantiates it via EntityManagerFactory.createEntityManager() so I'd say it's application-managed entity manager. But in official Wiki they write about seesion-per-transaction strategy, which suggests that EntityManager is (pseudo) transaction-scoped.
Should we invoke close() on it manually? Or Guice will take care of it?
What is the scope of first level cache? Only single transaction (like in transaction-scoped entity managers) or as long as I use the same injected instance of EntityManager (like in application managed entity managers)?
Even though the question is perfectly answered by Piotr I'd like to add some practical advise on how to use guice-persist.
I've been having issues with it which were pretty hard to debug. In my application certain threads would display outdated data and sometimes EntityManager instances were left with old dead database connections. The root cause was to be found in the way I used the #Transactional annotation (I only used them for methods that do updates/inserts/deletes, not for read-only methods). guice-persist stores EntityManager instances in a ThreadLocal as soon as you call get() on an injected Provider<EntityManager> instance (which I did for read-only methods). However, this ThreadLocal is only removed if you also call UnitOfWork.end() (which normally is done by the interceptor if #Transactional is on the method). Not doing so will leave the EM instance in the ThreadLocal so that eventually every thread in your thread pool will have an old EM instance with stale cached entities.
So, as long as you stick to the following simple rules the usage of guice-persist is straight forward:
Always inject Provider<EntityManager> instead of EntityManager directly.
For transaction-scoped semantics: always annotate each method with #Transactional (even the read-only methods). This way the JpaLocalTxnInterceptor will intercept the calls to your annotated methods making sure not only to start and commit transactions but also to set and unset EM instances in the ThreadLocal.
For request-scoped semantics: use the PersistFilter servlet filter that ships with guice-persist. It will call begin() and end() on the UnitOfWork for you before and after the request is done, thereby populating and cleaning up the ThreadLocal.
Hope this helps!
I did some research of the source code of Guice-persist and read through comments under Guice-persist wiki pages and these are the answers that I needed:
1 . Lifecycle management of EntityManager is kind of broken if it's injected via #Inject EntityManager. As stated in one of the comments on the Wiki:
I confirm that inject directly an EntityManager instead of a provider
can be dangerous. If you're not inside a UnitOfWork or a method
annotated with #Transaction, the first injection of an EntityManager
in a thread will create a new EntityManager, never destroy it, and
always use this specific EntityManager for this thread (EM are stored
thread-local). This can lead to terrible issues, like injection of
dead entityManager (connection closed, etc) So my recommendation if to
always inject a Provider, or at least to inject
directly an EntityManager only inside an opened UnitOfWork.
So example in my question isn't the most correct usage. It creates singleton instance of EntityManager (per-thread) and will inject this instance everywhere :-(.
However if I've injected Provider and used it inside #Transactional method then the instance of EntityManager would be per-transaction. So the answer to this question is: if injected and used correctly, the entity manager is transaction-scoped.
2 . If injected and used correctly then I don't need to manualy close entity manager (guice-persist will handle that for me). If used incorrectly, closing manually would be very bad idea (closed instance of EntityManager would be injected in every place when I #Inject EntityManager )
3 . If injected and used correctly then the scope of L1 cache is single transaction. If used incorrectly, the scope of the L1 cache is the lifetime of application (EntityManager is singleton)
1. It depends on you module cofiguration. There are some basic bindings:
JpaPersistanceService
public class JpaPersistanceService implements Provider<EntityManager> {
private EntityManagerFactory factory;
public JpaPersistanceService(EntityManagerFactory factory) {
this.factory = factory;
}
#Override
public EntityManager get() {
return factory.createEntityManager();
}
}
Module binding
EntityManagerFactory factory = Persistence.createEntityManagerFactory(getEnvironment(stage));
bind(EntityManager.class).annotatedWith(Names.named("request")).toProvider(new JpaPersistanceService(factory)).in(RequestScoped.class);
bind(EntityManager.class).annotatedWith(Names.named("session")).toProvider(new JpaPersistanceService(factory)).in(SessionScoped.class);
bind(EntityManager.class).annotatedWith(Names.named("app")).toProvider(new JpaPersistanceService(factory)).asEagerSingleton;
Usage
#Inject #Named("request")
private EntityManager em; //inject a new EntityManager class every request
#Inject #Named("session")
private Provider<EntityManager> emProvider; //inject a new EntityManager class each session
//This is little bit tricky, cuz EntityManager is stored in session. In Stage.PRODUCTION are all injection created eagerly and there is no session at injection time. Session binding should be done in lazy way - inject provider and call emProvider.get() when em is needed;
#Inject #Named("application")
private EntityManager em; //inject singleton
2. Yes, you should or you will use JpaPersistModule [javadoc]
3. Well, this is about JPA configuration in persistence.xml and EntityManager scope
I'm injecting a provider .... but I suspect something is wrong.
When I try to redeploy an application ALWAYS I have to restar the server because the JPA classes are cached.
It happens the following pseudo-bug
https://bugs.eclipse.org/bugs/show_bug.cgi?id=326552
Theoretically by injecting a Provider and getting an instance of EntityManager you should not close anything ....

Jersey Jaxb Issues

We are having a problem with generic Payload while using Jersey. Here is our Domain object.
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class Event<T> {
private T eventPayload;
private String eventType;
}
Here we have top level domain object defined. But the internal domain object is generic.
Now on the resource endpoint we have something like this as we know that the sub-domain object we were expecting is.
#POST
#Path("log")
#Consumes(MediaType.APPLICATION_XML)
public Response writeLog(Event<LogPayload> event)
But this doesn’t work.
The event instance is created but the subdomain is not populated correctly.
It just tries to populate the sub-domain object with any random domain object which has the same root element as in the XML (there may be more than one).
Our Solution:
This is our solution, but I am sure this is not the best.
We have to modify our parent domain object have a String variable which stores XML-representation of the generic payload in a String format. For this we have had to write our own Jaxb marshaller.
Modifications to the Event
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class Event<T> {
#XmlTransient
private T eventPayload;
private String eventType;
private String payLoadXML;
// Changes to the constructor:
public Event(T eventPayload ……) {
super();
this.eventPayload = eventPayload;
payLoadXML = JAXBUtils.marshall(eventPayload,false); }}
On the resource side once we get the parent Event object, we have to again use our own jaxb marshaller to get the required domain object from the payloadXML as follows.
#POST
#Path("log")
#Consumes(MediaType.APPLICATION_XML)
public Response writeLog(Event<LogPayload> event)
LogPayload log1 = (LogPayload) JAXBUtils.unMarshall(
event.getPayLoadXML(),LogPayload.class);
So ineffect we are using our jaxbmarshaller to marshall and unmarshall the generic subdomain object before and after making the rest call….
Please lets us know if there is a better way to do this ?
Thanks,
ND
I've seen the same question before and I don't think this will work as you originally planned. Web services (json/xml, rest/soap) usually create a service description (like wsdl) and a generic type technically cannot be part of this description. What you could do is to publish multiple services where Event is not generic anymore.

SessionScoped getting different instances

I'm getting different instances of a #SessionScoped bean for two calls to the same user session. What can lead to this?
A bean annotated #SessionScoped is injected into a servlet, and a RESTEasy JAX-RS web service endpoint. A user logs in using HTTPS with a certificate. First call goes to the RESTEasy endpoint. The next call from the browser goes to the servlet. I'd expect the same bean instance in both calls, but they are different. ... Any ideas?
Using JBoss 7.0.1
bean:
#Stateful
#SessionScoped
public class MyBean implements Serializable { ... }
REST endpoint:
#Path("/one")
public class MyService extends JAXRSPlugin {
#Inject MyBean myBean;
...
}
Servlet:
#WebServlet(urlPatterns = "/two", asyncSupported = true)
public class MyServlet extends HttpServlet {
#Inject MyBean myBean;
...
}
Turns out the REST service methods are not really supposed to have an HttpSession to share state. REST services are supposed to be stateless. They are given #SessionScoped beans as if they were #RequestScoped by design.
It's not what I want for this case, but maybe I should just not use REST for these calls. Mainly I just wanted the handy mapping of URL paths to methods in my REST service class. Servlets don't have path-to-method-mapping like that, as far as I know.
Basically I see 3 options: (1) make of find a dispatching mechanism to use in one Servlet, (2) use multiple Servlets, or (3) mis-use the REST by abusing the #Context HttpServletRequest to get to the HttpSession. I don't like abusing APIs, so option 3 is out. CDI might make option 2 cool, but option 1 is probably more common (and so might be easier to maintain by others).