You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
341 lines
13 KiB
341 lines
13 KiB
package de.superx; |
|
|
|
import java.io.File; |
|
import java.io.IOException; |
|
import java.nio.file.FileSystems; |
|
import java.nio.file.Files; |
|
import java.nio.file.Path; |
|
import java.sql.Connection; |
|
import java.sql.DatabaseMetaData; |
|
import java.sql.JDBCType; |
|
import java.sql.ResultSet; |
|
import java.sql.SQLException; |
|
import java.util.Arrays; |
|
import java.util.HashMap; |
|
import java.util.List; |
|
import java.util.Map; |
|
|
|
import javax.sql.DataSource; |
|
|
|
import org.apache.commons.io.FileUtils; |
|
import org.apache.log4j.Logger; |
|
import org.junit.Ignore; |
|
import org.pentaho.di.core.KettleEnvironment; |
|
import org.pentaho.di.core.logging.KettleLogStore; |
|
import org.postgresql.ds.common.PGObjectFactory; |
|
import org.postgresql.util.PGobject; |
|
import org.springframework.beans.factory.DisposableBean; |
|
import org.springframework.beans.factory.InitializingBean; |
|
import org.springframework.context.annotation.Bean; |
|
import org.springframework.context.annotation.ComponentScan; |
|
import org.springframework.context.annotation.Configuration; |
|
import org.springframework.context.annotation.Import; |
|
import org.springframework.context.annotation.Primary; |
|
import org.springframework.core.convert.converter.Converter; |
|
import org.springframework.core.io.ClassPathResource; |
|
import org.springframework.data.convert.ReadingConverter; |
|
import org.springframework.data.convert.WritingConverter; |
|
import org.springframework.data.jdbc.core.convert.JdbcCustomConversions; |
|
import org.springframework.data.jdbc.repository.config.AbstractJdbcConfiguration; |
|
import org.springframework.data.jdbc.repository.config.EnableJdbcRepositories; |
|
import org.springframework.data.relational.core.dialect.Dialect; |
|
import org.springframework.data.relational.core.dialect.PostgresDialect; |
|
import org.springframework.http.MediaType; |
|
import org.springframework.http.converter.HttpMessageConverter; |
|
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; |
|
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; |
|
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; |
|
import org.springframework.jdbc.datasource.DataSourceTransactionManager; |
|
import org.springframework.jdbc.datasource.init.ScriptUtils; |
|
import org.springframework.test.context.web.WebAppConfiguration; |
|
import org.springframework.transaction.PlatformTransactionManager; |
|
import org.springframework.web.servlet.config.annotation.EnableWebMvc; |
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; |
|
|
|
import com.fasterxml.jackson.core.JsonProcessingException; |
|
import com.fasterxml.jackson.databind.JsonNode; |
|
import com.fasterxml.jackson.databind.ObjectMapper; |
|
import com.fasterxml.jackson.databind.node.ArrayNode; |
|
import com.zaxxer.hikari.HikariDataSource; |
|
|
|
import de.superx.bianalysis.metadata.Identifier; |
|
import de.superx.servlet.LogInit; |
|
import de.superx.servlet.SuperXManager; |
|
import de.superx.servlet.SxPools; |
|
import de.superx.spring.TestUserServiceImpl; |
|
import de.superx.spring.batch.His1DataSources; |
|
import de.superx.spring.service.UserService; |
|
import de.superx.util.PathAndFileUtils; |
|
|
|
@Ignore |
|
@Configuration |
|
@EnableJdbcRepositories(basePackages = {"de.superx.jdbc.repository","de.superx.bianalysis.repository"} ) |
|
@ComponentScan(basePackages = "de.superx.spring.service,de.superx.rest,de.superx.bianalysis.service,de.superx.bianalysis.rest") |
|
@Import(TestAppConfig.class) |
|
public class TestApplicationConfigH2 extends AbstractJdbcConfiguration implements InitializingBean, DisposableBean{ |
|
|
|
protected static Logger logger; |
|
|
|
public static final String TEST_MANDANTEN_ID = "test"; |
|
private static String dbPath = String.join(File.separator, "test", "resources", "db") + File.separator; |
|
private static String DB_SUFFIX = ".mv.db"; |
|
private static String DB_TRACE_SUFFIX = ".trace.db"; |
|
private static String DB_TEMPLATE = "head_eduetl"; |
|
private long startThreadId; |
|
|
|
|
|
|
|
@Bean |
|
public UserService userService() { |
|
return new TestUserServiceImpl(); |
|
} |
|
|
|
|
|
@Bean |
|
DataSource dataSource() throws Exception { |
|
HikariDataSource ds = new HikariDataSource(); |
|
ds.setJdbcUrl("jdbc:h2:./test/resources/db/" + getDbName() + ";MODE=POSTGRESQL;DATABASE_TO_LOWER=TRUE;NON_KEYWORDS=KEY,VALUE,YEAR;BUILTIN_ALIAS_OVERRIDE=TRUE"); |
|
ds.setUsername("sa"); |
|
ds.setPassword(""); |
|
if (!batchSchemaExists(ds)) { |
|
createBatchSchema(ds); |
|
} |
|
return ds; |
|
} |
|
|
|
@Bean |
|
His1DataSources dataSources() throws Exception { |
|
Map<String, DataSource> dataSources = new HashMap<>(); |
|
dataSources.put("eduetl", dataSource()); |
|
His1DataSources h1d = new His1DataSources(dataSources); |
|
return h1d; |
|
} |
|
|
|
@Bean |
|
NamedParameterJdbcOperations operations() throws Exception { |
|
return new NamedParameterJdbcTemplate(dataSource()); |
|
} |
|
|
|
@Bean |
|
PlatformTransactionManager transactionManager() throws Exception { |
|
return new DataSourceTransactionManager(dataSource()); |
|
} |
|
|
|
@Override |
|
@Bean |
|
public Dialect jdbcDialect(NamedParameterJdbcOperations operations) { |
|
return PostgresDialect.INSTANCE; |
|
} |
|
|
|
@Override |
|
public JdbcCustomConversions jdbcCustomConversions() { |
|
return new JdbcCustomConversions(Arrays.asList(IntegerToBooleanConverter.INSTANCE, |
|
BooleanToIntegerConverter.INSTANCE, |
|
ShortToBooleanConverter.INSTANCE, |
|
BooleanToShortConverter.INSTANCE, |
|
IdentifierToString.INSTANCE, |
|
StringToIdentifier.INSTANCE, |
|
ArrayNodeToPGobjectConverter.INSTANCE, |
|
PGobjectToArrayNodeConverter.INSTANCE |
|
)); |
|
} |
|
|
|
@ReadingConverter |
|
enum IntegerToBooleanConverter implements Converter<Integer, Boolean> { |
|
INSTANCE; |
|
@Override |
|
public Boolean convert(Integer source) { |
|
if (source.equals(Integer.valueOf(1))) { |
|
return Boolean.TRUE; |
|
} |
|
return Boolean.FALSE; |
|
} |
|
} |
|
|
|
@WritingConverter |
|
public enum BooleanToIntegerConverter implements Converter<Boolean, Integer> { |
|
INSTANCE; |
|
|
|
@Override |
|
public Integer convert(Boolean source) { |
|
Integer value =source != null && source.booleanValue() ? Integer.valueOf(1) : Integer.valueOf(0); |
|
return value; |
|
} |
|
} |
|
|
|
@ReadingConverter |
|
enum ShortToBooleanConverter implements Converter<Short, Boolean> { |
|
INSTANCE; |
|
@Override |
|
public Boolean convert(Short source) { |
|
if (source.equals(Short.valueOf("1"))) { |
|
return Boolean.TRUE; |
|
} |
|
return Boolean.FALSE; |
|
} |
|
} |
|
|
|
@WritingConverter |
|
public enum BooleanToShortConverter implements Converter<Boolean, Short> { |
|
INSTANCE; |
|
|
|
@Override |
|
public Short convert(Boolean source) { |
|
return (source != null && source.booleanValue()) ? Short.valueOf((short)1) : Short.valueOf((short)0); |
|
} |
|
} |
|
|
|
@WritingConverter |
|
enum IdentifierToString implements Converter<Identifier, String> { |
|
INSTANCE; |
|
@Override |
|
public String convert(Identifier id) { |
|
return id.composedId; |
|
} |
|
} |
|
|
|
@ReadingConverter |
|
enum StringToIdentifier implements Converter<String, Identifier> { |
|
INSTANCE; |
|
@Override |
|
public Identifier convert(String source) { |
|
return new Identifier(source); |
|
} |
|
} |
|
|
|
protected static boolean batchSchemaExists(DataSource dataSource) { |
|
boolean exists = false; |
|
try(Connection con = dataSource.getConnection()) { |
|
DatabaseMetaData meta = con.getMetaData(); |
|
ResultSet resultSet = meta.getTables(null, null, "batch_job_execution" , new String[] {"TABLE"}); |
|
exists = resultSet.next(); |
|
} catch (SQLException e) { |
|
throw new RuntimeException("Couldn't check for table batch_job_execution", e); |
|
} |
|
return exists; |
|
} |
|
|
|
protected static void createBatchSchema(DataSource dataSource) { |
|
try (Connection con = dataSource.getConnection()){ |
|
ScriptUtils.executeSqlScript(con, new ClassPathResource("/org/springframework/batch/core/schema-postgresql.sql")); |
|
} catch (Exception e) { |
|
e.printStackTrace(); |
|
} |
|
} |
|
|
|
|
|
|
|
protected void setupTestDb() throws IOException { |
|
FileUtils.deleteQuietly(new File(dbPath + getDbName() + DB_TRACE_SUFFIX)); |
|
FileUtils.deleteQuietly(new File(dbPath + getDbName() + DB_SUFFIX)); |
|
Path from = FileSystems.getDefault().getPath(dbPath, DB_TEMPLATE + DB_SUFFIX); |
|
Path to = FileSystems.getDefault().getPath(dbPath, getDbName() + DB_SUFFIX); |
|
Files.copy(from, to); |
|
} |
|
|
|
private String getDbName() { |
|
return DB_TEMPLATE + startThreadId; |
|
} |
|
|
|
@Override |
|
public void afterPropertiesSet() throws Exception { |
|
this.startThreadId = Thread.currentThread().getId(); |
|
System.setProperty("SX_LOG_TO_TMP", "true"); |
|
File webInfPath = new File(String.join(File.separator, "superx", "WEB-INF")); |
|
File modulePath = new File(String.join(File.separator, "superx", "WEB-INF") + File.separator + PathAndFileUtils.MODULE_PATH); |
|
SuperXManager.setWEB_INFPfad(webInfPath.getAbsolutePath()); |
|
SuperXManager.setModuleDir(modulePath.getAbsolutePath()); |
|
System.setProperty("log4j.configuration", "log4j_unittests.properties"); |
|
System.setProperty("log4j.debug", "true"); |
|
initLogging(); |
|
setupTestDb(); |
|
DataSource eduetl = dataSource(); |
|
SxPools.initTesting(eduetl); |
|
initKettleEnv(); |
|
} |
|
|
|
@Override |
|
public void destroy() throws Exception { |
|
logger.debug("Context Stop Event received."); |
|
SxPools.closeAll(); |
|
FileUtils.deleteQuietly(new File(dbPath + getDbName() + DB_TRACE_SUFFIX)); |
|
FileUtils.deleteQuietly(new File(dbPath + getDbName() + DB_SUFFIX)); |
|
System.setProperty("SX_LOG_TO_TMP", "false"); |
|
if (KettleEnvironment.isInitialized()) { |
|
KettleEnvironment.shutdown(); |
|
} |
|
} |
|
|
|
private final static void initKettleEnv() { |
|
// init kettle environment |
|
try { |
|
System.setProperty("BI_KETTLE_PLUGIN_BASE_FOLDERS", |
|
SuperXManager.getWEB_INFPfad() + File.separator + "kettle-plugins"); |
|
KettleEnvironment.init(); |
|
// init KettleLogStore |
|
KettleLogStore.init(); |
|
logger.debug("Kettle environment sucessfully initialized."); |
|
} catch (Exception e) { |
|
logger.error("Couldn't initialize KettleEnvironment!", e); |
|
} |
|
} |
|
|
|
private static void initLogging() { |
|
File propertiesFile = new File("test/conf/log4j_unittests.properties"); |
|
LogInit.initLog4J(propertiesFile, System.getProperty("java.io.tmpdir")); |
|
logger = Logger.getLogger(TestApplicationConfigH2.class); |
|
logger.info("Log4J Init complete"); |
|
} |
|
|
|
|
|
@ReadingConverter |
|
enum PGobjectToArrayNodeConverter implements Converter<PGobject, ArrayNode> { |
|
INSTANCE; |
|
ObjectMapper mapper = new ObjectMapper(); |
|
|
|
@Override |
|
public ArrayNode convert(PGobject source) { |
|
if (source != null) { |
|
PGobject pgObject = source; |
|
String value = pgObject.getValue(); |
|
if (value == null || value.trim().isEmpty()) { |
|
return mapper.createArrayNode(); // Empty array instead of null |
|
} |
|
|
|
try { |
|
JsonNode node = mapper.readTree(value); |
|
// Ensure it's always an ArrayNode |
|
return node.isArray() ? (ArrayNode) node : mapper.createArrayNode(); |
|
} catch (IOException e) { |
|
throw new RuntimeException("Failed to parse JSON", e); |
|
} |
|
} |
|
return mapper.createArrayNode(); // Default empty array |
|
} |
|
} |
|
|
|
@WritingConverter |
|
enum ArrayNodeToPGobjectConverter implements Converter<ArrayNode, PGobject> { |
|
INSTANCE; |
|
@Override |
|
public PGobject convert(ArrayNode source) { |
|
if (source == null) return null; |
|
PGobject pgObject = new PGobject(); |
|
pgObject.setType("jsonb"); |
|
try { |
|
pgObject.setValue(new ObjectMapper().writeValueAsString(source)); |
|
} catch (JsonProcessingException e) { |
|
// TODO Auto-generated catch block |
|
e.printStackTrace(); |
|
} catch (SQLException e) { |
|
// TODO Auto-generated catch block |
|
e.printStackTrace(); |
|
} |
|
return pgObject; |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
}
|
|
|