* Stores the latest operation in the DB.
*/
private void storeOperationInDataBase() {
- operContext.getDataManager().store(requestId, eventContext.getEvent(),
+ operContext.getDataManager().store(requestId, eventContext.getEvent(), targetEntity,
operationHistory.peekLast().getClOperation());
}
*
* @param requestId request ID
* @param event event with which the operation is associated
+ * @param targetEntity target entity associated with the operation
* @param operation operation to be stored
*/
- void store(String requestId, VirtualControlLoopEvent event, ControlLoopOperation operation);
+ void store(String requestId, VirtualControlLoopEvent event, String targetEntity, ControlLoopOperation operation);
/**
* Starts the background thread.
return;
}
+ logger.info("start operation history thread");
+
thread = makeThread(emFactory, this::run);
thread.setDaemon(true);
thread.start();
@Override
public synchronized void stop() {
+ logger.info("requesting stop of operation history thread");
+
stopped = true;
if (thread == null) {
}
@Override
- public synchronized void store(String requestId, VirtualControlLoopEvent event, ControlLoopOperation operation) {
+ public synchronized void store(String requestId, VirtualControlLoopEvent event, String targetEntity,
+ ControlLoopOperation operation) {
if (stopped) {
logger.warn("operation history thread is stopped, discarding requestId={} event={} operation={}", requestId,
return;
}
- operations.add(new Record(requestId, event, operation));
+ operations.add(new Record(requestId, event, targetEntity, operation));
if (operations.size() > maxQueueLength) {
Record discarded = operations.remove();
* @param firstRecord first record to be stored
*/
private void storeBatch(EntityManager entityManager, Record firstRecord) {
+ logger.info("store operation history record batch");
try (EntityMgrCloser emc = new EntityMgrCloser(entityManager);
EntityTransCloser trans = new EntityTransCloser(entityManager.getTransaction())) {
* @param record record to be stored
*/
private void storeRecord(EntityManager entityMgr, Record record) {
-
Dbao newEntry = new Dbao();
final VirtualControlLoopEvent event = record.getEvent();
final ControlLoopOperation operation = record.getOperation();
+ logger.info("store operation history record for {}", event.getRequestId());
+
newEntry.setClosedLoopName(event.getClosedLoopControlName());
newEntry.setRequestId(record.getRequestId());
newEntry.setActor(operation.getActor());
newEntry.setOperation(operation.getOperation());
- newEntry.setTarget(operation.getTarget());
+ newEntry.setTarget(record.getTargetEntity());
newEntry.setSubrequestId(operation.getSubRequestId());
newEntry.setMessage(operation.getMessage());
newEntry.setOutcome(operation.getOutcome());
private static class Record {
private String requestId;
private VirtualControlLoopEvent event;
+ private String targetEntity;
private ControlLoopOperation operation;
}
public class OperationHistoryDataManagerStub implements OperationHistoryDataManager {
@Override
- public void store(String requestId, VirtualControlLoopEvent event, ControlLoopOperation operation) {
+ public void store(String requestId, VirtualControlLoopEvent event, String targetEntity,
+ ControlLoopOperation operation) {
// do nothing
}
verify(mgrctx).updated(mgr);
// should not have tried to store anything in the DB
- verify(dataMgr, never()).store(any(), any(), any());
+ verify(dataMgr, never()).store(any(), any(), any(), any());
}
@Test
assertTrue(mgr.nextStep());
verify(mgrctx, times(2)).updated(mgr);
- verify(dataMgr, never()).store(any(), any(), any());
+ verify(dataMgr, never()).store(any(), any(), any(), any());
}
/**
}
private void verifyDb(int nrecords, PolicyResult expectedResult, String expectedMsg) {
- ArgumentCaptor<ControlLoopOperation> captor = ArgumentCaptor.forClass(ControlLoopOperation.class);
- verify(dataMgr, times(nrecords)).store(any(), any(), captor.capture());
+ ArgumentCaptor<String> entityCaptor = ArgumentCaptor.forClass(String.class);
+ ArgumentCaptor<ControlLoopOperation> opCaptor = ArgumentCaptor.forClass(ControlLoopOperation.class);
+ verify(dataMgr, times(nrecords)).store(any(), any(), entityCaptor.capture(), opCaptor.capture());
- ControlLoopOperation oper = captor.getValue();
+ assertEquals(MY_TARGET, entityCaptor.getValue());
+
+ ControlLoopOperation oper = opCaptor.getValue();
assertEquals(expectedResult.toString(), oper.getOutcome());
assertEquals(expectedMsg, oper.getMessage());
private static final IllegalStateException EXPECTED_EXCEPTION = new IllegalStateException("expected exception");
private static final String MY_TARGET = "my-target";
+ private static final String MY_ENTITY = "my-entity";
private static final String REQ_ID = "my-request-id";
private static final int BATCH_SIZE = 5;
private static final int MAX_QUEUE_LENGTH = 23;
@Test
public void testStore_testStop() throws InterruptedException {
// store
- mgr.store(REQ_ID, event, operation);
+ mgr.store(REQ_ID, event, MY_ENTITY, operation);
runThread();
mgr.stop();
// store
- mgr.store(REQ_ID, event, operation);
+ mgr.store(REQ_ID, event, MY_ENTITY, operation);
assertEquals(0, mgr.getRecordsAdded());
}
public void testStoreTooManyItems() throws InterruptedException {
final int nextra = 5;
for (int nitems = 0; nitems < MAX_QUEUE_LENGTH + nextra; ++nitems) {
- mgr.store(REQ_ID, event, operation);
+ mgr.store(REQ_ID, event, MY_ENTITY, operation);
}
runThread();
mgr = new RealThread();
mgr.start();
- mgr.store(REQ_ID, event, operation);
- mgr.store(REQ_ID, event, operation);
- mgr.store(REQ_ID, event, operation);
+ mgr.store(REQ_ID, event, MY_ENTITY, operation);
+ mgr.store(REQ_ID, event, MY_ENTITY, operation);
+ mgr.store(REQ_ID, event, MY_ENTITY, operation);
waitForThread();
mgr = new RealThread();
mgr.start();
- mgr.store(REQ_ID, event, operation);
- mgr.store(REQ_ID, event, operation);
- mgr.store(REQ_ID, event, operation);
+ mgr.store(REQ_ID, event, MY_ENTITY, operation);
+ mgr.store(REQ_ID, event, MY_ENTITY, operation);
+ mgr.store(REQ_ID, event, MY_ENTITY, operation);
waitForThread();
// arrange to throw an exception
when(emfSpy.createEntityManager()).thenThrow(EXPECTED_EXCEPTION);
- mgr.store(REQ_ID, event, operation);
+ mgr.store(REQ_ID, event, MY_ENTITY, operation);
runThread();
}
@Test
public void testStoreRecord() throws InterruptedException {
// no start time
- mgr.store(REQ_ID, event, operation);
+ mgr.store(REQ_ID, event, MY_ENTITY, operation);
// no start time
operation = new ControlLoopOperation(operation);
operation.setStart(Instant.now());
- mgr.store(REQ_ID, event, operation);
+ mgr.store(REQ_ID, event, MY_ENTITY, operation);
// both start and end times
operation = new ControlLoopOperation(operation);
operation.setEnd(Instant.now());
- mgr.store(REQ_ID, event, operation);
+ mgr.store(REQ_ID, event, MY_ENTITY, operation);
// only end time
operation = new ControlLoopOperation(operation);
operation.setStart(null);
- mgr.store(REQ_ID, event, operation);
+ mgr.store(REQ_ID, event, MY_ENTITY, operation);
runThread();
public void test() {
OperationHistoryDataManagerStub mgr = new OperationHistoryDataManagerStub();
- assertThatCode(() -> mgr.store(null, null, null)).doesNotThrowAnyException();
+ assertThatCode(() -> mgr.store(null, null, null, null)).doesNotThrowAnyException();
assertThatCode(() -> mgr.stop()).doesNotThrowAnyException();
}
}