use of org.meveo.model.sql.SqlConfiguration in project meveo by meveo-org.
the class StartupListener method init.
@SuppressWarnings("unchecked")
@PostConstruct
@Transactional(Transactional.TxType.REQUIRES_NEW)
public void init() {
entityManagerWrapper.getEntityManager().joinTransaction();
Session session = entityManagerWrapper.getEntityManager().unwrap(Session.class);
session.doWork(connection -> {
applicationInitializer.init();
// A default Repository and SQL Configuration should be genarated/updated at Meveo first initialization
try {
// defaultSqlConfiguration
SqlConfiguration defaultSqlConfiguration;
defaultSqlConfiguration = sqlConfigurationService.findByCode(SqlConfiguration.DEFAULT_SQL_CONNECTION);
if (defaultSqlConfiguration == null) {
defaultSqlConfiguration = new SqlConfiguration();
defaultSqlConfiguration.setCode(SqlConfiguration.DEFAULT_SQL_CONNECTION);
setSqlConfiguration(defaultSqlConfiguration);
sqlConfigurationService.create(defaultSqlConfiguration);
} else {
setSqlConfiguration(defaultSqlConfiguration);
sqlConfigurationService.update(defaultSqlConfiguration);
}
// defaultNeo4jConfiguration
Neo4JConfiguration defaultNeo4jConfiguration = neo4jConfigurationService.findByCode(Neo4JConfiguration.DEFAULT_NEO4J_CONNECTION);
if (defaultNeo4jConfiguration == null) {
defaultNeo4jConfiguration = neo4jConnectionProvider.getDefaultConfiguration();
if (defaultNeo4jConfiguration != null) {
neo4jConfigurationService.create(defaultNeo4jConfiguration);
}
}
Repository defaultRepository = repositoryService.findByCode(Repository.DEFAULT_REPOSITORY);
if (defaultRepository == null) {
defaultRepository = new Repository();
defaultRepository.setCode(Repository.DEFAULT_REPOSITORY);
defaultRepository.setSqlConfiguration(defaultSqlConfiguration);
defaultRepository.setNeo4jConfiguration(defaultNeo4jConfiguration);
repositoryService.create(defaultRepository);
log.info("Created default repository");
} else if (defaultNeo4jConfiguration != null && defaultRepository.getNeo4jConfiguration() == null) {
defaultRepository.setNeo4jConfiguration(defaultNeo4jConfiguration);
repositoryService.update(defaultRepository);
log.info("Updated default repository");
}
} catch (BusinessException e) {
log.error("Cannot create default repository", e);
}
// Create Meveo git repository
GitRepository meveoRepo = gitRepositoryService.findByCode("Meveo");
if (meveoRepo == null) {
try {
meveoRepo = gitRepositoryService.create(GitRepositoryService.MEVEO_DIR, false, GitRepositoryService.MEVEO_DIR.getDefaultRemoteUsername(), GitRepositoryService.MEVEO_DIR.getClearDefaultRemotePassword());
log.info("Created Meveo GIT repository");
} catch (BusinessException e) {
log.error("Cannot create Meveo GIT repository", e);
}
} else {
log.info("Meveo GIT repository already created");
try {
GitRepositoryService.MEVEO_DIR = meveoRepo;
//
gitClient.create(//
GitRepositoryService.MEVEO_DIR, //
false, //
GitRepositoryService.MEVEO_DIR.getDefaultRemoteUsername(), GitRepositoryService.MEVEO_DIR.getDefaultRemotePassword());
} catch (BusinessException e) {
log.error("Cannot create Meveo Git folder", e);
}
}
try {
createMeveoModule(meveoRepo);
} catch (BusinessException e2) {
log.error("Failed to create main Meveo module");
}
// Generate .gitignore file
List<String> ignoredFiles = List.of(".classpath", ".project", ".settings/*", ".vscode/*", "target/*");
File gitRepo = GitHelper.getRepositoryDir(appInitUser.get(), meveoRepo.getCode());
File gitIgnoreFile = new File(gitRepo, ".gitignore");
try {
List<String> actualIgnoredFiles = gitIgnoreFile.exists() ? Files.readAllLines(gitIgnoreFile.toPath()) : List.of();
Collection<String> missingEntries = CollectionUtils.subtract(ignoredFiles, actualIgnoredFiles);
try (FileWriter fw = new FileWriter(gitIgnoreFile, true);
BufferedWriter output = new BufferedWriter(fw)) {
for (String missingEntry : missingEntries) {
output.append(missingEntry);
output.newLine();
}
}
gitClient.commitFiles(meveoRepo, List.of(gitIgnoreFile), "Update .gitignore");
} catch (IOException e1) {
log.error("Can't read / write .gitignore file");
} catch (BusinessException e) {
log.error("Can't commit .gitignore file", e);
} catch (JGitInternalException e) {
log.error("Can't commit .gitignore file, it is probably corrupted, you might want to delete it and restart meveo", e);
}
// Create default pom file
mavenConfigurationService.createDefaultPomFile(meveoRepo.getCode());
try {
// Create default maven repository
RemoteRepository remoteRepository = remoteRepositoryService.findByCode("maven central");
if (remoteRepository == null) {
remoteRepository = new RemoteRepository();
remoteRepository.setCode("maven central");
remoteRepository.setUrl("https://repo1.maven.org/maven2/");
remoteRepositoryService.create(remoteRepository);
log.info("Created default maven repository");
}
} catch (BusinessException e) {
log.error("Cannot create default maven repository", e);
}
log.info("Thank you for running Meveo Community code.");
});
session.flush();
try {
// Set-up secret key
String secret = System.getProperty("meveo.security.secret");
if (secret == null) {
var paramBean = ParamBean.getInstance("meveo-security.properties");
secret = paramBean.getProperty("meveo.security.secret", null);
if (secret == null) {
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
SecureRandom secureRandom = new SecureRandom();
int keyBitSize = 256;
keyGenerator.init(keyBitSize, secureRandom);
SecretKey secretKey = keyGenerator.generateKey();
byte[] encodedKey = Base64.getEncoder().encode(secretKey.getEncoded());
var randomSecret = new String(encodedKey, StandardCharsets.UTF_8);
paramBean.setProperty("meveo.security.secret", randomSecret);
paramBean.saveProperties();
secret = randomSecret;
}
System.setProperty("meveo.security.secret", secret);
}
} catch (NoSuchAlgorithmException e1) {
throw new RuntimeException(e1);
}
// Test neo4j connections
var neo4jConfs = neo4jConfigurationService.listActive();
for (var neo4jConf : neo4jConfs) {
try {
var neo4jSession = neo4jConnectionProvider.getSession(neo4jConf.getCode());
neo4jSession.close();
} catch (Exception e) {
try {
neo4jConfigurationService.disable(neo4jConf.getId());
} catch (BusinessException e1) {
log.error("Failed to disable {}", neo4jConf, e1);
}
}
}
for (MeveoInitializer initializer : initializers) {
try {
initializer.init();
} catch (Exception e) {
log.error("Error during execution of {}", initializer.getClass(), e);
}
}
}
use of org.meveo.model.sql.SqlConfiguration in project meveo by meveo-org.
the class EncryptPasswords method execute.
@Override
public void execute() throws Exception {
for (MeveoInstance meveoInstance : meveoInstanceService.list()) {
meveoInstance.setClearPassword(meveoInstance.getAuthPassword());
meveoInstanceService.update(meveoInstance);
}
for (Neo4JConfiguration neo4jConf : neo4jConfigurationService.list()) {
neo4jConf.setClearPassword(neo4jConf.getNeo4jPassword());
neo4jConfigurationService.update(neo4jConf);
}
for (SqlConfiguration sqlService : sqlConfigurationService.list()) {
sqlService.setClearPassword(sqlService.getPassword());
sqlConfigurationService.update(sqlService);
}
for (GitRepository gitRepo : gitRepositoryService.list()) {
if (gitRepo.getDefaultRemoteUsername() != null) {
gitRepo.setClearDefaultRemotePassword(gitRepo.getDefaultRemotePassword());
gitRepositoryService.update(gitRepo);
}
}
}
use of org.meveo.model.sql.SqlConfiguration in project meveo by meveo-org.
the class CustomTableCreatorService method createTable.
/**
* Create a table with a single 'id' field. Value is autoincremented for mysql
* or taken from sequence for Postgress databases.
*
* @param sqlConnectionCode Code of the {@link SqlConfiguration}
* @param template Template used to create the table
* @param createSequence Whether to create a sequence to generate ids
*/
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void createTable(String sqlConnectionCode, CustomEntityTemplate template, boolean createSequence) {
executePostgreSqlExtension(sqlConnectionCode);
var dbTableName = SQLStorageConfiguration.getDbTablename(template);
List<Change> pgChanges = new ArrayList<>();
List<Change> msChanges = new ArrayList<>();
DatabaseChangeLog dbLog = new DatabaseChangeLog("path");
// Changeset for Postgress
ChangeSet pgChangeSet = new ChangeSet(dbTableName + "_CT_CP_" + System.currentTimeMillis(), "Meveo", false, false, "meveo", "", "postgresql", dbLog);
CreateTableChange createPgTableChange = new CreateTableChange();
createPgTableChange.setTableName(dbTableName);
AddColumnConfig pgUuidColumn = new AddColumnConfig();
pgUuidColumn.setName(UUID);
pgUuidColumn.setType("varchar(255)");
pgUuidColumn.setDefaultValueComputed(new DatabaseFunction("uuid_generate_v4()"));
// Primary key constraint
ConstraintsConfig idConstraints = new ConstraintsConfig();
idConstraints.setNullable(false);
idConstraints.setPrimaryKey(true);
idConstraints.setPrimaryKeyName(dbTableName + "PK");
// If template has a parent template, uuid should have foreign key on parent table
if (template.getSuperTemplate() != null && template.getSuperTemplate().getAvailableStorages().contains(DBStorageType.SQL)) {
var parentTableName = SQLStorageConfiguration.getDbTablename(template.getSuperTemplate());
idConstraints.setForeignKeyName(getInheritanceFK(dbTableName, parentTableName));
idConstraints.setReferencedTableName(parentTableName);
idConstraints.setReferencedColumnNames(UUID);
}
pgUuidColumn.setConstraints(idConstraints);
createPgTableChange.addColumn(pgUuidColumn);
pgChanges.add(createPgTableChange);
// Statement generated by liquibase not suitable for postgres < 9.5
SqlConfiguration sqlConf = sqlConfigurationService.findByCode(sqlConnectionCode);
String schema = StringUtils.isBlank(sqlConf.getSchema()) ? "public" : sqlConf.getSchema();
final RawSQLChange createPgSequence;
if (createSequence) {
createPgSequence = new RawSQLChange("CREATE SEQUENCE " + schema + "." + dbTableName + "_seq;");
pgChanges.add(createPgSequence);
} else {
createPgSequence = null;
}
dbLog.addChangeSet(pgChangeSet);
// Changeset for mysql
ChangeSet mysqlChangeSet = new ChangeSet(dbTableName + "_CT_CM_" + System.currentTimeMillis(), "Meveo", false, false, "meveo", "", "mysql", dbLog);
CreateTableChange createMsTableChange = new CreateTableChange();
createMsTableChange.setTableName(dbTableName);
AddColumnConfig msUuidcolumn = new AddColumnConfig();
msUuidcolumn.setName(UUID);
msUuidcolumn.setType("varchar(255)");
msUuidcolumn.setDefaultValueComputed(new DatabaseFunction("uuid()"));
msUuidcolumn.setConstraints(idConstraints);
createMsTableChange.addColumn(msUuidcolumn);
msChanges.add(createMsTableChange);
dbLog.addChangeSet(mysqlChangeSet);
try (Session hibernateSession = sqlConnectionProvider.getSession(sqlConnectionCode)) {
hibernateSession.doWork(connection -> {
DatabaseMetaData meta = connection.getMetaData();
Database database;
try {
database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(connection));
setSchemaName(database);
} catch (DatabaseException e1) {
log.error("Failed to retrieve database for connection {}", connection);
throw new SQLException(e1);
}
// Check table does not exists
try (var res = meta.getTables(null, database.getDefaultSchemaName(), dbTableName, new String[] { "TABLE" })) {
if (res.next()) {
pgChanges.remove(createPgTableChange);
msChanges.remove(createMsTableChange);
// if uuid field does not exists, add it
try (ResultSet res2 = meta.getColumns(null, database.getDefaultSchemaName(), dbTableName, "uuid")) {
if (!res2.next()) {
AddColumnChange pgUuidColChange = new AddColumnChange();
pgUuidColChange.setTableName(dbTableName);
pgUuidColChange.setColumns(List.of((pgUuidColumn)));
pgChanges.add(pgUuidColChange);
AddColumnChange msUuidColChange = new AddColumnChange();
msUuidColChange.setTableName(dbTableName);
msUuidColChange.setColumns(List.of(msUuidcolumn));
msChanges.add(msUuidColChange);
}
}
}
}
// Check sequence does not exists
try (var res = meta.getTables(null, database.getDefaultSchemaName(), dbTableName + "_seq", new String[] { "SEQUENCE" })) {
if (res.next() && createPgSequence != null) {
pgChanges.remove(createPgSequence);
}
}
try {
pgChanges.forEach(pgChangeSet::addChange);
msChanges.forEach(mysqlChangeSet::addChange);
Liquibase liquibase = new Liquibase(dbLog, new ClassLoaderResourceAccessor(), database);
liquibase.update(new Contexts(), new LabelExpression());
} catch (Exception e) {
log.error("Failed to create a custom table {} on SQL Configuration {}", dbTableName, sqlConnectionCode, e);
throw new SQLException(e);
}
});
}
}
use of org.meveo.model.sql.SqlConfiguration in project meveo by meveo-org.
the class NativePersistenceService method update.
/**
* Update a record in a table. Record is identified by an "uuid" field value.
* @param sqlConnectionCode Code of the {@link SqlConfiguration} to use
*
* @param cei the {@link CustomEntityInstance}. The cf values must
* contain the field uuid.
* @param isFiltered if true process only the fields with storage=SQL
* @param removeNullValues if true, remove the null values
* @throws BusinessException General exception
*/
public void update(String sqlConnectionCode, CustomEntityInstance cei, boolean isFiltered, Collection<CustomFieldTemplate> cfts, boolean removeNullValues) throws BusinessException {
// Update data in parent template
if (cei.getCet().getSuperTemplate() != null && cei.getCet().getSuperTemplate().storedIn(DBStorageType.SQL)) {
var parentCfts = customFieldTemplateService.findByAppliesTo(cei.getCet().getSuperTemplate().getAppliesTo()).values();
var parentCei = new CustomEntityInstance();
parentCei.setCet(cei.getCet().getSuperTemplate());
parentCei.setCfValues(cei.getCfValues());
parentCei.setUuid(cei.getUuid());
update(sqlConnectionCode, parentCei, true, parentCfts, removeNullValues);
}
String tableName = PostgresReserverdKeywords.escapeAndFormat(cei.getTableName());
Map<String, Object> sqlValues = cei.getCfValuesAsValues(isFiltered ? DBStorageType.SQL : null, cfts, removeNullValues);
var appliesTo = CustomEntityTemplate.getAppliesTo(cei.getCetCode());
Map<String, CustomFieldTemplate> cftsMap = cfts.stream().filter(cft -> cft.getAppliesTo().equals(appliesTo)).collect(Collectors.toMap(cft -> cft.getCode(), cft -> cft));
// remove inherited data
for (String sqlValueKey : List.copyOf(sqlValues.keySet())) {
if (sqlValueKey.equals("uuid"))
continue;
if (!cftsMap.containsKey(sqlValueKey)) {
sqlValues.remove(sqlValueKey);
}
}
final Map<String, Object> values = serializeValues(convertValue(sqlValues, cftsMap, removeNullValues, null), cftsMap);
for (String key : cftsMap.keySet()) {
if (key != null && !values.keySet().contains(key) && cftsMap.get(key).getStorageType().equals(CustomFieldStorageTypeEnum.LIST)) {
values.put(key, new ArrayList<>());
}
}
if (sqlValues.get(FIELD_ID) == null) {
throw new BusinessException("'uuid' field value not provided to update values in native table");
}
if (sqlValues.size() < 2) {
// Nothing to update a there is only "uuid" value inside the map
return;
}
StringBuilder sql = new StringBuilder();
try {
sql.append("UPDATE ").append(tableName).append(" SET ");
boolean first = true;
for (String fieldName : values.keySet()) {
String fieldNameInSQL = PostgresReserverdKeywords.escapeAndFormat(fieldName);
if (fieldName.equals(FIELD_ID)) {
continue;
}
if (!first) {
sql.append(",");
}
if (values.get(fieldName) == null) {
sql.append(fieldNameInSQL).append(" = NULL");
} else {
sql.append(fieldNameInSQL).append(" = ? ");
}
first = false;
}
sql.append(" WHERE uuid='" + cei.getUuid() + "'");
Session hibernateSession = crossStorageTransaction.getHibernateSession(sqlConnectionCode);
hibernateSession.doWork(connection -> {
if (!sqlConnectionCode.equals(SqlConfiguration.DEFAULT_SQL_CONNECTION)) {
if (!sqlConnectionProvider.getSqlConfiguration(sqlConnectionCode).isXAResource())
connection.setAutoCommit(false);
}
setSchema(sqlConnectionCode, connection);
try (PreparedStatement ps = connection.prepareStatement(sql.toString())) {
int parameterIndex = 1;
for (String fieldName : values.keySet()) {
Object fieldValue = values.get(fieldName);
if (fieldValue != null && fieldName != "uuid") {
setParameterValue(ps, parameterIndex++, fieldValue);
}
}
ps.executeUpdate();
if (!sqlConnectionCode.equals(SqlConfiguration.DEFAULT_SQL_CONNECTION)) {
if (!sqlConnectionProvider.getSqlConfiguration(sqlConnectionCode).isXAResource())
connection.commit();
}
} catch (Exception e) {
log.error("Native SQL update failed: {}", e.getMessage());
if (!sqlConnectionCode.equals(SqlConfiguration.DEFAULT_SQL_CONNECTION)) {
if (!sqlConnectionProvider.getSqlConfiguration(sqlConnectionCode).isXAResource())
connection.rollback();
}
}
});
CustomTableRecord record = new CustomTableRecord();
record.setUuid((String) values.get(FIELD_ID));
record.setCetCode(cei.getTableName());
customTableRecordUpdate.fire(record);
} catch (Exception e) {
log.error("Failed to insert values into table {} {} sql {}", tableName, values, sql, e);
throw e;
}
}
use of org.meveo.model.sql.SqlConfiguration in project meveo by meveo-org.
the class SQLConnectionProvider method findByCode.
public SqlConfiguration findByCode(String code) {
EntityManager entityManager = emWrapperProvider.get().getEntityManager();
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<SqlConfiguration> query = cb.createQuery(SqlConfiguration.class);
Root<SqlConfiguration> root = query.from(SqlConfiguration.class);
query.select(root);
query.where(cb.equal(root.get("code"), code));
return entityManager.createQuery(query).getSingleResult();
}
Aggregations