All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.tsl2.nano.persistence.replication.Replication Maven / Gradle / Ivy

/*
 * File: $HeadURL$
 * Id  : $Id$
 * 
 * created by: Tom, Thomas Schneider
 * created on: 16.11.2013
 * 
 * Copyright: (c) Thomas Schneider 2013, all rights reserved
 */
package de.tsl2.nano.persistence.replication;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.net.URL;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executors;

import org.apache.commons.logging.Log;

import de.tsl2.nano.core.ENV;
import de.tsl2.nano.core.ManagedException;
import de.tsl2.nano.core.execution.CompatibilityLayer;
import de.tsl2.nano.core.log.LogFactory;
import de.tsl2.nano.core.serialize.XmlUtil;
import de.tsl2.nano.core.util.FileUtil;
import de.tsl2.nano.core.util.StringUtil;
import de.tsl2.nano.persistence.Persistence;

/**
 * Persistence bean only to be used as additional connection. Default values are set for hsqldb/hibernate
 * 
 * @author Tom, Thomas Schneider
 * @version $Revision$
 */
public class Replication extends Persistence implements Runnable {
    /** serialVersionUID */
    private static final long serialVersionUID = 8157364611484654367L;

    private static final Log LOG = LogFactory.getLog(Replication.class);
    /** xml serialization of Persistence object */
    public static final String FILE_REPLICATION_BEAN = "replication-bean.xml";
    /** jdbc connection properties - used by ejb creator */
    public static final String REPLICATION_JDBC_PROP_FILE = "jdbc-replication.properties";

    transient Map p;

    /**
     * constructor
     */
    public Replication() {
        super();
        persistenceUnit = "replication";
        transactionType = "RESOURCE_LOCAL";
        provider = "org.hibernate.jpa.HibernatePersistenceProvider";
        connectionDriverClass = STD_LOCAL_DATABASE_DRIVER;
        connectionUrl = "jdbc:h2:tcp://localhost:9992/PUBLIC";
        connectionUserName = "SA";
        connectionPassword = "";
        hibernateDialect = "org.hibernate.dialect.H2Dialect";
        defaultSchema = DEFAULT_SCHEMA;
        datasourceClass = STD_LOCAL_DATABASE_DRIVER;
        port = "9992";
        database = "replication";
    }

    @SuppressWarnings("static-access")
    public static Replication current() {
        if (Persistence.exists()) {
            return ENV.get(XmlUtil.class).loadXml(getPath(FILE_PERSISTENCE_BEAN),
                Replication.class);
        } else {
            return new Replication();
        }
    }

    /**
     * addPersistenceProperties
     * 
     * @param prop
     */
    @Override
    public void addPersistenceProperties(Persistence parent, Map prop) {
        database = "replication-" + parent.getConnectionUserName();
        prop.put("replication-unit", "replication");
        prop.put("replication.transaction-type", "RESOURCE_LOCAL");
        prop.put("replication.provider", parent.getProvider());
        prop.put("replication.jta-data-source", parent.getJtaDataSource());
        prop.put("replication.jar-file", parent.jarURL());
        prop.put("replication.dialect", getHibernateDialect());
        prop.put("replication.driver_class", getConnectionDriverClass());
        prop.put("replication.url", getConnectionUrl());
        prop.put("replication.database", getDatabase());
        prop.put("replication.scheme", getDefaultSchema());
        prop.put("replication.username", parent.getConnectionUserName().toUpperCase());
        prop.put("replication.password", parent.getConnectionPassword());

        p = prop;

        if (ENV.get("service.use.database.replication", false)) {
            startReplicationThread();
        }
    }

    @Override
    protected String getBeanFileName() {
        return FILE_REPLICATION_BEAN;
    }

    public Object actionOk() {
        return this;
    }

    @Override
    public String save() throws IOException {
        FileUtil.removeToBackup(getPath(getBeanFileName()));
        ENV.get(XmlUtil.class).saveXml(getPath(getBeanFileName()), this);
        saveJdbcProperties();
        return null;
    }

    @Override
    protected void saveJdbcProperties() throws IOException {
        Properties prop = getJdbcProperties();
        ENV.saveBackup(REPLICATION_JDBC_PROP_FILE);

        prop.store(new FileWriter(new File(getPath(REPLICATION_JDBC_PROP_FILE))),
            "Property file generated by nano.directaccess");
    }
    /**
     * startReplicationThread
     */
    private void startReplicationThread() {
        try {
            //first: check, if connection available
            Socket socket = new Socket((String) null, Integer.valueOf(getPort()));
            socket.close();
            LogFactory.getLog(Replication.class).warn("connection localhost:" + getPort()
                + " already in use. can't start the replication-database!");
        } catch (Exception e) {
            LogFactory.getLog(Replication.class).info("starting replication database '" + database
                + "' on port "
                + port);
            Thread replicationRunner = Executors.defaultThreadFactory().newThread(this);
            replicationRunner.setName("replication-database");
            replicationRunner.setDaemon(true);
            replicationRunner.start();
        }
    }

    @Override
    public void run() {
        String databaseName = getPath((String) p.get("replication.database"));
        String user = p.get("replication.username").toString().toUpperCase();
        String passwd = p.get("replication.password").toString();
//        String scheme = p.get("replication.scheme").toString();
        String databaseFile = databaseName + ".script";
        if (!new File(databaseFile).exists()) {
            /*
             * create hsqldb database script
             */
            try {
                URL resource = Thread.currentThread()
                    .getContextClassLoader()
                    .getResource("replication.script");
                //on nested jars, the resource may be unloadable...
                if (resource == null) {
                    LOG.error("unable to load replication.script ==> canceling replication!");
                    return;
                }

                InputStream stream = (InputStream) resource.getContent();
                String database_script = String.copyValueOf(FileUtil.getFileData(stream, null));

                //hsqldb needs user in uppercase
                p.put("replication.username", user);
                p.put("replication.password", passwd);

                //some properties are twice...
                database_script = StringUtil.insertProperties(database_script, p);
                database_script = StringUtil.insertProperties(database_script, p);
                FileUtil.writeBytes(database_script.getBytes(), databaseFile, false);
            } catch (IOException e) {
                ManagedException.forward(e);
            }
        }
        /*
         * start the hsqldb database
         */
        ENV.get(CompatibilityLayer.class).runOptional("org.hsqldb.Server",
            "main",
            new Class[] { String[].class },
            new Object[] { new String[] { "-database",
                databaseName,
                "-port",
                getPort(),
                "-no_system_exit",
                "true",
                "-silent",
                "false",
                "-trace",
                "true" } });
//        try {
//            ConcurrentUtil.sleep(2000);
//            //doing the same as in createuser.sql of mda.xml
//            Connection con = DriverManager.getConnection(p.get("replication.url").toString(), user,
//                passwd);
//            String sql = "create user " + user + " password '" + passwd + "'; commit;" +
//                         "GRANT DBA to " + user +
//                         "CREATE SCHEMA " + scheme + " AUTHORIZATION DBA;" +
//                         "SET SCHEMA " + scheme + ";";
//            con.prepareStatement(sql).execute();
//        } catch (SQLException e) {
//            ManagedException.forward(e);
//        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy