How to resolve Autofac per-request service from custom attribute - entity-framework

I have configured my EF context configured like so
b.RegisterAssemblyTypes(webAssembly, coreAssembly)
.Where(t => t.IsAssignableTo<DbContext>())
.InstancePerLifetimeScope();
I would like to use it from a custom authorization attribute that hits the database using my EF context. This means no constructor-injection. I achieve this by using CommonSeviceLocator
var csl = new AutofacServiceLocator(container);
ServiceLocator.SetLocatorProvider(() => csl);
...
var user = await ServiceLocator.Current
.GetInstance<SiteContext>().FindAsync(id);
I am finding that this fails with a "multiple connections not supported" error if the browser issues two simultaneous requests to routes using this attribute. It seems like this might be due to what is mentioned in this answer. My guess is that ServiceLocator resolves from the root scope rather than the web request scope and the two request are conflicting (either request in isolation works fine).
This seems confirmed by that when I change to InstancePerRequest() I get this from any invocation of the attribute.
Autofac.Core.DependencyResolutionException No scope with a Tag matching 'AutofacWebRequest' is visible from the scope in which the instance was requested. This generally indicates that a component registered as per-HTTP request is
being requested by a SingleInstance() component (or a similar scenario.) Under the web integration always request dependencies from the DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime, never from the container itself.
So it seems like maybe ServiceLocator is simply not the way to go.
How do I resolve the request-scoped SiteContext from inside the attribute (using a service-locator pattern)?

Your issue derives from the fact that you are trying to put behavior inside of an Attribute. Attributes are for defining meta-data on code elements and assemblies, not for behavior.
Microsoft's marketing of Action Filter Attributes has led people implementing DI down the wrong path by putting both the Filter and the Attribute into the same class. As described in the post passive attributes, the solution is to break apart filter attributes into 2 classes:
An attribute that contains no behavior to mark code elements with meta-data.
A globally-registered filter that scans for the attribute and executes the desired behavior if present.
See the following for more examples:
Constructor Dependency Injection WebApi Attributes
Unity Inject dependencies into MVC filter class with parameters
Implementing passive attributes with dependencies that should be resolved by a DI container
Dependency Injection in Attributes: don’t do it!
Injecting dependencies into ASP.NET MVC 3 action filters. What's wrong with this approach?
How can I test for the presence of an Action Filter with constructor arguments?
Another option is to use IFilterProvider to resolve the filters as in IFilterProvider and separation of concerns.
Once you get your head around the fact that Attributes should not be doing anything themselves, using them with DI is rather straightforward.

Related

CQ/AEM - What are the 'resource' in a CQ form component?

I'm trying to understand how CQ form components works.
I see that they use a variable called 'resource' a lot. For example, in the beginning of every componenet it always goes:
final String name = FormsHelper.getParameterName(resource);
final String id = FormsHelper.getFieldId(slingRequest, resource);
final boolean required = FormsHelper.isRequired(resource);
I know that Sling treats everything as a resource. But what exactly is this specific piece of 'resource'? Where is it defined? Where does it come from? And what does it contain?
The resource variable, which is an implementation of org.apache.sling.api.resource.Resource, is an object that represents a node entity in the jcr repository, but comes with some additional convenience methods compared to e.g. lower level javax.jcr.Node object.
In this case the mentioned resource likely represents the component's resource.
To explain why sling is using the terminology Resource:
A resource is a fundamental concept in restful APIs.
Resources are typed objects with associated data, relationships to other resources and methods that operate on it.
Sling is actually a restful layer on top of a Java Content Repository.
For the sling layer the repository is a virtual tree of resources.
I highly recommend you to read the official documentation for more details on this topic https://sling.apache.org/documentation/the-sling-engine/resources.html

What is the difference between BasicHttpRequest and HttpGet, HttpPost, etc in Apache HTTP Client 4.3 ?

I am creating HTTP request using Apache HTTP Client version 4.3.4. I see there are some classes like HttpGet,... and there is also a class BasicHttpRequest. I am not sure which one to use.
Whats the difference and which one should be used in which condition ?
BasicHttpRequest is provided by the core library. As its name suggests it is pretty basic: it enforces no particular method name or type, nor does it attempt to validate the request URI. The URI parameter can be any arbitrary garbage. HttpClient will dutifully transmit it to server as is, if it is unable to parse it to a valid URI.
HttpUriRequest variety on the other hand will enforce specific method type and will require a valid URI. Another important feature is that HttpUriRequest can be aborted at any point of their execution.
You should always be using classes that implement HttpUriRequest per default.
I was just browsing the 4.3.6 javadoc attempting to locate your BasicHttpRequest and was unable to find it. Do you have a reference to the javadoc of this class?
I would be under the impression that BasicHttpRequest would be a base class providing operations and attributes common to more than one HttpRequest. It may be extremely generic for extension purposes.
To the first part of your question, use HttpGet, HttpPost etc for their specific operations. If you only need to HTTP/GET information then use HttpGet, if you need to post a form or document body, then use HttpPost. If you are attempting to use things like the Head, Put, Delete method, then use the correspoding HttpXXX class.

How to properly check selectors and extensions via RequestPathInfo

I've been working on a component and currently I'm trying to do different things based on the selector chosen for the component.
So basically if I have a component with this structure
myComponent/
dialog.xml
myComponent.jsp
altView.jsp
I know that if I have a Node with resourceType myComponent I can request the alt view via browser by requesting "path/to/component/content.altView.html" and everything is hunky dory.
Similarly I can do a cq include and do something like:
# with cq include
<cq:include path="my/path.altView" resourceType="myComponent"/>
# or with sling include
<sling:include path="my/path" resourceType="myComponent" replaceSelectors="altView"/>
However, when I'm handling the request, I've seen some interesting behavior when looking at the RequestPathInfo Object.
For example, if we look at all 3 of the above cases I might have something like this:
# http://path/to/component/content.altView.html
slingRequest.getRequestPathInfo().getSelectors(); // {altView}
slingRequest.getRequestPathInfo().getExtension(); // html
# <sling:include path="my/path" resourceType="myComponent" replaceSelectors="altView"/>
slingRequest.getRequestPathInfo().getSelectors(); // {altView}
slingRequest.getRequestPathInfo().getExtension(); // html
# <cq:include path="my/path.altView" resourceType="myComponent"/>
slingRequest.getRequestPathInfo().getSelectors(); // []
slingRequest.getRequestPathInfo().getExtension(); // altView
I understand why the cq:include returns different results (we're making a request to my/path.altView and .altView coincidentally serves as the extension in this case). I'm curious if there is a normalized why to pull "altView" (or the selected view) regardless of if it's been used as an extension or selector. Or if this is normal and I just need to check both the extensions and selectors individually.
i.e
selectors = get selectors();
if selectors
do stuff
else check extensions
do stuff
Again thank you very much for your insights, this community is awesome.
[EDIT]
In response to an answer, I thought I'd give a little more context to what I'm doing. Basically our component structure is set up so that each of our components has an associated Java Class that handles the business logic. (I.E. apps/myapp/components/myComponent will map to com.mypackage.components.MyComponent) That said, within my component's Class I need to handle the control flow differently depending on how the component was called (i.e. what selectors/extensions/etc). For example, if my component was called normally I'd do the base behavior, but if it was called with selector (for exmaple) "altView" I would need to handle the alternative view differently, and in this alternative view different data will be available, etc.
My question was along the basis that it seems that i can give the "path" attribute of a "cq:include" tag the selector I want to use:
<cq:include path="my/path.altView" resourceType="myComponent"/>
However, when I check my RequestPathInfo in my component class to decide workflow, "altView" is returned as the extension, not within the String[] selectors. Note, the above compiles fine, and it selectors the correct .jsp file for rendering, the RequestPathInfo object just stores the data in a different place.
I'm starting to guess that places the selector into the path attribute works because the selectors and extensions modifiers alter the behavior vary similarly. mycomponent.altView.html resolves to altView.jsp whereas if I was to do mycomponent.altView it would also attempt to resolve a mycomponent/altView.jsp just as it would do the same for mycomponent.xml to mycomponent/XML.jsp
It seems like you're kind of working around Sling resolution. The easiest way to do "different things based on selector" in a given component (let's say my/new/component) is to create different renderers.
For example, say I am requesting /content/app/page.html, and on that page was the component my/new/component. Or if I request /content/app/page.selector.html, I want a slightly different experience for my/new/component.
In the cq:component, I would create two JSPs: component.jsp and component.selector.jsp. Sling will automatically know, based on the selector in the request, which renderer to use. Obviously each renderer can produce a different experience.
The same is true for extension. In the example, component.jsp and component.selector.jsp are actually equivalent to component.HTML.jsp and component.selector.HTML.jsp. The HTML is just implied. However, you could do component.XML.jsp and component.selector.XML.jsp and Sling will again, pick the most relevant selector, based on the selector(s) and extension of the request.
Now, what if you don't want the selector to show up in the page request's URL (in my opinion you shouldn't)...
You can include your component using sling:include and add the selector, like you've done.
The caveat is that sling:include works a little differently than cq:include, so only use this when you need to. Instead, you could also use Sling mapping to hide the selector from the user. The majority of the time I would recommend this approach.
I'm not sure what you were trying to do with adding the selector to the "path" attribute. I don't think that would do anything. The "path" is defining the resource name (and the node name if the resource is not synthetic). Including the selector in that wouldn't do anything, except make the resource name include a period and the selector.
My question was along the basis that it seems that i can give the
"path" attribute of a "cq:include" tag the selector I want to use:
<cq:include path="my/path.altView" resourceType="myComponent"/> However, when I check my RequestPathInfo in my component class to
decide workflow, "altView" is returned as the extension, not within
the String[] selectors.
As opposed to the cq:include tag, you could alternatively use sling:include tag, which provides attributes to modify the selectors & suffix on the request:
<sling:include resourceType="myComponent" path="my/path" addSelectors="altView"/>
or
<sling:include resourceType="myComponent" path="my/path" replaceSelectors="altView"/>
If you already have selectors on the request that you don't want to apply to myComponent.
In terms of the differences between Sling include & CQ include, there seems to be very little, apart from the latter also supporting script inclusion. From the docs:
Should you use <cq:include> or <sling:include>?
When developing AEM components, Adobe recommends that you use
<cq:include>.
<cq:include> allows you to directly include script files
by their name when using the script attribute. This takes component
and resource type inheritance into account, and is often simpler than
strict adherence to Sling's script resolution using selectors and
extensions.

JAX-RS and unknown query parameters

I have a Java client that calls a RESTEasy (JAX-RS) Java server. It is possible that some of my users may have a newer version of the client than the server.
That client may call a resource on the server that contains query parameters that the server does not know about. Is it possible to detect this on the server side and return an error?
I understand that if the client calls a URL that has not been implemented yet on the server, the client will get a 404 error, but what happens if the client passes in a query parameter that is not implemented (e.g.: ?sort_by=last_name)?
Is it possible to detect this on the server side and return an error?
Yes, you can do it. I think the easiest way is to use #Context UriInfo. You can obtain all query parameters by calling getQueryParameters() method. So you know if there are any unknown parameters and you can return error.
but what happens if the client passes in a query parameter that is not implemented
If you implement no special support of handling "unknown" parameters, the resource will be called and the parameter will be silently ignored.
Personally I think that it's better to ignore the unknown parameters. If you just ignore them, it may help to make the API backward compatible.
You should definitely check out the JAX-RS filters (org.apache.cxf.jaxrs.ext.RequestHandler) to intercept, validate, manipulate request, e.g. for security or validatng query parameters.
If you declared all your parameters using annotations you can parse the web.xml file for the resource class names (see possible regex below) and use the full qualified class names to access the declared annotations for methods (like javax.ws.rs.GET) and method parameters (like javax.ws.rs.QueryParam) to scan all available web service resources - this way you don't have to manually add all resource classes to your filter.
Store this information in static variables so you just have to parse this stuff the first time you hit your filter.
In your filter you can access the org.apache.cxf.message.Message for the incoming request. The query string is easy to access - if you also want to validate form parameters and multipart names, you have to reas the message content and write it back to the message (this gets a bit nasty since you have to deal with multipart boundaries etc).
To 'index' the resources I just take the HTTP method and append the path (which is then used as key to access the declared parameters.
You can use the ServletContext to read the web.xml file. For extracting the resource classes this regex might be helpful
String webxml = readInputStreamAsString(context.getResourceAsStream("WEB-INF/web.xml"));
Pattern serviceClassesPattern = Pattern.compile("<param-name>jaxrs.serviceClasses</param-name>.*?<param-value>(.*?)</param-value>", Pattern.DOTALL | Pattern.MULTILINE);

GWT - internationalization of entity properties

I'm looking for an elegant solution for the following problem:
In my database, I have some predefined(!) entities. These entities have names and descriptions (Strings). Around the data access layer, there are some EJBs containing business logic to load/search for/etc. those entities.
Now for the frontend, we are developing a GWT application which calls the EJB methods on our backend.
The problem is, that the name and the descriptions of the entities mentioned above must be internationalized - e.g., depending on the user's locale, an entity's description must be "My cool description" (English) or "Beschreibung bla" (German) or whatever :)
My first approach was to use a resource string in the database. So entity A has a description "descriptionA", entity B has a description "descriptionB"... Later on, the GWT app (or any other client) translates this resource string into the actual description using some kind of "resource bundle". E.g.:
*resources_en.properties*:
descriptionA=Actual Description of Entity A
descriptionB=Actual Description of Entity B
*resources_de.properties*:
descriptionA=Beschreibung A
descriptionB=Beschreibung B
(Remember, the entities are predefined, so it's possible to "know" all descriptions at compile time. BUT it would be better if the resource bundle could be enhanced without having to recompile the application).
Is this possible with GWT? How can I do this? Is it better to "translate" on the server or on the client side?
Otherwise, I've to deal with all that i18n stuff on the backend side. Well, this would allow to keep data together (instead of defining the descriptions on the client side). But the big drawback is that the backend must be aware of the caller's locale.
Regards,
Frank
It's mainly a decision between download time/speed vs flexibility. If you compile it GWT inlines the messages and can generate a little faster code, because no string lookup has to be done. However, if you need to make changes and don't want to recompile or want to be a able to let users dynamically alter messages you need dynamic messages.
Regarding the latter case, the Dictionary class can help you with this, see also: http://code.google.com/webtoolkit/doc/latest/DevGuideI18n.html#DevGuideDynamicStringInternationalization
With the Dictionary you generate all messages in the static page served to the user. The users locale can be found in the header Accept-Language, which is send by the browser when a page is requested.
In either case (compiled or dynamic) you might want to serve the locale set by the user in some configuration property and in that case you still need logic for both cases on the server side to serve the locale to the user.
Everything is possible for those who try...
Back to your question: there are several ways to resolve your issue. One would be to introduce some kind of i18n facade and treat your descriptions and names as resource keys. Then you could define convenience methods to access translations i.e. public String translate(String message, Locale locale);. This method could use standard Java ResourceBundle class to access resources at runtime.
The only real problem I see is how to deal with compound messages (i.e. "Blah, blah 4 items" where 4 is a placeholder). Well, what we did in one project in similar situation, we added delimiter and actual resource key then another delimiter and count: "Blah, blah 4 items##items.in.your.whatever##4". In the case of English you could simply trim the first part and for other languages you would need to process whole string.