Hi!
I see that there is nothing like HistoricCommentCreatedEvent
in history log implementation. I need to notify my custom history backend that task or process instance comment was created (and pass that information together with its content and author).
My only bet currently is to provide custom rest endpoint for adding comments, where my custom backend would be notified.
Do any of you have better idea what could be done to provide this functionality?
Thanks in advance,
Adam
Hi Adam,
Your findings that comments do not go through the HistoryEventHandler
are correct. In order to hook into comment creation, you could subclass org.camunda.bpm.engine.impl.persistence.entity.CommentManager
and override the appropriate methods. Then create a process engine plugin that registers a session factory for your subclass with the process engine. See engine configuration setter #setCustomSessionFactories
, the method ProcessEngineConfigurationImpl#initSessionFactories
and the class org.camunda.bpm.engine.impl.persistence.GenericManagerFactory.GenericManagerFactory
.
Cheers,
Thorben
1 Like
Hello,
I have the same issue here and I tried your solution @thorben but Camunda is still calling the original CommentManager. I saw in the class CommandContext the following method:
public CommentManager getCommentManager() {
return getSession(CommentManager.class);
}
It always return CommentManager class.
Should I create a custom CommandContext class?
Tks.
Hi @denisgmarques ,
you should not need a subclass of CommandContext
. Could you show us how you registered your custom CommentManager
implementation?
To make it hopefully clearer already, these should be your steps:
- Subclass
CommentManager
- Subclass
SessionFactory
to provide your custom CommentManager
. You could rely on the generic implementation as @thorben pointed out called GenericManagerFactory
.
- Write a
ProcessEnginePlugin
that adds your custom SessionFactory
on preInit
. It is important that it is defined before the init process starts.
Then, you should be good to go and getCommentManager
should create your implementation of the CommentManager
.
If you already did these steps, please share relevant snippets and will have a look into it together.
Kind regards
Adagatiya
Hello,
Here it is:
public class CustomCommentManager extends CommentManager {
@Override
public void insert(DbEntity dbEntity) {
super.insert(dbEntity);
log.info("*********************** SEND MAIL **************************");
}
}
public class CommentManagerPlugin extends AbstractProcessEnginePlugin {
@Override
public void preInit(ProcessEngineConfigurationImpl processEngineConfiguration) {
// Custom Comment Manager
List<SessionFactory> customSessionFactories = new ArrayList<>();
customSessionFactories.add(new GenericManagerFactory(CustomCommentManager.class));
processEngineConfiguration.setCustomSessionFactories(customSessionFactories);
}
}
@Configuration
public class ProcessEnginePluginsConfiguration {
@Bean
@Order(Ordering.DEFAULT_ORDER + 1)
public static ProcessEnginePlugin registerCommentManagerPlugin() {
return new CommentManagerPlugin();
}
}
Camunda will register my custom CommentManager here:
public abstract class ProcessEngineConfigurationImpl extends ProcessEngineConfiguration {
...
protected void initSessionFactories() {
...
if (customSessionFactories != null) {
for (SessionFactory sessionFactory : customSessionFactories) {
addSessionFactory(sessionFactory);
}
}
}
...
}
But this does not work because in AddCommentCmd.java Camunda will get CommentManager this way:
public class AddCommentCmd implements Command<Comment>, Serializable {
...
public Comment execute(CommandContext commandContext) {
...
commandContext
.getCommentManager()
.insert(comment);
...
}
}
And CommandContext.java will return the original CommentManager:
public class CommandContext {
...
public CommentManager getCommentManager() {
return getSession(CommentManager.class); // IT WILL NOT RETURN MY CUSTOM CLASS
}
...
}
Denis
Hi @denisgmarques ,
I spotted the problem in your SessionFactory
configuration. By default the GenericManagerFactory
uses the specific subclass of your implementation as session type, but what you want is to overwrite CommentManager
with CustomCommentManager
. In order to achieve this, you could use a factory as follows:
public class CustomManagerFactory<T extends Session> extends GenericManagerFactory {
private final Class<T> sessionType;
public CustomManagerFactory(Class<T> sessionType, Class<? extends T> implementation) {
super(implementation);
this.sessionType = sessionType;
}
@Override
public Class<?> getSessionType() {
return sessionType;
}
}
Sidenote:
It is good practise to not override the exisiting custom session factories:
public class CommentManagerPlugin extends AbstractProcessEnginePlugin {
@Override
public void preInit(ProcessEngineConfigurationImpl processEngineConfiguration) {
// Custom Comment Manager
List<SessionFactory> customSessionFactories = processEngineConfiguration.getCustomSessionFactories();
customSessionFactories.add(new CustomManagerFactory<>(CommentManager.class, CustomCommentManager.class));
processEngineConfiguration.setCustomSessionFactories(customSessionFactories);
}
}
Kind regards
Adagatiya
1 Like