cancel
Showing results for 
Search instead for 
Did you mean: 

Create a node and post new file to external service

trmmnt
Champ on-the-rise
Champ on-the-rise

I am developing a custom AIO extension (SDK 3.0.1, Alfresco Community 5.2) that handles Node when it is being created based on Policy Component Bahaviour:

policyComponent.bindClassBehaviour(
NodeServicePolicies.OnCreateNodePolicy.QNAME,
ContentModel.TYPE_CONTENT,
new JavaBehaviour(this, "onCreateNode",
Behaviour.NotificationFrequency.TRANSACTION_COMMIT));

In onCreateMethod created file is posted to external service. Since the processing of this file in external service can take a long time I get a timeout in Share in upload file dialog.

I tried a workaround to run a method that posts new file to external service in a new thread but this clearly does not work due to transaction management and it fails with following exceptions:

"Thread-29" org.alfresco.error.AlfrescoRuntimeException: 11140019 Transaction must be active and synchronization is required: Thread[Thread-29,5,main]

"Thread-30" org.alfresco.service.cmr.repository.InvalidNodeRefException: Node does not exist: workspace://SpacesStore/f9e3d633-33ba-443b-811c-b3781d3f8f22 (status:null)

I don't want to block a User with longer timeout. Is there a way to allow a file to be uploaded and then run posting it to external service in the background/async? Does anybody have a working example or a suggestion what is the most optimal way to perform such tasks?

Thank you in advance,

D.

1 ACCEPTED ANSWER

jpotts
World-Class Innovator
World-Class Innovator

Behaviors should perform as quickly as possible to avoid blocking node creation and the response to the user.

Instead of posting the file to an external service from within the behavior, add a message to a queue, such as Apache Kafka or ActiveMQ. Then have a listener subscribe to that queue. When it sees that a document has been created, grab the document and post it to the external service.

I have an example that does this here:

https://github.com/jpotts/alfresco-kafka

And a sample listener is here:

https://github.com/jpotts/alfresco-kafka-listener-example

And here is a presentation from DevCon that covers it:

https://www.slideshare.net/jpotts/moving-from-actions-behaviors-to-microservices

View answer in original post

4 REPLIES 4

narkuss
Star Contributor
Star Contributor

You could try to externalize the code for sending the http request in an Alfresco action, then call actionService.executeAction, with async param to true, from inside the behaviour. Here you have the action service docs:

https://dev.alfresco.com/resource/docs/java/org/alfresco/service/cmr/action/ActionService.html#execu...

You can also check this action:

https://github.com/keensoft/alfresco-simple-ocr/blob/master/simple-ocr-repo/src/main/java/es/keensof...

Where ThreadPoolExecuter is used to asynchronously execute code. I don't know which is the "best" option, but both should work.

Hope this helps

jpotts
World-Class Innovator
World-Class Innovator

Behaviors should perform as quickly as possible to avoid blocking node creation and the response to the user.

Instead of posting the file to an external service from within the behavior, add a message to a queue, such as Apache Kafka or ActiveMQ. Then have a listener subscribe to that queue. When it sees that a document has been created, grab the document and post it to the external service.

I have an example that does this here:

https://github.com/jpotts/alfresco-kafka

And a sample listener is here:

https://github.com/jpotts/alfresco-kafka-listener-example

And here is a presentation from DevCon that covers it:

https://www.slideshare.net/jpotts/moving-from-actions-behaviors-to-microservices

trmmnt
Champ on-the-rise
Champ on-the-rise

I forgot to mention that external service returns its internal file id that is added to Node as property. Do you still recommend suggested approach in this case?

trmmnt
Champ on-the-rise
Champ on-the-rise

Jeff, thanks for useful information, especially a presentation from the DevCon, which led me to your other example (Alfresco NLP Enricher).

However, due to memory limitations I will probably stick with Redis instead of using Kafka for this particular use case.