diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/factories/DlmsConnectionHelper.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/factories/DlmsConnectionHelper.java index 82433e84820..6c6423bf43a 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/factories/DlmsConnectionHelper.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/factories/DlmsConnectionHelper.java @@ -113,16 +113,30 @@ private void createAndHandleConnectionForDevice( final ConnectionProperties connectionProperties, final MessageMetadata messageMetadata, final Permit permit, - final Consumer taskForConnectionManager) + final Consumer originalTaskForConnectionManager) throws OsgpException { if (connectionProperties.isPingDevice()) { this.devicePingConfig.pinger().ping(device.getIpAddress()); } + final Consumer taskForConnectionManager; if (connectionProperties.isInitializeInvocationCounter()) { this.delay(connectionProperties.getWaitBeforeInitializingInvocationCounter()); - this.invocationCounterManager.initializeInvocationCounter(messageMetadata, device); + + /* + * When the invocation counter is out of sync, the device closes the session. + * By setting the ip-address to null, the application will be forced to get a new ip-address. + * This is done by the DlmsConnectionFactory in the method: + * this.domainHelperService.setIpAddressFromMessageMetadataOrSessionProvider + */ + device.setIpAddress(null); + + taskForConnectionManager = + this.invocationCounterManager.addInitializeInvocationCounterTask( + device, originalTaskForConnectionManager); + } else { + taskForConnectionManager = originalTaskForConnectionManager; } try { @@ -152,7 +166,7 @@ private void createAndHandleConnectionForDevice( newConnectionProperties, messageMetadata, permit, - taskForConnectionManager); + originalTaskForConnectionManager); return; } /* diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/factories/InvocationCounterManager.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/factories/InvocationCounterManager.java index dea9b13c475..5ed12569cbf 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/factories/InvocationCounterManager.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/factories/InvocationCounterManager.java @@ -5,22 +5,16 @@ package org.opensmartgridplatform.adapter.protocol.dlms.domain.factories; import java.util.Objects; +import java.util.function.Consumer; import org.openmuc.jdlms.AttributeAddress; import org.openmuc.jdlms.ObisCode; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.DlmsHelper; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.DlmsDevice; import org.opensmartgridplatform.adapter.protocol.dlms.domain.repositories.DlmsDeviceRepository; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ThrowingConsumer; -import org.opensmartgridplatform.adapter.protocol.dlms.infra.messaging.DlmsLogItemRequestMessageSender; -import org.opensmartgridplatform.adapter.protocol.dlms.infra.messaging.DlmsMessageListener; -import org.opensmartgridplatform.adapter.protocol.dlms.infra.messaging.InvocationCountingDlmsMessageListener; -import org.opensmartgridplatform.adapter.protocol.dlms.infra.messaging.LoggingDlmsMessageListener; import org.opensmartgridplatform.shared.exceptionhandling.ComponentType; import org.opensmartgridplatform.shared.exceptionhandling.FunctionalException; import org.opensmartgridplatform.shared.exceptionhandling.FunctionalExceptionType; -import org.opensmartgridplatform.shared.exceptionhandling.OsgpException; -import org.opensmartgridplatform.shared.infra.jms.MessageMetadata; -import org.opensmartgridplatform.throttling.api.Permit; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -36,59 +30,35 @@ public class InvocationCounterManager { private static final AttributeAddress ATTRIBUTE_ADDRESS_INVOCATION_COUNTER_VALUE = new AttributeAddress(1, new ObisCode(new byte[] {0, 0, 43, 1, 0, -1}), 2); - private final DlmsConnectionFactory connectionFactory; private final DlmsHelper dlmsHelper; private final DlmsDeviceRepository deviceRepository; - private final DlmsLogItemRequestMessageSender dlmsLogItemRequestMessageSender; @Autowired public InvocationCounterManager( - final DlmsConnectionFactory connectionFactory, - final DlmsHelper dlmsHelper, - final DlmsDeviceRepository deviceRepository, - final DlmsLogItemRequestMessageSender dlmsLogItemRequestMessageSender) { - this.connectionFactory = connectionFactory; + final DlmsHelper dlmsHelper, final DlmsDeviceRepository deviceRepository) { this.dlmsHelper = dlmsHelper; this.deviceRepository = deviceRepository; - this.dlmsLogItemRequestMessageSender = dlmsLogItemRequestMessageSender; } /** * Updates the device instance with the invocation counter value on the actual device. Should only * be called for a device that actually has an invocation counter stored on the device itself. */ - public void initializeInvocationCounter( - final MessageMetadata messageMetadata, final DlmsDevice device) throws OsgpException { - - /* - * When the invocation counter is out of sync, the device closes the session. - * By setting the ip-address to null, the application will be forced to get a new ip-address. - * This is done by the DlmsConnectionFactory in the method: - * this.domainHelperService.setIpAddressFromMessageMetadataOrSessionProvider - */ - device.setIpAddress(null); - - this.initializeWithInvocationCounterStoredOnDevice(messageMetadata, device, null); + public Consumer addInitializeInvocationCounterTask( + final DlmsDevice device, + final Consumer originalTaskForConnectionManager) { + final Consumer initializeTask = + (ThrowingConsumer) + connectionManager -> + this.initializeWithInvocationCounterStoredOnDeviceTask(device, connectionManager); + return initializeTask.andThen(originalTaskForConnectionManager); } - /** - * Updates the device instance with the invocation counter value on the actual device. Should only - * be called for a device that actually has an invocation counter stored on the device itself. If - * a permit for network access is passed, it is to be released upon closing the connection. - */ - private void initializeWithInvocationCounterStoredOnDevice( - final MessageMetadata messageMetadata, final DlmsDevice device, final Permit permit) - throws OsgpException { - - final ThrowingConsumer taskForConnectionManager = + public Consumer createInitializeInvocationCounterTask( + final DlmsDevice device) { + return (ThrowingConsumer) connectionManager -> this.initializeWithInvocationCounterStoredOnDeviceTask(device, connectionManager); - - final DlmsMessageListener dlmsMessageListener = - this.createMessageListenerForDeviceConnection(device, messageMetadata); - - this.connectionFactory.createAndHandlePublicClientConnection( - messageMetadata, device, dlmsMessageListener, permit, taskForConnectionManager); } void initializeWithInvocationCounterStoredOnDeviceTask( @@ -136,19 +106,4 @@ private long getInvocationCounter(final DlmsConnectionManager connectionManager) .getValue(); return invocationCounter.longValue(); } - - protected DlmsMessageListener createMessageListenerForDeviceConnection( - final DlmsDevice device, final MessageMetadata messageMetadata) { - final InvocationCountingDlmsMessageListener dlmsMessageListener; - if (device.isInDebugMode()) { - dlmsMessageListener = - new LoggingDlmsMessageListener( - device.getDeviceIdentification(), this.dlmsLogItemRequestMessageSender); - dlmsMessageListener.setMessageMetadata(messageMetadata); - dlmsMessageListener.setDescription("Create connection"); - } else { - dlmsMessageListener = null; - } - return dlmsMessageListener; - } } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/factories/DlmsConnectionHelperTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/factories/DlmsConnectionHelperTest.java index 4dbac73214b..835cb826e3e 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/factories/DlmsConnectionHelperTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/factories/DlmsConnectionHelperTest.java @@ -24,6 +24,7 @@ import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.DlmsDevice; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.DlmsDeviceBuilder; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ConnectionException; +import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ThrowingConsumer; import org.opensmartgridplatform.adapter.protocol.dlms.infra.messaging.DlmsMessageListener; import org.opensmartgridplatform.adapter.protocol.dlms.infra.messaging.InvocationCountingDlmsMessageListener; import org.opensmartgridplatform.shared.infra.jms.MessageMetadata; @@ -135,14 +136,16 @@ void noInteractionsWithInvocationCounterManagerForDeviceThatDoesNotNeedInvocatio .build(); final DlmsMessageListener listener = new InvocationCountingDlmsMessageListener(); + final Consumer initTask = this.createInitTask(); + when(this.invocationCounterManager.addInitializeInvocationCounterTask(device, this.task)) + .thenReturn(initTask); + doNothing() .when(this.connectionFactory) - .createAndHandleConnection(this.messageMetadata, device, listener, null, this.task); + .createAndHandleConnection(this.messageMetadata, device, listener, null, initTask); this.helper.createAndHandleConnectionForDevice( this.messageMetadata, device, listener, this.task); - - verify(this.invocationCounterManager).initializeInvocationCounter(this.messageMetadata, device); } @Test @@ -173,6 +176,10 @@ void initializesInvocationCounterWhenInvocationCounterIsOutOfSyncForIskraDevice( .build(); final DlmsMessageListener listener = new InvocationCountingDlmsMessageListener(); + final Consumer initTask = this.createInitTask(); + when(this.invocationCounterManager.addInitializeInvocationCounterTask(device, this.task)) + .thenReturn(initTask); + final ConnectionException exception = new ConnectionException( "Error creating connection for device E0033006878667817 with Ip address:62.133.86.119 Port:4059 " @@ -181,6 +188,9 @@ void initializesInvocationCounterWhenInvocationCounterIsOutOfSyncForIskraDevice( doThrow(exception) .when(this.connectionFactory) .createAndHandleConnection(this.messageMetadata, device, listener, null, this.task); + doThrow(exception) + .when(this.connectionFactory) + .createAndHandleConnection(this.messageMetadata, device, listener, null, initTask); assertThrows( ConnectionException.class, @@ -188,9 +198,10 @@ void initializesInvocationCounterWhenInvocationCounterIsOutOfSyncForIskraDevice( this.helper.createAndHandleConnectionForDevice( this.messageMetadata, device, listener, null, this.task)); - verify(this.invocationCounterManager).initializeInvocationCounter(this.messageMetadata, device); - verify(this.connectionFactory, times(2)) + verify(this.connectionFactory, times(1)) .createAndHandleConnection(this.messageMetadata, device, listener, null, this.task); + verify(this.connectionFactory, times(1)) + .createAndHandleConnection(this.messageMetadata, device, listener, null, initTask); } @Test @@ -204,6 +215,10 @@ void initializesInvocationCounterWhenInvocationCounterIsOutOfSyncForLAndGDevice( .build(); final DlmsMessageListener listener = new InvocationCountingDlmsMessageListener(); + final Consumer initTask = this.createInitTask(); + when(this.invocationCounterManager.addInitializeInvocationCounterTask(device, this.task)) + .thenReturn(initTask); + final ConnectionException exception = new ConnectionException( "Error creating connection for device E0051004228715518 with Ip address:62.133.88.34 Port:null " @@ -211,6 +226,9 @@ void initializesInvocationCounterWhenInvocationCounterIsOutOfSyncForLAndGDevice( doThrow(exception) .when(this.connectionFactory) .createAndHandleConnection(this.messageMetadata, device, listener, null, this.task); + doThrow(exception) + .when(this.connectionFactory) + .createAndHandleConnection(this.messageMetadata, device, listener, null, initTask); assertThrows( ConnectionException.class, @@ -218,9 +236,10 @@ void initializesInvocationCounterWhenInvocationCounterIsOutOfSyncForLAndGDevice( this.helper.createAndHandleConnectionForDevice( this.messageMetadata, device, listener, null, this.task)); - verify(this.invocationCounterManager).initializeInvocationCounter(this.messageMetadata, device); - verify(this.connectionFactory, times(2)) + verify(this.connectionFactory, times(1)) .createAndHandleConnection(this.messageMetadata, device, listener, null, this.task); + verify(this.connectionFactory, times(1)) + .createAndHandleConnection(this.messageMetadata, device, listener, null, initTask); } @Test @@ -233,6 +252,10 @@ void invocationCounterUpdateSuccesfull() throws Exception { .build(); final DlmsMessageListener listener = new InvocationCountingDlmsMessageListener(); + final Consumer initTask = this.createInitTask(); + when(this.invocationCounterManager.addInitializeInvocationCounterTask(device, this.task)) + .thenReturn(initTask); + final ConnectionException exception = new ConnectionException( "Error creating connection for device E0051004228715518 with Ip address:62.133.88.34 Port:null " @@ -240,16 +263,19 @@ void invocationCounterUpdateSuccesfull() throws Exception { // First try throw exception, second time no exception doThrow(exception) - .doNothing() .when(this.connectionFactory) .createAndHandleConnection(this.messageMetadata, device, listener, null, this.task); + doNothing() + .when(this.connectionFactory) + .createAndHandleConnection(this.messageMetadata, device, listener, null, initTask); this.helper.createAndHandleConnectionForDevice( this.messageMetadata, device, listener, null, this.task); - verify(this.invocationCounterManager).initializeInvocationCounter(this.messageMetadata, device); - verify(this.connectionFactory, times(2)) + verify(this.connectionFactory, times(1)) .createAndHandleConnection(this.messageMetadata, device, listener, null, this.task); + verify(this.connectionFactory, times(1)) + .createAndHandleConnection(this.messageMetadata, device, listener, null, initTask); } @Test @@ -280,4 +306,8 @@ void invocationCounterUpdateSuccesfull() throws Exception { verifyNoMoreInteractions(this.invocationCounterManager); } + + private Consumer createInitTask() { + return (ThrowingConsumer) connectionManager -> {}; + } } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/factories/InvocationCounterManagerTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/factories/InvocationCounterManagerTest.java index 2a2b12c8ac9..6f16018f2d7 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/factories/InvocationCounterManagerTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/factories/InvocationCounterManagerTest.java @@ -6,13 +6,9 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.catchThrowableOfType; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.isNotNull; -import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.ArgumentMatchers.refEq; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -21,6 +17,7 @@ import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.core.read.ListAppender; import java.util.List; +import java.util.function.Consumer; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -33,11 +30,9 @@ import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.DlmsDevice; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.DlmsDeviceBuilder; import org.opensmartgridplatform.adapter.protocol.dlms.domain.repositories.DlmsDeviceRepository; -import org.opensmartgridplatform.adapter.protocol.dlms.infra.messaging.DlmsLogItemRequestMessageSender; import org.opensmartgridplatform.shared.exceptionhandling.FunctionalException; import org.opensmartgridplatform.shared.exceptionhandling.FunctionalExceptionType; import org.opensmartgridplatform.shared.exceptionhandling.OsgpException; -import org.opensmartgridplatform.shared.infra.jms.MessageMetadata; import org.slf4j.LoggerFactory; @ExtendWith(MockitoExtension.class) @@ -47,26 +42,16 @@ class InvocationCounterManagerTest { private static final String IP_ADDRESS = "1.2.3.4"; private InvocationCounterManager manager; - private MessageMetadata messageMetadata; private DlmsDevice device; private final long invocationCounterValueInDatabaseEntity = 7; private final long initialDeviceVersion = 2; - @Mock private DlmsConnectionFactory connectionFactory; - @Mock private DlmsHelper dlmsHelper; @Mock private DlmsDeviceRepository deviceRepository; - private DlmsLogItemRequestMessageSender dlmsLogItemRequestMessageSender; @BeforeEach void setUp() { - this.manager = - new InvocationCounterManager( - this.connectionFactory, - this.dlmsHelper, - this.deviceRepository, - this.dlmsLogItemRequestMessageSender); - this.messageMetadata = MessageMetadata.newBuilder().withCorrelationUid("123456").build(); + this.manager = new InvocationCounterManager(this.dlmsHelper, this.deviceRepository); this.device = new DlmsDeviceBuilder() .withInvocationCounter(this.invocationCounterValueInDatabaseEntity) @@ -78,25 +63,10 @@ void setUp() { void initializeInvocationCounterForDeviceTaskExecuted() throws OsgpException { this.device.setIpAddress(IP_ADDRESS); - this.manager.initializeInvocationCounter(this.messageMetadata, this.device); - - assertThat(this.device.getIpAddress()).isNull(); - verify(this.connectionFactory, times(1)) - .createAndHandlePublicClientConnection( - any(MessageMetadata.class), eq(this.device), isNull(), isNull(), any()); - } - - @Test - void initializeInvocationCounterForDeviceTaskExecutedDebugEnabled() throws OsgpException { - this.device.setInDebugMode(true); - this.device.setIpAddress(IP_ADDRESS); - - this.manager.initializeInvocationCounter(this.messageMetadata, this.device); + final Consumer task = + this.manager.createInitializeInvocationCounterTask(this.device); - assertThat(this.device.getIpAddress()).isNull(); - verify(this.connectionFactory, times(1)) - .createAndHandlePublicClientConnection( - any(MessageMetadata.class), eq(this.device), isNotNull(), isNull(), any()); + assertThat(task).isNotNull(); } @Test diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/MessagingTestConfiguration.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/MessagingTestConfiguration.java index 3a241249b94..70a25c3d089 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/MessagingTestConfiguration.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/MessagingTestConfiguration.java @@ -4,13 +4,11 @@ package org.opensmartgridplatform.adapter.protocol.dlms.infra.messaging; -import java.time.Duration; import java.util.Arrays; import java.util.List; import javax.jms.Destination; import org.apache.activemq.command.ActiveMQDestination; import org.mockito.Mockito; -import org.opensmartgridplatform.adapter.protocol.dlms.application.config.DevicePingConfig; import org.opensmartgridplatform.adapter.protocol.dlms.application.config.ThrottlingClientConfig; import org.opensmartgridplatform.adapter.protocol.dlms.application.config.messaging.OutboundLogItemRequestsMessagingConfig; import org.opensmartgridplatform.adapter.protocol.dlms.application.config.messaging.OutboundOsgpCoreResponsesMessagingConfig; @@ -21,7 +19,6 @@ import org.opensmartgridplatform.adapter.protocol.dlms.application.services.ThrottlingService; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.DlmsHelper; import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.DlmsConnectionFactory; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.DlmsConnectionHelper; import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.InvocationCounterManager; import org.opensmartgridplatform.adapter.protocol.dlms.domain.repositories.DlmsDeviceRepository; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.OsgpExceptionConverter; @@ -35,7 +32,6 @@ import org.opensmartgridplatform.shared.infra.jms.BaseMessageProcessorMap; import org.opensmartgridplatform.shared.infra.jms.JmsMessageCreator; import org.opensmartgridplatform.shared.infra.jms.MessageProcessorMap; -import org.opensmartgridplatform.shared.infra.networking.ping.Pinger; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @@ -149,42 +145,8 @@ public DlmsConnectionFactory dlmsConnectionFactory() { @Bean public InvocationCounterManager invocationCounterManager( - final DlmsDeviceRepository deviceRepository, - final DlmsLogItemRequestMessageSender dlmsLogItemRequestMessageSender) { - return new InvocationCounterManager( - this.dlmsConnectionFactory(), - this.dlmsHelper(), - deviceRepository, - dlmsLogItemRequestMessageSender); - } - - @Bean - public DlmsConnectionHelper dlmsConnectionHelper( - final DlmsDeviceRepository deviceRepository, - final DlmsLogItemRequestMessageSender dlmsLogItemRequestMessageSender) { - final DevicePingConfig devicePingConfig = - new DevicePingConfig() { - @Override - public boolean pingingEnabled() { - return false; - } - - @Override - public Pinger pinger() { - return new Pinger(1, 0, Duration.ofSeconds(1), false); - } - }; - return new DlmsConnectionHelper( - this.invocationCounterManager(deviceRepository, dlmsLogItemRequestMessageSender), - this.dlmsConnectionFactory(), - devicePingConfig, - 0, - this.domainHelperService()); - } - - @Bean - public DlmsLogItemRequestMessageSender dlmsLogItemRequestMessageSender() { - return new DlmsLogItemRequestMessageSender(); + final DlmsDeviceRepository deviceRepository) { + return new InvocationCounterManager(this.dlmsHelper(), deviceRepository); } @Bean