FINERACT-1694: Reworked bulk external events

This commit is contained in:
Arnold Galovics
2022-09-04 18:23:55 +02:00
committed by Arnold Gálovics
parent 0980aa8abf
commit 17b36a0919
5 changed files with 208 additions and 185 deletions
@@ -0,0 +1,161 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.infrastructure.event.business.service;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
import org.apache.fineract.infrastructure.core.config.FineractProperties;
import org.apache.fineract.infrastructure.event.business.BusinessEventListener;
import org.apache.fineract.infrastructure.event.business.domain.BulkBusinessEvent;
import org.apache.fineract.infrastructure.event.business.domain.BusinessEvent;
import org.apache.fineract.infrastructure.event.external.service.ExternalEventService;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;
@ExtendWith(MockitoExtension.class)
@SuppressWarnings({ "rawtypes", "unchecked" })
@MockitoSettings(strictness = Strictness.LENIENT)
class BusinessEventNotifierServiceImplTest {
@Mock
private ExternalEventService externalEventService;
@Mock
private FineractProperties fineractProperties;
@InjectMocks
private BusinessEventNotifierServiceImpl underTest;
@Test
public void testNotifyPostBusinessEventShouldNotifyPostListeners() {
// given
configureExternalEventsProperties(false);
MockBusinessEvent event = new MockBusinessEvent();
BusinessEventListener<MockBusinessEvent> postListener = mockListener();
underTest.addPostBusinessEventListener(MockBusinessEvent.class, postListener);
// when
underTest.notifyPostBusinessEvent(event);
// then
verify(postListener).onBusinessEvent(event);
verifyNoInteractions(externalEventService);
}
@Test
public void testNotifyPostBusinessEventShouldNotifyPostListenersAndPostAnExternalEvent() {
// given
configureExternalEventsProperties(true);
MockBusinessEvent event = new MockBusinessEvent();
BusinessEventListener<MockBusinessEvent> postListener = mockListener();
underTest.addPostBusinessEventListener(MockBusinessEvent.class, postListener);
// when
underTest.notifyPostBusinessEvent(event);
// then
verify(postListener).onBusinessEvent(event);
verify(externalEventService).postEvent(event);
}
@Test
public void testNotifyPostBusinessEventShouldNotifyPostListenersAndPostAnBulkExternalEventWhenRecordingEnabled() {
// given
configureExternalEventsProperties(true);
MockBusinessEvent event = new MockBusinessEvent();
BusinessEventListener<MockBusinessEvent> postListener = mockListener();
underTest.addPostBusinessEventListener(MockBusinessEvent.class, postListener);
underTest.startExternalEventRecording();
underTest.notifyPostBusinessEvent(event);
// when
underTest.stopExternalEventRecording();
// then
verify(postListener).onBusinessEvent(event);
ArgumentCaptor<BulkBusinessEvent> argumentCaptor = ArgumentCaptor.forClass(BulkBusinessEvent.class);
verify(externalEventService).postEvent(argumentCaptor.capture());
BulkBusinessEvent capturedEvent = argumentCaptor.getValue();
assertThat(capturedEvent.get()).hasSize(1);
assertThat(capturedEvent.get().get(0)).isEqualTo(event);
}
@Test
public void testNotifyPreBusinessEventShouldNotifyPreListeners() {
// given
configureExternalEventsProperties(false);
MockBusinessEvent event = new MockBusinessEvent();
BusinessEventListener<MockBusinessEvent> preListener = mockListener();
underTest.addPreBusinessEventListener(MockBusinessEvent.class, preListener);
// when
underTest.notifyPreBusinessEvent(event);
// then
verify(preListener).onBusinessEvent(event);
verifyNoInteractions(externalEventService);
}
@Test
public void testNotifyPreBusinessEventShouldNotifyPreListenersWithoutPostingAnExternalEvent() {
// given
configureExternalEventsProperties(true);
MockBusinessEvent event = new MockBusinessEvent();
BusinessEventListener<MockBusinessEvent> preListener = mockListener();
underTest.addPreBusinessEventListener(MockBusinessEvent.class, preListener);
// when
underTest.notifyPreBusinessEvent(event);
// then
verify(preListener).onBusinessEvent(event);
verifyNoInteractions(externalEventService);
}
private void configureExternalEventsProperties(boolean isExternalEventsEnabled) {
FineractProperties.FineractEventsProperties eventsProperties = new FineractProperties.FineractEventsProperties();
FineractProperties.FineractExternalEventsProperties externalProperties = new FineractProperties.FineractExternalEventsProperties();
eventsProperties.setExternal(externalProperties);
externalProperties.setEnabled(isExternalEventsEnabled);
given(fineractProperties.getEvents()).willReturn(eventsProperties);
}
private BusinessEventListener<MockBusinessEvent> mockListener() {
return (BusinessEventListener<MockBusinessEvent>) mock(BusinessEventListener.class);
}
private static class MockBusinessEvent implements BusinessEvent<Object> {
@Override
public Object get() {
return null;
}
@Override
public String getType() {
return null;
}
}
}
@@ -1,116 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.infrastructure.event.external.service;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import java.util.List;
import org.apache.fineract.infrastructure.event.business.domain.BulkBusinessEvent;
import org.apache.fineract.infrastructure.event.business.domain.BusinessEvent;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
@SuppressWarnings({ "rawtypes", "unchecked" })
class DelayedExternalEventServiceTest {
@Mock
private ExternalEventService delegate;
@InjectMocks
private DelayedExternalEventService underTest;
@BeforeEach
public void setUp() {
underTest.clearEnqueuedEvents();
}
@Test
public void testEnqueueEventFailsWhenNullEventIsGiven() {
// given
// when & then
assertThatThrownBy(() -> underTest.enqueueEvent(null)).isExactlyInstanceOf(IllegalArgumentException.class);
}
@Test
public void testEnqueueEventWorks() {
// given
BusinessEvent event = mock(BusinessEvent.class);
// when
underTest.enqueueEvent(event);
// then
List<BusinessEvent<?>> enqueuedEvents = underTest.getEnqueuedEvents();
assertThat(enqueuedEvents).hasSize(1);
assertThat(enqueuedEvents.get(0)).isEqualTo(event);
}
@Test
public void testHasEnqueuedEventsReturnsTrueWhenEventIsEnqueued() {
// given
BusinessEvent event = mock(BusinessEvent.class);
underTest.enqueueEvent(event);
// when
boolean result = underTest.hasEnqueuedEvents();
// then
assertThat(result).isTrue();
}
@Test
public void testHasEnqueuedEventsReturnsFalseWhenNoEventIsEnqueued() {
// given
// when
boolean result = underTest.hasEnqueuedEvents();
// then
assertThat(result).isFalse();
}
@Test
public void testPostEnqueuedEventsFailsWhenNoEventIsEnqueued() {
// given
// when & then
assertThatThrownBy(() -> underTest.postEnqueuedEvents()).isExactlyInstanceOf(IllegalStateException.class);
}
@Test
public void testPostEnqueuedEventsWorks() {
// given
ArgumentCaptor<BusinessEvent> delegateEventCaptor = ArgumentCaptor.forClass(BusinessEvent.class);
BusinessEvent event = mock(BusinessEvent.class);
underTest.enqueueEvent(event);
// when
underTest.postEnqueuedEvents();
// then
verify(delegate).postEvent(delegateEventCaptor.capture());
BusinessEvent delegateEvent = delegateEventCaptor.getValue();
assertThat(delegateEvent).isExactlyInstanceOf(BulkBusinessEvent.class);
BulkBusinessEvent bulkDelegateEvent = (BulkBusinessEvent) delegateEvent;
List<BusinessEvent<?>> enqueuedEvents = bulkDelegateEvent.get();
assertThat(enqueuedEvents).hasSize(1);
assertThat(enqueuedEvents.get(0)).isEqualTo(event);
}
}