fr.gael.dhus.server.http.webapp.symmetricDS.SymmetricDSWebapp.java Source code

Java tutorial

Introduction

Here is the source code for fr.gael.dhus.server.http.webapp.symmetricDS.SymmetricDSWebapp.java

Source

/*
 * Data Hub Service (DHuS) - For Space data distribution.
 * Copyright (C) 2016 GAEL Systems
 *
 * This file is part of DHuS software sources.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package fr.gael.dhus.server.http.webapp.symmetricDS;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import javax.sql.DataSource;

import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.HttpClients;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.io.ClassPathResource;
import org.springframework.jdbc.datasource.init.ScriptUtils;
import org.springframework.stereotype.Component;

import com.google.common.io.Files;
import com.jolbox.bonecp.BoneCPDataSource;

import fr.gael.dhus.server.ScalabilityManager;
import fr.gael.dhus.server.http.webapp.WebApp;
import fr.gael.dhus.server.http.webapp.WebApplication;
import fr.gael.dhus.system.config.ConfigurationManager;

@Component
@WebApp(name = "sync", scalability = "true")
public class SymmetricDSWebapp extends WebApplication implements InitializingBean {
    private static final Logger LOGGER = LogManager.getLogger(SymmetricDSWebapp.class);

    @Autowired
    BoneCPDataSource dataSource;

    @Autowired
    ScalabilityManager scalabilityManager;

    @Autowired
    ConfigurationManager cfgManager;

    @Qualifier("boneCPDataSource")
    @Autowired
    DataSource datasource;

    @Override
    public void configure(String dest_folder) throws IOException {
        String configurationFolder = "fr/gael/dhus/server/http/webapp/symmetricDS/web";
        URL u = Thread.currentThread().getContextClassLoader().getResource(configurationFolder);
        if (u != null && "jar".equals(u.getProtocol())) {
            extractJarFolder(u, configurationFolder, dest_folder);
        } else if (u != null) {
            File webAppFolder = new File(dest_folder);
            copyFolder(new File(u.getFile()), webAppFolder);
        }

        String properties = "fr/gael/dhus/server/http/webapp/symmetricDS/"
                + (scalabilityManager.isMaster() ? "master" : "replica") + ".properties";
        u = Thread.currentThread().getContextClassLoader().getResource(properties);

        String propFile = dest_folder + "/WEB-INF/classes/symmetric.properties";
        if (u != null && "jar".equals(u.getProtocol())) {
            extractJarFile(u, properties, propFile);
        } else if (u != null) {
            File webAppFolder = new File(propFile);
            Files.copy(new File(u.getFile()), webAppFolder);
        }

        Path path = Paths.get(propFile);
        Charset charset = StandardCharsets.UTF_8;

        String content = new String(java.nio.file.Files.readAllBytes(path), charset);
        content = content.replaceAll("%id%", String.format("%03d", scalabilityManager.getReplicaId()));
        content = content.replaceAll("%masterUrl%", scalabilityManager.getMasterUrl());
        content = content.replaceAll("%localUrl%", scalabilityManager.getLocalUrl());

        content = content.replaceAll("%dbDriver%", dataSource.getDriverClass());
        content = content.replaceAll("%dbUrl%", dataSource.getJdbcUrl());
        content = content.replaceAll("%dbUser%", dataSource.getUsername());
        content = content.replaceAll("%dbPassword%", dataSource.getPassword());
        java.nio.file.Files.write(path, content.getBytes(charset));
    }

    @Override
    public InputStream getWarStream() {
        return SymmetricDSWebapp.class.getClassLoader()
                .getResourceAsStream("fr/gael/dhus/server/http/webapp/symmetricDS/symmetric-ds.war");
    }

    @Override
    public boolean hasWarStream() {
        return true;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        if (!scalabilityManager.getClearDB()) {
            return;
        }
        PreparedStatement ps = datasource.getConnection().prepareStatement(
                "SELECT TRIGGER_NAME FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME LIKE 'SYM_%';",
                ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);

        ResultSet rs = ps.executeQuery();
        while (rs.next()) {
            PreparedStatement ps2 = datasource.getConnection()
                    .prepareStatement("DROP TRIGGER " + rs.getString("TRIGGER_NAME"));
            ps2.execute();
            ps2.close();
        }
        ps.close();

        ps = datasource.getConnection().prepareStatement(
                "SELECT CONSTRAINT_NAME, TABLE_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE CONSTRAINT_NAME LIKE 'SYM_%';",
                ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
        rs = ps.executeQuery();
        while (rs.next()) {
            PreparedStatement ps2 = datasource.getConnection().prepareStatement("ALTER TABLE "
                    + rs.getString("TABLE_NAME") + " DROP CONSTRAINT " + rs.getString("CONSTRAINT_NAME"));
            ps2.execute();
            ps2.close();
        }
        ps.close();

        ps = datasource.getConnection().prepareStatement(
                "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE 'SYM_%';",
                ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);

        rs = ps.executeQuery();
        while (rs.next()) {
            PreparedStatement ps2 = datasource.getConnection()
                    .prepareStatement("DROP TABLE " + rs.getString("TABLE_NAME"));
            ps2.execute();
            ps2.close();
        }
        ps.close();
    }

    @Override
    public void checkInstallation() throws Exception {
        if (!scalabilityManager.isMaster())
            return;

        // Check database is ready for SymmetricDS
        PreparedStatement ps = datasource.getConnection().prepareStatement(
                "SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE CONSTRAINT_NAME='SYM_FK_TRGPLT_2_TR';",
                ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);

        while (!ps.executeQuery().first()) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        ps.close();
        // Check if init.sql has already been executed
        ps = datasource.getConnection().prepareStatement(
                "SELECT node_group_id FROM SYM_NODE_GROUP WHERE node_group_id = 'dhus-replica-group';",
                ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);

        if (!ps.executeQuery().first()) {
            // Wait for master group to be inserted         
            PreparedStatement ps2 = datasource.getConnection().prepareStatement(
                    "SELECT * FROM SYM_NODE_GROUP WHERE node_group_id='dhus-master-group';",
                    ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);

            while (!ps2.executeQuery().first()) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            ps2.close();

            ScriptUtils.executeSqlScript(datasource.getConnection(),
                    new ClassPathResource("fr/gael/dhus/server/http/webapp/symmetricDS/init.sql"));
            LOGGER.info("SymmetricDS initialization script loaded");

            // Force the synchronizers to be reloaded
            HttpClient httpclient = HttpClients.createDefault();
            HttpPost httppost = new HttpPost(
                    cfgManager.getServerConfiguration().getLocalUrl() + "/sync/api/engine/synctriggers");

            httpclient.execute(httppost);
        }
        ps.close();
    }
}