TLDR: How do I identify all the Synthetic resources that are defined in an AEM instance?
Issue:
I have a cq:Page named xyz under /content and a URL mapping defined in Apache Sling JCR Resource Resolver as /content/:/
Accessing the page as http://<server>:<port>/content/xyz.html or http://<server>:<port>/xyz/_jcr_content.html works fine, however accessing the same as http://<server>:<port>/xyz.html gives me 404.
Accessing the same using .json extension gives { } and using .infinity.json gives Resource not adaptable to node: /xyz (500)
Resolving the path through Sling Resource Resolver shows
SyntheticResource, type=sling:syntheticResourceProviderResource, path=/xyz and according to the Sling's Documentation accessing a Synthetic resource would result in a 404.
However the question is,
would a Synthetic resource take precedence before the URL mappings are applied?
If that is the case, then how do i identify where such a resource is defined, and what other such resources are available?
I have already gone through this similar question, however the solution provided isn't complete or rather only discusses the same things as described above.
Related
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.
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
whats the difference between /etc/map/testmap and /etc/map/testmap.internal.
under system/console/jcrresolver at the bottom of the page, it says:
Mapping Map Entries(/etc/map/testmap.internal)
"Lists the entries used by the ResourceResolver.map methods to map Resource Paths to URLs , How is it used and is related with normal map.
These maps do not belong to a vanity AEM instance. In a clean AEM instance you have just one single map placed under /etc/map. The map definitions are used by the resource resolver to map URIs to resources and vice versa.
I would like to instantiate a Sling Model from a JSP using a path to a resource like
<sling:adaptTo adaptable="/path/to/my/resource" adaptTo="org.apache.sling.models.it.models.MyModel" var="model"/>
Within the the Sling Model, I would like to access properties of the specified resource via #ValueMapValue annotations.
My question is, how can I adapt my Sling Model to a resource path String so that I can inject the properties of the specified resource?
The sling:getResource EL Function provided by Sling could be used in conjunction with the sling:adaptTo tag which you are endevoring to use:
<sling:adaptTo adaptable="${sling:getResource(resourceResolver,'/path/to/my/resource')}" adaptTo="org.apache.sling.models.it.models.MyModel" var="model"/>
Full documentation concerning the available tags can be found on the Sling site.
I'm wondering what REST API version defines - resource structure, URI path or both? To me, it seems that specifying version in URI like this can define both:
api.foo.com/v1/path/to/resource
While specifying version as part of mime-type:
Content-type: application/json;application,v1
Clearly defines resource representation.
Some time ago I've read that the URL of a particular resource should not change among versions. After some thinking about it makes deep sense. URL is used to define an unique resource on the internet. If you specify version in URL it makes two different resources when it comes to definition above. Such resources may be a little different (a new field was added e.g.) however they seem to be exactly the same. Since then I use only header versioning.
Its completely up to us, how we want to represent and implement API. To me also it seems that specifying version in URI defines both "Version" as well as "Resource" present in current API version or not.