Is it possible to write to a table from inside an Event Handler class?

1
0
-1

How do I write to a table from inside an Event Handler class? I need to make an insert from an event handler.

For example:
```
package com.company.event;

import java.util.UUID;

import org.bonitasoft.engine.events.model.SEvent;
import org.bonitasoft.engine.events.model.SHandler;
import org.bonitasoft.engine.events.model.SHandlerExecutionException;
import org.bonitasoft.engine.log.technical.TechnicalLogSeverity;
import org.bonitasoft.engine.log.technical.TechnicalLoggerService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyEventHandler implements SHandler {

private static final Logger LOGGER = LoggerFactory.getLogger(MyEventHandler .class);

private static final long serialVersionUID = 5868248324139776071L;
private final TechnicalLoggerService technicalLoggerService;
private TechnicalLogSeverity technicalLogSeverity;

public MyEventHandler (TechnicalLoggerService technicalLoggerService) {
this.technicalLoggerService = technicalLoggerService;
// set desired logging level
this.technicalLogSeverity = TechnicalLogSeverity.INFO;
LOGGER.info("Starting MyEventHandler ");
}

public void execute(SEvent event) throws SHandlerExecutionException {
if (technicalLoggerService.isLoggable(this.getClass(), technicalLogSeverity)) {
technicalLoggerService.log(this.getClass(), technicalLogSeverity, "MyEventHandler : executing event " + event.getType());
}
LOGGER.info("MyEventHandler : execute " + event.getType());
// Write to db here... (insert into blah blah..)
}

public boolean isInterested(SEvent event) {
if (technicalLoggerService.isLoggable(this.getClass(), technicalLogSeverity)) {
technicalLoggerService.log(this.getClass(), technicalLogSeverity, "MyEventHandler - event "+ event.getType() + " - asks if we are interested in handling this event instance");
}
LOGGER.info("MyEventHandler : isInterested: " + event.getType());
// for this example purpose, assume we are always interested
return true;
}

public String getIdentifier() {
// ensure this handler is registered only once
return UUID.randomUUID().toString();
}
}

2 answers

1
0
-1

How would I go about it? Where do I define such connection? Can I use an ORM to interact with it (Spring Data)?
==> in the execute(SEvent event) , you are inside a Java method : you do what you want.
Only main important information:
* you are inside a Database Transaction opened on the Bonita Database.
* this is a very low layer in the engine. This execution should be done in less than 200 / 100 ms, as fast as possible, because at this moment, due to the Database Transaction, resource are LOCK so you slow down all the complete engine.

So, if you want to use a transaction, use a Datasource (configured then in the bonita.xml), if you want to use some another tool, you are in Java so if you can access them in JAVA, you can.

1
0
-1

Hello Jose,

The answer is rather not.
The engine call this execute() method when it is INSIDE a database transaction. So, in general, you are not allow to open a second internal transaction during this call (except maybe to a different database - depends of the database).
Secondly, keep in mind the engine execute a transaction and wait for the answer : this call should not take more than 100 to 200 ms
Thirdly, you have to manage the error. If you failed during this transaction, then the engine failed it's transaction (and it could be a human execute).

So, saying that, what is the best approach ?

The best is to use an internal memory queue. Then, during the execute(), just register the information you need in a memory queue. In a DIFFERENT thread, read the memory queue and do your database transaction. Doing that, if the transaction take time, you don't care.

Attention, you should have some difference:

  • if the queue is large, the time between the event and the database transaction may be large : event and database are not synchrone

  • if the server shutdown, you may have some event in the memory queue, you will lost (on the another hand, in the first architecture, you may have some information in your database, and finally the Bonita Transaction failed).

Comments

Submitted by jose.diazpalacios on Mon, 04/11/2016 - 23:45

Lets say I want to write to a different database (different from the one bonitauses)

"The engine call this execute() method when it is INSIDE a database transaction. So, in general, you are not allow to open a second internal transaction during this call (except maybe to a different database - depends of the database)."

How would I go about it? Where do I define such connection? Can I use an ORM to interact with it (Spring Data)?

Notifications