package org.openslx.bwlp.sat.database.mappers;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;
import org.openslx.bwlp.sat.database.Database;
import org.openslx.bwlp.sat.database.MysqlConnection;
import org.openslx.bwlp.sat.database.MysqlStatement;
import org.openslx.bwlp.sat.mail.MailQueue.MailConfig;
import org.openslx.bwlp.sat.mail.MailTemplate;
import org.openslx.bwlp.sat.mail.MailTemplateConfiguration;
import org.openslx.bwlp.sat.mail.MailTemplatePlain.Template;
import org.openslx.bwlp.thrift.iface.SatelliteConfig;
import org.openslx.util.Json;
public class DbConfiguration {
private static final Logger LOGGER = Logger.getLogger(DbConfiguration.class);
private static final String KEY_CERTIFICATE = "certstore";
private static final String KEY_MAILCONFIG = "mailconfig";
private static final String KEY_TEMPLATES = "templates";
private static final String KEY_LIMITS = "runtimelimits";
static {
Json.registerThriftClass(SatelliteConfig.class);
}
public static KeyStore loadKeyStore(String password)
throws KeyStoreException, SQLException, NoSuchAlgorithmException, CertificateException, IOException {
KeyStore keystore = KeyStore.getInstance("JKS");
InputStream stream = retrieveStream(KEY_CERTIFICATE);
if (stream == null)
return null;
keystore.load(stream, password.toCharArray());
return keystore;
}
public static void saveKeyStore(File file) throws SQLException, FileNotFoundException, IOException {
store(KEY_CERTIFICATE, new FileInputStream(file));
}
private static void store(String configKey, InputStream stream) throws IOException, SQLException {
store(configKey, IOUtils.toByteArray(stream));
}
private static void store(String configKey, byte[] value) throws SQLException {
try (MysqlConnection connection = Database.getConnection()) {
MysqlStatement stmt = connection
.prepareStatement("INSERT INTO configuration" + " (parameter, value) VALUES (:parameter, :value)"
+ " ON DUPLICATE KEY UPDATE value = VALUES(value)");
stmt.setString("parameter", configKey);
stmt.setBinary("value", value);
stmt.executeUpdate();
connection.commit();
} catch (SQLException e) {
LOGGER.error("Query failed in DbConfiguration.store()", e);
throw e;
}
}
private static InputStream retrieveStream(String configKey) throws SQLException {
byte[] data = retrieve(configKey);
if (data == null)
return null;
return new ByteArrayInputStream(data);
}
private static byte[] retrieve(String configKey) throws SQLException {
try (MysqlConnection connection = Database.getConnection()) {
MysqlStatement stmt = connection
.prepareStatement("SELECT value FROM configuration" + " WHERE parameter = :parameter LIMIT 1");
stmt.setString("parameter", configKey);
ResultSet rs = stmt.executeQuery();
if (!rs.next())
return null;
return rs.getBytes("value");
} catch (SQLException e) {
LOGGER.error("Query failed in DbConfiguration.retrieve()", e);
throw e;
}
}
/**
* Returns mailing configuration (SMTP) from data base.
*
* @return mailing configuration (SMTP) from data base.
* @throws SQLException
*/
public static MailConfig getMailConfig() throws SQLException {
byte[] conf = retrieve(KEY_MAILCONFIG);
if (conf == null)
return null;
return Json.deserialize(new String(conf, StandardCharsets.UTF_8), MailConfig.class);
}
/**
* Return satellite runtime config.
*
* @return
* @throws SQLException
*/
public static SatelliteConfig getSatelliteConfig() throws SQLException {
byte[] conf = retrieve(KEY_LIMITS);
if (conf == null)
return null;
return Json.deserialize(new String(conf, StandardCharsets.UTF_8), SatelliteConfig.class);
}
public static void setSatelliteConfig(SatelliteConfig config) throws SQLException {
store(KEY_LIMITS, Json.serialize(config).getBytes(StandardCharsets.UTF_8));
}
private static MailTemplateConfiguration getExistingMailTemplates()
{
MailTemplateConfiguration templateConf = null;
try {
byte[] raw = retrieve(KEY_TEMPLATES);
if (raw != null) {
String json = new String(raw, StandardCharsets.UTF_8);
templateConf = Json.deserialize(json, MailTemplateConfiguration.class);
}
} catch (Exception e) {
LOGGER.debug("Cannot get mail templates from db", e);
}
return templateConf;
}
/**
* access the database to read the mail templates. If the template is not
* found a hard-coded configuration is used and is merged with the database.
*
* @param name name of the desired mail template
*
* @return the mail template with the given name or NULL if no such template
* could be found.
*/
public static MailTemplate getMailTemplate(Template name) {
/* Try to get config from DB */
MailTemplateConfiguration templateConf = getExistingMailTemplates();
/* Case 1: Nothing in DB */
if (templateConf == null) {
/* save default to db */
LOGGER.debug("No template config in DB -> save the default config to DB");
templateConf = MailTemplateConfiguration.defaultTemplateConfiguration;
try {
store(KEY_TEMPLATES, Json.serialize(templateConf).getBytes(StandardCharsets.UTF_8));
} catch (SQLException e) {
}
}
/* Case 2: DB has config but not the template */
if (templateConf != null && templateConf.getByName(name) == null
&& MailTemplateConfiguration.defaultTemplateConfiguration.getByName(name) != null) {
/* merge default config with templateConf */
LOGGER.debug("DB template config does not contain a template for " + name);
MailTemplateConfiguration newConf = templateConf.merge(MailTemplateConfiguration.defaultTemplateConfiguration);
try {
store(KEY_TEMPLATES, Json.serialize(newConf).getBytes(StandardCharsets.UTF_8));
templateConf = newConf;
} catch (SQLException e) {
}
}
/* Case 3: DB has config and has the template */
if (templateConf != null && templateConf.getByName(name) != null) {
return templateConf.getByName(name);
}
/* CASE 4: Neither in DB nor in default */
LOGGER.debug("Template with name \"" + name + "\" could not be found");
return null;
}
public static void updateMailTemplates(boolean resetExisting)
{
MailTemplateConfiguration conf = null;
if (!resetExisting) {
conf = getExistingMailTemplates();
if (conf != null) {
conf = conf.merge(MailTemplateConfiguration.defaultTemplateConfiguration);
}
}
if (conf == null) {
conf = MailTemplateConfiguration.defaultTemplateConfiguration;
}
try {
store(KEY_TEMPLATES, Json.serialize(conf).getBytes(StandardCharsets.UTF_8));
} catch (SQLException e) {
}
}
}