I'm having an issue where the querybuilder will occasionally return incorrect results. I have a requirement to add a label to collections containing assets with a restricted tag. It works most of the time, but occasionally the querybuilder will return collections that don't contain any restricted assets.I have a clientlib that grabs all the collection paths in the viewport and sends it to the servlet that runs the query. Based on my logging, it appears that the error is occuring in the servlet when it receives incorrect results showing a collection has an asset with the restricted tag, but doesn't. There doesn't seem to be any consistency with which collections/assets this happens to. I have tried running the queries through the debugger repeatedly to see if it would return incorrect results, but I haven't been able to reproduce the error there. Any idea why this would happen? I'm running aem 6.5.
@Component(service= Servlet.class,
property={
Constants.SERVICE_DESCRIPTION + "=Check collection restrictions.",
"sling.servlet.methods=" + HttpConstants.METHOD_POST,
"sling.servlet.paths="+"/bin/my/check-restrictions"
})
public class CollectionRestrictionServlet extends SlingAllMethodsServlet {
private transient Logger logger = LoggerFactory.getLogger(CollectionRestrictionServlet.class);
transient Map<String, String> querymap = new HashMap<>();
@Reference
transient QueryBuilder queryBuilder;
@Override
protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response)
throws IOException {
try {
Session session = request.getResourceResolver().adaptTo(Session.class);
RequestParameter[] param = request.getRequestParameters("item");
List<String> collections = new ArrayList<>();
List<String> resCollections = new ArrayList<>();
for(RequestParameter par : param){
collections.add(URLDecoder.decode(par.getString(), "UTF-8"));
}
Writer writer = response.getWriter();
logger.info("Collections checked for asset restrictions: " + collections);
for(String col : collections){
querymap.put("path", "/content");
querymap.put("type", "dam:Asset");
querymap.put("memberOf", col);
querymap.put("property", "jcr:content/metadata/restricted");
querymap.put("property.1_value", "my-asset-info:restricted/do-not-modify");
querymap.put("property.2_value", "my-asset-info:restricted/credit-to-photographer");
querymap.put("property.3_value", "my-asset-info:restricted/credit-to-designer");
querymap.put("property.4_value", "my-asset-info:restricted/digital-use-only");
querymap.put("property.5_value", "my-asset-info:restricted/social-media-use-only");
querymap.put("p.limit", "1");
Query query = queryBuilder.createQuery(PredicateGroup.create(querymap), session);
SearchResult result = query.getResult();
long resNum = result.getTotalMatches();
logger.info("Collection: " + col + " returned " + resNum);
if (resNum > 0){
resCollections.add(col);
}
}
if (resCollections.size() > 0){
String out = resCollections.toString();
logger.info("Collections with restrictions sent to clientlib: " + out);
writer.write(out);
}
else {
writer.write("");
}
}
catch(Exception e){
logger.error("Unable to obtain asset restrictions for collection " + e);
}
}
}
Solved! Go to Solution.
Views
Replies
Total Likes
After some more testing and reading through the documentation I have added in a line
queryBuilder.clearFacetCache();
at the end of each for loop. This has fixed the issue.
What is the below line do ?
querymap.put("memberOf", col);
and you are returning 1 , if you want all the result set p.limit=-1
querymap.put("p.limit", "1");
querymap.put("memberOf", col);
this finds assets that are a member of the collection I am checking.
And as far as the p.limit goes, I only need the one result. If the collection has a single asset with a restriction tag it gets the restricted label.
It looks like you are NOT using a service user, which can be a problem with querying nodes in the JCR, might be a permissions issue. I suggest you exchange
Session session = request.getResourceResolver().adaptTo(Session.class);
with a service user, and then ensure that all the right permissions are assigned to this service user.
Are you always using admin user when performing your actions?
Wouldn't the admin have the permissions required? I tried using a service user, but for some reason i'm getting "session has been closed" errors on some of the queries now. Previously, I wasn't receiving any access control errors or anything.
here's the code I added to try your suggestion:
Map<String, Object> params = new HashMap<String, Object>();
params.put(ResourceResolverFactory.USER, MyConstants.MY_SYSTEM_USER);
resolver = resourceResolverFactory.getServiceResourceResolver(params);
Session session = resolver.adaptTo(Session.class);
If you are looking for single result then use p.limit=1 and order by clause to get consistent result.
I'm not sure how this would affect the error I'm experiencing? The query should be returning 0 results in the instances I am referring to, but instead it is saying that assets are members of collections that they aren't in at all.
After some more testing and reading through the documentation I have added in a line
queryBuilder.clearFacetCache();
at the end of each for loop. This has fixed the issue.
Views
Likes
Replies