diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/DatabaseConfig.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/DatabaseConfig.java index cd2a1158064fd86ab92cec31ecac693b33a5f822..df10d4ba7b31abba588810b8fe02d1467e28b349 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/DatabaseConfig.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/DatabaseConfig.java @@ -53,22 +53,22 @@ public class DatabaseConfig { @Value("${" + FileProperty.PROPERTY_DB_DRIVER + ":}") - private String driver; + protected String driver; @Value("${" + FileProperty.PROPERTY_DB_USER + ":}") - private String username; + protected String username; @Value("${" + FileProperty.PROPERTY_DB_TOKEN + ":}") - private String password; + protected String password; @Value("${" + FileProperty.PROPERTY_DB_URL + ":}") - private String url; + protected String url; // set default jdbc @Value("${" + FileProperty.PROPERTY_DB_JNDI + ":jdbc/smpDatasource}") - private String jndiDatasourceName; + protected String jndiDatasourceName; @Value("${" + FileProperty.PROPERTY_DB_DIALECT + ":}") - private String hibernateDialect; + protected String hibernateDialect; @Bean(name = "dataSource") diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/ConfigurationDao.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/ConfigurationDao.java index 2ae1290c6ccea56b30885369264855856cd22c5f..10db28feb0915cb50eeca54fad707c7637d8c42a 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/ConfigurationDao.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/ConfigurationDao.java @@ -52,7 +52,6 @@ public class ConfigurationDao extends BaseDao<DBConfiguration> { Map<String, Object> cachedPropertyValues = new HashMap(); OffsetDateTime lastUpdate = null; OffsetDateTime initiateDate = null; - boolean applicationInitialized = false; ApplicationContext applicationContext; boolean serverRestartNeeded = false; @@ -221,8 +220,7 @@ public class ConfigurationDao extends BaseDao<DBConfiguration> { @EventListener({ContextStartedEvent.class}) public void contextRefreshedEvent() { LOG.debug("Application context is initialized: triggered refresh to update all property listeners"); - applicationInitialized = true; - initiateDate = OffsetDateTime.now(); + setInitializedTime(OffsetDateTime.now()); reloadPropertiesFromDatabase(); } @@ -232,15 +230,27 @@ public class ConfigurationDao extends BaseDao<DBConfiguration> { @EventListener({ContextStoppedEvent.class}) protected void contextStopEvent() { LOG.debug("Application context is stopped!"); - applicationInitialized = false; - initiateDate = null; + setInitializedTime(null); + } + + protected void setInitializedTime(OffsetDateTime dateTime) { + initiateDate = dateTime; + } + + + public OffsetDateTime getInitiateDate() { + return initiateDate; + } + + public boolean isApplicationInitialized() { + return initiateDate!=null; } private void updatePropertyListeners() { // wait to get all property listener beans to avoid cyclic initialization // some beans are using ConfigurationService also are in PropertyUpdateListener // for listener to update properties - if (!applicationInitialized) { + if (!isApplicationInitialized()) { LOG.debug("Application is not started. The PropertyUpdateEvent is not triggered"); return; } @@ -262,7 +272,7 @@ public class ConfigurationDao extends BaseDao<DBConfiguration> { return applicationContext.getBeansOfType(PropertyUpdateListener.class); } - private void updateListener(String name, PropertyUpdateListener listener) { + protected void updateListener(String name, PropertyUpdateListener listener) { LOG.debug("updateListener [{}]", name); Map<SMPPropertyEnum, Object> mapProp = new HashMap<>(); for (SMPPropertyEnum prop : listener.handledProperties()) { diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceGroupService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceGroupService.java index 68f7b230cc01a13f5bd2bd4a20ee40ad2784962b..0b02b8eb6b2506631fe948a90956f92992e2f3f5 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceGroupService.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceGroupService.java @@ -46,21 +46,19 @@ import static eu.europa.ec.edelivery.smp.exceptions.ErrorCode.*; public class UIServiceGroupService extends UIServiceBase<DBServiceGroup, ServiceGroupRO> { private static final SMPLogger LOG = SMPLoggerFactory.getLogger(UIServiceGroupService.class); - @Autowired - DomainDao domainDao; - - @Autowired - ServiceGroupDao serviceGroupDao; - - @Autowired - UserDao userDao; - - @Autowired - CaseSensitivityNormalizer caseSensitivityNormalizer; - - @Autowired - SMLIntegrationService smlIntegrationService; - + protected final DomainDao domainDao; + protected final ServiceGroupDao serviceGroupDao; + protected final UserDao userDao; + protected final CaseSensitivityNormalizer caseSensitivityNormalizer; + protected final SMLIntegrationService smlIntegrationService; + + public UIServiceGroupService(DomainDao domainDao, ServiceGroupDao serviceGroupDao, UserDao userDao, CaseSensitivityNormalizer caseSensitivityNormalizer, SMLIntegrationService smlIntegrationService) { + this.domainDao = domainDao; + this.serviceGroupDao = serviceGroupDao; + this.userDao = userDao; + this.caseSensitivityNormalizer = caseSensitivityNormalizer; + this.smlIntegrationService = smlIntegrationService; + } @Override protected BaseDao<DBServiceGroup> getDatabaseDao() { @@ -642,11 +640,12 @@ public class UIServiceGroupService extends UIServiceBase<DBServiceGroup, Service } // if new check if service group already exist if (serviceGroup.getStatusAction() == EntityROStatus.NEW.getStatusNumber()){ - ParticipantIdentifierType headerPI = caseSensitivityNormalizer.normalizeParticipantIdentifier( + + ParticipantIdentifierType normalizedParticipant = caseSensitivityNormalizer.normalizeParticipantIdentifier( serviceGroup.getParticipantScheme(), serviceGroup.getParticipantIdentifier()); - Optional<DBServiceGroup> sg= serviceGroupDao.findServiceGroup(serviceGroup.getParticipantIdentifier(), - serviceGroup.getParticipantScheme()); + Optional<DBServiceGroup> sg= serviceGroupDao.findServiceGroup(normalizedParticipant.getValue(), + normalizedParticipant.getScheme()); if (sg.isPresent()) { serviceGroup.setErrorMessage("Service group: " +serviceGroup.getParticipantScheme()+ ":"+serviceGroup.getParticipantIdentifier()+ " already exists!"); @@ -656,7 +655,7 @@ public class UIServiceGroupService extends UIServiceBase<DBServiceGroup, Service } if (StringUtils.isBlank(serviceGroup.getExtension())) { - // emtpy extension is also a valid extension; + // empty extension is also a valid extension serviceGroup.setErrorMessage(null); } else { try { @@ -664,10 +663,7 @@ public class UIServiceGroupService extends UIServiceBase<DBServiceGroup, Service ExtensionConverter.validateExtensionBySchema(buff); // validate by schema serviceGroup.setErrorMessage(null); serviceGroup.setErrorCode(ERROR_CODE_OK); - } catch (XmlInvalidAgainstSchemaException e) { - serviceGroup.setErrorMessage(ExceptionUtils.getRootCauseMessage(e)); - serviceGroup.setErrorCode(ERROR_CODE_INVALID_EXTENSION); - } catch (UnsupportedEncodingException e) { + } catch (XmlInvalidAgainstSchemaException | UnsupportedEncodingException e) { serviceGroup.setErrorMessage(ExceptionUtils.getRootCauseMessage(e)); serviceGroup.setErrorCode(ERROR_CODE_INVALID_EXTENSION); } @@ -720,8 +716,6 @@ public class UIServiceGroupService extends UIServiceBase<DBServiceGroup, Service transformer.setOutputProperty(OutputKeys.INDENT, "yes"); transformer.transform(xmlInput, xmlOutput); sgExtension.setExtension(xmlOutput.getWriter().toString()); - } catch (TransformerConfigurationException e) { - sgExtension.setErrorMessage(ExceptionUtils.getRootCauseMessage(e)); } catch (TransformerException e) { sgExtension.setErrorMessage(ExceptionUtils.getRootCauseMessage(e)); } diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/config/DatabaseConfigTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/config/DatabaseConfigTest.java new file mode 100644 index 0000000000000000000000000000000000000000..1a642977801ecb68469e12500e117e54c7a21fab --- /dev/null +++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/config/DatabaseConfigTest.java @@ -0,0 +1,55 @@ +package eu.europa.ec.edelivery.smp.config; + +import org.junit.Assert; +import org.junit.Test; +import org.springframework.jdbc.datasource.DriverManagerDataSource; +import org.springframework.orm.jpa.JpaVendorAdapter; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.transaction.PlatformTransactionManager; + +import javax.persistence.EntityManagerFactory; +import javax.sql.DataSource; + +import static org.junit.Assert.*; + +public class DatabaseConfigTest { + + DatabaseConfig testInstance = new DatabaseConfig(){{ + // test properties from persistence-test-h2.properties + jndiDatasourceName =null; + driver = "org.h2.Driver"; + url = "jdbc:h2:file:./target/myDb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=TRUE;AUTO_SERVER=TRUE"; + username = "smp-dev"; + password = "smp-dev"; + }}; + + @Test + public void getDataSource() { + + DataSource result = testInstance.getDataSource(); + + Assert.assertNotNull(result); + Assert.assertEquals(DriverManagerDataSource.class, result.getClass()); + } + @Test + public void jpaVendorAdapter() { + JpaVendorAdapter result = testInstance.jpaVendorAdapter(); + + Assert.assertNotNull(result); + } + + @Test + public void smpEntityManagerFactory() { + LocalContainerEntityManagerFactoryBean result = testInstance.smpEntityManagerFactory(testInstance.getDataSource(), testInstance.jpaVendorAdapter()); + Assert.assertNotNull(result); + } + + @Test + public void smpTransactionManager() { + EntityManagerFactory entityManagerFactory = testInstance.smpEntityManagerFactory(testInstance.getDataSource(), testInstance.jpaVendorAdapter()).getObject(); + PlatformTransactionManager result = testInstance.smpTransactionManager(entityManagerFactory); + Assert.assertNotNull(result); + } + + +} \ No newline at end of file diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/ConfigurationDAOImplTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/ConfigurationDAOImplTest.java index d40dfdd34a748c14d67a85db4facbbd30d1f2101..5ed577a1c4940c4c805a4bd0fecd65adbef2eee7 100644 --- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/ConfigurationDAOImplTest.java +++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/ConfigurationDAOImplTest.java @@ -18,15 +18,20 @@ package eu.europa.ec.edelivery.smp.data.dao; +import eu.europa.ec.edelivery.smp.config.PropertyUpdateListener; import eu.europa.ec.edelivery.smp.data.model.DBConfiguration; import eu.europa.ec.edelivery.smp.data.ui.enums.SMPPropertyEnum; +import eu.europa.ec.edelivery.smp.exceptions.ErrorCode; import eu.europa.ec.edelivery.smp.exceptions.SMPRuntimeException; import eu.europa.ec.edelivery.smp.utils.SecurityUtils; import eu.europa.ec.edelivery.smp.utils.SecurityUtilsTest; +import org.apache.commons.beanutils.BeanUtils; +import org.hamcrest.CoreMatchers; +import org.hamcrest.MatcherAssert; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; +import org.mockito.ArgumentCaptor; +import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.util.ReflectionTestUtils; import org.springframework.transaction.annotation.Transactional; @@ -35,8 +40,8 @@ import java.io.File; import java.io.IOException; import java.nio.file.Paths; import java.time.OffsetDateTime; -import java.util.Optional; -import java.util.UUID; +import java.util.*; +import java.util.stream.Collectors; import static eu.europa.ec.edelivery.smp.data.ui.enums.SMPPropertyEnum.*; import static org.junit.Assert.*; @@ -47,9 +52,6 @@ public class ConfigurationDAOImplTest extends AbstractBaseDao { @Autowired private ConfigurationDao configurationDao; - @Rule - public ExpectedException expectedException = ExpectedException.none(); - @Before public void before() throws IOException { resetKeystore(); @@ -103,6 +105,48 @@ public class ConfigurationDAOImplTest extends AbstractBaseDao { assertTrue(lastUpdate.isBefore(configurationDao.getLastUpdate())); } + @Test + public void testSetPropertyByStringOk() { + // given + OffsetDateTime lastUpdate = configurationDao.getLastUpdate(); + String propertyValue = "localhost"; + + //WHEN + DBConfiguration result = configurationDao.setPropertyToDatabase(SMPPropertyEnum.HTTP_NO_PROXY_HOSTS.getProperty(), propertyValue); + + //THEN + assertNotNull(result); + Optional<DBConfiguration> configuration = configurationDao.getConfigurationEntityFromDatabase(SMPPropertyEnum.HTTP_NO_PROXY_HOSTS); + assertTrue(configuration.isPresent()); + assertEquals(propertyValue, configuration.get().getValue()); + assertTrue(lastUpdate.isBefore(configurationDao.getLastUpdate())); + } + + @Test + public void testSetPropertyByStringNotExists() { + // given + OffsetDateTime lastUpdate = configurationDao.getLastUpdate(); + String propertyValue = "localhost"; + + //WHEN + DBConfiguration result = configurationDao.setPropertyToDatabase("NotExistingProperty", propertyValue); + + //THEN + assertNull(result); + } + + @Test + public void testUpdatePropertyInvalid() { + //WHEN + SMPRuntimeException result = assertThrows(SMPRuntimeException.class, + () -> configurationDao.setPropertyToDatabase(SMPPropertyEnum.HTTP_FORWARDED_HEADERS_ENABLED, + "ThisIsNotValidBoolean", null)); + + //THEN + assertNotNull(result); + assertEquals(ErrorCode.CONFIGURATION_ERROR, result.getErrorCode()); + } + @Test public void testUpdateProperty() { // given @@ -264,12 +308,12 @@ public class ConfigurationDAOImplTest extends AbstractBaseDao { // given File f = new File("no.key"); String password = "TEST11002password1@!." + System.currentTimeMillis(); - // then - expectedException.expect(SMPRuntimeException.class); - expectedException.expectMessage("Error occurred while encrypting the property:"); - // when - configurationDao.encryptString(SMPPropertyEnum.KEYSTORE_PASSWORD, password, f); + SMPRuntimeException result = assertThrows(SMPRuntimeException.class, + () -> configurationDao.encryptString(SMPPropertyEnum.KEYSTORE_PASSWORD, password, f)); + //then + assertNotNull(result); + MatcherAssert.assertThat(result.getMessage(), CoreMatchers.containsString("Error occurred while encrypting the property:")); } @Test @@ -294,12 +338,12 @@ public class ConfigurationDAOImplTest extends AbstractBaseDao { String password = "TEST11002password1@!." + System.currentTimeMillis(); String encPassword = configurationDao.encryptString(SMPPropertyEnum.KEYSTORE_PASSWORD, password, f); - // then - expectedException.expect(SMPRuntimeException.class); - expectedException.expectMessage("Error occurred while decrypting the property:"); // when - configurationDao.decryptString(SMPPropertyEnum.KEYSTORE_PASSWORD, encPassword, fErr); - + SMPRuntimeException result = assertThrows(SMPRuntimeException.class, + () -> configurationDao.decryptString(SMPPropertyEnum.KEYSTORE_PASSWORD, encPassword, fErr)); + //then + assertNotNull(result); + MatcherAssert.assertThat(result.getMessage(), CoreMatchers.containsString("Error occurred while decrypting the property:")); } @Test @@ -332,7 +376,6 @@ public class ConfigurationDAOImplTest extends AbstractBaseDao { assertEquals(password, decPassword); } - @Test public void testRetrieveNonEncryptedPassword() { // given @@ -406,6 +449,57 @@ public class ConfigurationDAOImplTest extends AbstractBaseDao { assertEquals(newTestPassword, configurationDao.decryptString(SMPPropertyEnum.HTTP_PROXY_PASSWORD, dbProxyPassword, encryptionKey)); } + @Test + public void testContextRefreshedEvent() { + + configurationDao.setInitializedTime(null); + assertFalse(configurationDao.isApplicationInitialized()); + + // when + configurationDao.contextRefreshedEvent(); + // then + assertTrue(configurationDao.isApplicationInitialized()); + assertNotNull(configurationDao.getInitiateDate()); + } + + + @Test + public void testContextStopEvent() { + configurationDao.setInitializedTime(OffsetDateTime.now()); + // when + configurationDao.contextStopEvent(); + // then + assertFalse(configurationDao.isApplicationInitialized()); + assertNull(configurationDao.getInitiateDate()); + } + + @Test + public void testGetPendingRestartProperties(){ + // set start "yesterday" - but all properties have update today! + configurationDao.setInitializedTime(OffsetDateTime.now().minusDays(1)); + // when + List<DBConfiguration> restartProp = configurationDao.getPendingRestartProperties(); + // then + assertFalse(restartProp.isEmpty()); + } + + @Test + public void testUpdateListener(){ + + configurationDao.contextRefreshedEvent(); + PropertyUpdateListener listener = Mockito.mock(PropertyUpdateListener.class); + Mockito.doReturn(Arrays.asList(SMP_ALERT_BATCH_SIZE)).when(listener).handledProperties(); + Mockito.doNothing().when(listener).updateProperties(Mockito.anyMap()); + ArgumentCaptor<Map<SMPPropertyEnum, Object>> argCaptor = ArgumentCaptor.forClass(Map.class); + configurationDao.updateListener("testListener",listener); + // when + + + Mockito.verify(listener, Mockito.times(1)).updateProperties(argCaptor.capture()); + assertEquals(1,argCaptor.getValue().size() ); + assertTrue(argCaptor.getValue().containsKey(SMP_ALERT_BATCH_SIZE) ); + } + public void updateOrCreatePropertyToDB(SMPPropertyEnum propertyEnum, String value) { Optional<DBConfiguration> prop = configurationDao.findConfigurationProperty(propertyEnum.getProperty()); DBConfiguration dbProp;