Skip to content

Commit

Permalink
Be able to reinit the connection to the computation manager with no i…
Browse files Browse the repository at this point in the history
…mpact on other backend connections (#151)

* [IMG-2365] [IMG] When the connexion with the computation manager is lost, reinitiate the
connexion (do not modify other existing connexions with other backends)

* [IMG-2365] [IMG] Perte de connexion avec CALIN
  • Loading branch information
CR36053T authored Jun 10, 2024
1 parent 2d346ce commit 1a5e497
Show file tree
Hide file tree
Showing 3 changed files with 176 additions and 1 deletion.
4 changes: 4 additions & 0 deletions afs-ws/afs-ws-server-utils/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.powsybl.afs.AppFileSystem;
import com.powsybl.afs.ProjectFile;
import com.powsybl.afs.storage.AppStorage;
import com.powsybl.commons.PowsyblException;
import com.powsybl.computation.ComputationManager;
import com.powsybl.computation.DefaultComputationManagerConfig;

Expand All @@ -20,6 +21,9 @@
import jakarta.inject.Singleton;
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Objects;

/**
Expand All @@ -28,13 +32,16 @@
@Named
@Singleton
public class AppDataBean {
private static final Logger LOGGER = LoggerFactory.getLogger(AppDataBean.class);

protected AppData appData;

protected ComputationManager shortTimeExecutionComputationManager;

protected ComputationManager longTimeExecutionComputationManager;

protected DefaultComputationManagerConfig config = DefaultComputationManagerConfig.load();

public AppData getAppData() {
return appData;
}
Expand Down Expand Up @@ -75,7 +82,6 @@ public <T extends ProjectFile, U> U getProjectFile(String fileSystemName, String

@PostConstruct
public void init() {
DefaultComputationManagerConfig config = DefaultComputationManagerConfig.load();
shortTimeExecutionComputationManager = config.createShortTimeExecutionComputationManager();
longTimeExecutionComputationManager = config.createLongTimeExecutionComputationManager();
appData = new AppData(shortTimeExecutionComputationManager, longTimeExecutionComputationManager);
Expand All @@ -91,4 +97,38 @@ public void clean() {
}
}
}

/**
* This method reinit only the computation manager (no effect on other connexions with other backends)
* @param throwException if {@code true}, throw the exception caught, else only log it
*/
public void reinitComputationManager(boolean throwException) {
// If possible, close the existing connections
try {
if (shortTimeExecutionComputationManager != null) {
shortTimeExecutionComputationManager.close();
}
} catch (Exception e) {
if (throwException) {
throw new PowsyblException("Error while closing existing connection to the short-time execution computation manager", e);
} else {
LOGGER.warn("shortTimeExecutionComputationManager is not in a closable state. Had exception '{}' while trying to close it. It will be reinitialized anyway.", e.getMessage());
}
}
try {
if (longTimeExecutionComputationManager != null) {
longTimeExecutionComputationManager.close();
}
} catch (Exception e) {
if (throwException) {
throw new PowsyblException("Error while closing existing connection to the long-time execution computation manager", e);
} else {
LOGGER.warn("longTimeExecutionComputationManager is not in a closable state. Had exception '{}' while trying to close it. It will be reinitialized anyway.", e.getMessage());
}
}

// Open new connections
shortTimeExecutionComputationManager = config.createShortTimeExecutionComputationManager();
longTimeExecutionComputationManager = config.createLongTimeExecutionComputationManager();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package com.powsybl.afs.ws.server.utils;

import com.powsybl.commons.PowsyblException;
import com.powsybl.computation.*;
import org.junit.jupiter.api.*;
import org.mockito.InjectMocks;
import org.mockito.Mock;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.*;
import static org.mockito.MockitoAnnotations.openMocks;

class AppDataBeanTest {

@Mock
private ComputationManager shortTimeExecutionComputationManager;
@Mock
private ComputationManager longTimeExecutionComputationManager;
@Mock
private DefaultComputationManagerConfig config;
@InjectMocks
private AppDataBean appDataBeanUnderTest;

@BeforeEach
void init() {
appDataBeanUnderTest = new AppDataBean();
shortTimeExecutionComputationManager = mock(ComputationManager.class);
longTimeExecutionComputationManager = mock(ComputationManager.class);
config = mock(DefaultComputationManagerConfig.class);
appDataBeanUnderTest.config = config;
openMocks(shortTimeExecutionComputationManager);
openMocks(longTimeExecutionComputationManager);
}

@Test
void reinitComputationManagerNominal() {
// GIVEN
appDataBeanUnderTest.longTimeExecutionComputationManager = longTimeExecutionComputationManager;
appDataBeanUnderTest.shortTimeExecutionComputationManager = shortTimeExecutionComputationManager;
// WHEN
appDataBeanUnderTest.reinitComputationManager(false);
// THEN
verify(longTimeExecutionComputationManager, times(1)).close();
verify(shortTimeExecutionComputationManager, times(1)).close();
try (
com.powsybl.computation.ComputationManager ignored = verify(config, times(1)).createShortTimeExecutionComputationManager();
com.powsybl.computation.ComputationManager ignored1 = verify(config, times(1)).createLongTimeExecutionComputationManager()
) {
verifyNoMoreInteractions(config);
}
}

@Test
void reinitComputationManagerManagerExceptionLogged() {
// GIVEN
appDataBeanUnderTest.longTimeExecutionComputationManager = longTimeExecutionComputationManager;
appDataBeanUnderTest.shortTimeExecutionComputationManager = shortTimeExecutionComputationManager;
doThrow(new Exception("SHORT")).when(shortTimeExecutionComputationManager).close();
doThrow(new Exception("LONG")).when(longTimeExecutionComputationManager).close();
// WHEN
appDataBeanUnderTest.reinitComputationManager(false);
// THEN
verify(longTimeExecutionComputationManager, times(1)).close();
verify(shortTimeExecutionComputationManager, times(1)).close();
try (
com.powsybl.computation.ComputationManager ignored = verify(config, times(1)).createShortTimeExecutionComputationManager();
com.powsybl.computation.ComputationManager ignored1 = verify(config, times(1)).createLongTimeExecutionComputationManager()
) {
verifyNoMoreInteractions(config);
}
}

@Test
void reinitComputationManagerManagerThrowsExceptionShortTime() {
// GIVEN
appDataBeanUnderTest.longTimeExecutionComputationManager = longTimeExecutionComputationManager;
appDataBeanUnderTest.shortTimeExecutionComputationManager = shortTimeExecutionComputationManager;
doThrow(new Exception("SHORT")).when(shortTimeExecutionComputationManager).close();
// WHEN
PowsyblException exception = assertThrows(PowsyblException.class, () -> appDataBeanUnderTest.reinitComputationManager(true));
// THEN
verify(longTimeExecutionComputationManager, times(0)).close();
verify(shortTimeExecutionComputationManager, times(1)).close();
try (
com.powsybl.computation.ComputationManager ignored = verify(config, times(0)).createShortTimeExecutionComputationManager();
com.powsybl.computation.ComputationManager ignored1 = verify(config, times(0)).createLongTimeExecutionComputationManager()
) {
verifyNoMoreInteractions(config);
}
assertEquals("Error while closing existing connection to the short-time execution computation manager", exception.getMessage());
}

@Test
void reinitComputationManagerManagerThrowsExceptionLongTime() {
// GIVEN
appDataBeanUnderTest.longTimeExecutionComputationManager = longTimeExecutionComputationManager;
appDataBeanUnderTest.shortTimeExecutionComputationManager = shortTimeExecutionComputationManager;
doThrow(new Exception("LONG")).when(longTimeExecutionComputationManager).close();
// WHEN
PowsyblException exception = assertThrows(PowsyblException.class, () -> appDataBeanUnderTest.reinitComputationManager(true));
// THEN
verify(longTimeExecutionComputationManager, times(1)).close();
verify(shortTimeExecutionComputationManager, times(1)).close();
try (
com.powsybl.computation.ComputationManager ignored = verify(config, times(0)).createShortTimeExecutionComputationManager();
com.powsybl.computation.ComputationManager ignored1 = verify(config, times(0)).createLongTimeExecutionComputationManager()
) {
verifyNoMoreInteractions(config);
}
assertEquals("Error while closing existing connection to the long-time execution computation manager", exception.getMessage());
}

@Test
void reinitComputationManagerManagerNull() {
// GIVEN
appDataBeanUnderTest.longTimeExecutionComputationManager = null;
appDataBeanUnderTest.shortTimeExecutionComputationManager = null;
// WHEN
appDataBeanUnderTest.reinitComputationManager(false);
// THEN
verify(longTimeExecutionComputationManager, times(0)).close();
verify(shortTimeExecutionComputationManager, times(0)).close();
try (
com.powsybl.computation.ComputationManager ignored = verify(config, times(1)).createShortTimeExecutionComputationManager();
com.powsybl.computation.ComputationManager ignored1 = verify(config, times(1)).createLongTimeExecutionComputationManager()
) {
verifyNoMoreInteractions(config);
}
}
}

0 comments on commit 1a5e497

Please sign in to comment.