06-28-2018 10:30 AM
Hi,
We have a policy that moves the document according to the metadata called state id. So if the state id is 123456. It will move the document to 123 -> 456 -> 123456 -> c.pdf
As and when document comes into Alfresco through JAVA CMIS call, we check using NodeService whether the document is exists or not at the destination location. (123 -> 456 -> 123456 ->) . If it exists then we trow DuplicateChildNodeNameException like below.
message = "Duplicate child name not allowed c.pdf";
throw new DuplicateChildNodeNameException(docRef, ContentModel.ASSOC_CONTAINS, docName, new Exception(message));
The problem is even though we set the proper message in the exception, we are not getting the same message on the CMIS side. Instead we get below message...
Exception : 05280006 Failed to execute transaction-level behaviour public abstract void org.alfresco.repo.node.NodeServicePolicies$OnUpdateNodePolicy.onUpdateNode(org.alfresco.service.cmr.repository.NodeRef) in transaction 6f796a47-cdde-4930-b83a-c12fcf9de17d
Without policy code if I upload a document x.pdf into folder A and again I try to reupload a same document when x.pdf to folder A, it gives me proper exception on the CMIS side saying duplicate content or content already exists.
How can I show the same message that Alfresco policy throws to the CMIS client?
Thank you in advance
06-29-2018 03:12 PM
You will only get called 20 times for 20 properties if some code in Alfresco is extremely inefficient and calling NodeService.setProperty for each property instead of calling NodeService.addProperties once for all properties. Unfortunately, it looks like the Alfresco CMIS implementation is that inefficient (I just checked the source).
But still, you should check in the code of your policy if the change is actually interesting for you, and such a check can be implement quite efficiently with two gets on the before/after maps and a single call to EqualsHelper.nullSafeEquals to check for a change/no-change.
Alfresco will always recommend using TRANSACTION_COMMIT because they have to deal with a lot of unqualified 3rd-party / customer developers that do not know how to properly / efficiently implement an EVERY_EVENT policy. I just see too many problems with TRANSACTION_COMMIT in almost every customer project where a non-professional (i.e. someone with little Alfresco development experience) is working on behaviour code, because the people know even less about properly using that frequency than they regarding to EVERY_EVENT.
06-29-2018 04:13 AM
You will never get the proper exception message from a transaction-level policy (bound using NotificationFrequency.TRANSACTION_COMMIT) to any client - CMIS or otherwise. All exceptions from such policies are wrapped and only via a stacktrace (not available to clients) could you get at the real cause.
This is one of the many reasons I typically recommend to NOT use transaction-level policies at all, and none of the policies I write are ever transaction-level. I do use custom transaction listeners combined with regular EVERY_EVENT policies on occasion to aggregate multiple events into a single processing step at the end of a transaction, but at least if a listener throws an exception, it is not wrapped excessively on the way up the call-chain.
06-29-2018 01:46 PM
Axel Faust
If I keep policy for EVERY_EVENT then it will be called multiple times for a single file. I need to keep checking the metadata whether they are updated or not that I want to manipulate. So if I have 20 metadata then the code will run 20 times.. is that a good practice ?
But yes I have tested with EVERY_EVENT and it shows the actual exception thrown by the policy...
Thank you
06-29-2018 03:12 PM
You will only get called 20 times for 20 properties if some code in Alfresco is extremely inefficient and calling NodeService.setProperty for each property instead of calling NodeService.addProperties once for all properties. Unfortunately, it looks like the Alfresco CMIS implementation is that inefficient (I just checked the source).
But still, you should check in the code of your policy if the change is actually interesting for you, and such a check can be implement quite efficiently with two gets on the before/after maps and a single call to EqualsHelper.nullSafeEquals to check for a change/no-change.
Alfresco will always recommend using TRANSACTION_COMMIT because they have to deal with a lot of unqualified 3rd-party / customer developers that do not know how to properly / efficiently implement an EVERY_EVENT policy. I just see too many problems with TRANSACTION_COMMIT in almost every customer project where a non-professional (i.e. someone with little Alfresco development experience) is working on behaviour code, because the people know even less about properly using that frequency than they regarding to EVERY_EVENT.
06-29-2018 04:19 PM
Thanks Axel Faust for your time and information...
As we have lot of properties and CMIS calls I would rather stick to TRANSACTION_COMMIT option. But I understand why I was not able to catch the actual error message from the policy.
07-11-2018 08:20 PM
Interesting approach, and I didn't know that class.
By
I do use custom transaction listeners combined with regular EVERY_EVENT policies on occasion to aggregate multiple events into a single processing step at the end of a transaction
Do you mean something like this? Alfresco – Implementing delete behavior | Programming and So
Do you have any sample code you can share using the approach you described?
Thank you.
07-12-2018 09:32 AM
Hi,
All you need to do is set the NotificationFrequency to EVERY_EVENT in the initialization method of your policy.
public class CustomDocPolicy implements NodeServicePolicies.OnCreateNodePolicy,
NodeServicePolicies.OnUpdateNodePolicy,
NodeServicePolicies.BeforeDeleteNodePolicy {
public void initialise() {
this.policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onCreateNode"),
CustomConstants.TYPE_BASE_DOC, new JavaBehaviour(this, "onCreateNode", Behaviour.NotificationFrequency.EVERY_EVENT));
}
}
Explore our Alfresco products with the links below. Use labels to filter content by product module.