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

com.virtusa.gto.nyql.engine.NyQL.groovy Maven / Gradle / Ivy

There is a newer version: 2.0-rc4
Show newest version
package com.virtusa.gto.nyql.engine
@java.lang.SuppressWarnings('JdbcConnectionReference')
import com.virtusa.gto.nyql.configs.ConfigBuilder
import com.virtusa.gto.nyql.configs.ConfigKeys
import com.virtusa.gto.nyql.configs.ConfigParser
import com.virtusa.gto.nyql.configs.Configurations
import com.virtusa.gto.nyql.exceptions.NyException
import com.virtusa.gto.nyql.model.QScript
import com.virtusa.gto.nyql.utils.QUtils
import groovy.json.JsonSlurper
import groovy.transform.CompileStatic
import org.slf4j.Logger
import org.slf4j.LoggerFactory

import java.nio.charset.StandardCharsets
/**
 * Main interface to interact with NyQL queries.
 *
 * @author IWEERARATHNA
 */
@SuppressWarnings('CatchException')
class NyQL {

    private static final Logger LOGGER = LoggerFactory.getLogger(NyQL)

    private static final String BOOTSTRAP_KEY = 'com.virtusa.gto.nyql.autoBootstrap'
    private static final String AUTO_SHUTDOWN_KEY = 'com.virtusa.gto.nyql.addShutdownHook'
    private static final String LOAD_CLASSPATH_KEY = 'com.virtusa.gto.nyql.classpathBootstrap'
    private static final String CONFIG_PATH_KEY = 'com.virtusa.gto.nyql.nyConfigFile'
    private static final String MODE_KEY = 'com.virtusa.gto.nyql.mode'

    private static final int STAR_LEN = 100
    private static final String TRUE_STR = 'true'
    private static final String FALSE_STR = 'false'
    private static final String JSON_CONFIG_FILENAME = 'nyql.json'

    private static NyQLInstance nyQLInstance

    static {
        boolean serverMode = QUtils.readEnv(MODE_KEY, "").equalsIgnoreCase("server")

        try {
            if (!serverMode && !Boolean.parseBoolean(QUtils.readEnv(BOOTSTRAP_KEY, TRUE_STR))) {
                LOGGER.warn('*' * STAR_LEN)
                LOGGER.warn('You MUST EXPLICITLY setup NyQL with programmatically or configuration json file!')
                LOGGER.warn('*' * STAR_LEN)
                return
            }

            configure()

            if (Boolean.parseBoolean(QUtils.readEnv(AUTO_SHUTDOWN_KEY, FALSE_STR))) {
                LOGGER.warn('Automatically adding a NyQL shutdown hook...')
                Runtime.runtime.addShutdownHook(new Thread ({ shutdown() }))
            } else if (!serverMode) {
                LOGGER.warn('*' * STAR_LEN)
                LOGGER.warn('You MUST EXPLICITLY Call SHUTDOWN method of NyQL when you are done with this!')
                LOGGER.warn('*' * STAR_LEN)
            }
        } catch (Exception ex) {
            LOGGER.error('Error occurred while initializing NyQL!', ex)
            throw ex
        }
    }

    /**
     * Configure NyQL with a configuration json file. If the input json file is null,
     * then it will look for a file in classpath/working directory.
     *
     * @param inputJson input json file.
     * @param force if specified true, then configurations will be reloaded.
     */
    static void configure(File inputJson=null, boolean force=false) {
        boolean serverMode = QUtils.readEnv(MODE_KEY, "").equalsIgnoreCase("server")
        if (!Configurations.instance().isConfigured() || force) {
            LOGGER.warn('NyQL is going to configure with default configurations using classpath...')
            if (!configFromSystemProperty() && !configFromClasspath()) {
                File nyConfig = inputJson ?: new File(JSON_CONFIG_FILENAME)
                if (!nyConfig.exists()) {
                    if (!serverMode) {
                        LOGGER.error('*' * STAR_LEN)
                        LOGGER.error("No nyql.json file is found on classpath! [${nyConfig.absolutePath}]")
                        LOGGER.error(' ' * (STAR_LEN / 2))
                        LOGGER.error('Explicitly call the configure method with configuration input file!')
                        LOGGER.error('*' * STAR_LEN)
                    }
                    //throw new RuntimeException("No '$JSON_CONFIG_FILENAME' file is found on classpath! [" + nyConfig.absolutePath + "]");
                } else {
                    LOGGER.debug("Loading configurations from ${nyConfig.canonicalPath}...")
                    Map configData = ConfigParser.parseAndResolve(nyConfig)
                    configData.put(ConfigKeys.LOCATION_KEY, new File('.').canonicalPath)
                    Configurations configurations = ConfigBuilder.instance().setupFrom(configData).build()
                    nyQLInstance = NyQLInstance.create(configurations)
                }
            }

        } else {
            LOGGER.warn('NyQL has already been configured!')
        }
    }

    /**
     * Config NyQL from the file specified in system property.
     *
     * @return true if configured from system property.
     */
    private static boolean configFromSystemProperty() {
        String path = QUtils.readEnv(CONFIG_PATH_KEY, null)
        if (path != null) {
            LOGGER.debug('NyQL is configuring from path specified in system property: ' + path)
            File inputConfig = new File(path)
            if (inputConfig.exists()) {
                Map configData = ConfigParser.parseAndResolve(inputConfig)
                configData.put(ConfigKeys.LOCATION_KEY, inputConfig.canonicalPath)
                Configurations configInst = ConfigBuilder.instance().setupFrom(configData).build()
                nyQLInstance = NyQLInstance.create(configInst)
                return true
            } else {
                throw new IOException('Given configuration file does not exist! ' + path)
            }
        }
        false
    }

    /**
     * Config NyQL from classpath.
     *
     * @return true if successfully configured from
     */
    private static boolean configFromClasspath() {
        if (!asBoolean(QUtils.readEnv(LOAD_CLASSPATH_KEY, TRUE_STR))) {
            LOGGER.warn('NyQL configuration from classpath has been disabled!')
            return false
        }

        def res = Thread.currentThread().contextClassLoader.getResourceAsStream(JSON_CONFIG_FILENAME)
        if (res != null) {
            try {
                LOGGER.debug('Loading configurations from classpath...')
                Map configData = new JsonSlurper().parse(res, StandardCharsets.UTF_8.name()) as Map
                Configurations configInst = ConfigBuilder.instance().setupFrom(configData).build()
                nyQLInstance = NyQLInstance.create(configInst)
                return true
            } finally {
                res.close()
            }
        }
        false
    }

    /**
     * 

* Parse the given file indicated from given script name and returns the generated query * with its other information. Your script name would be the relative path from the * script root directory, always having forward slashes (/). *

* You should call this only if you are working with a script repository. * * @param scriptName name of the script. * @return generated query instance. * @throws NyException any exception thrown while parsing. */ @CompileStatic static QScript parse(String scriptName) throws NyException { nyQLInstance.parse(scriptName) } /** *

* Parse the given file indicated from given script name using the given variable set * and returns the generated query * with its other information. Your script name would be the relative path from the * script root directory, always having forward slashes (/). *

* You should call this only if you are working with a script repository. * * @param scriptName name of the script. * @param data set of variable data required for generation of query. * @return generated query instance. * @throws NyException any exception thrown while parsing. */ @CompileStatic static QScript parse(String scriptName, Map data) throws NyException { nyQLInstance.parse(scriptName, data) } /** * Shutdown the nyql engine. * This should be called only when your application exits. */ @CompileStatic static void shutdown() { nyQLInstance.shutdown() } static Configurations getConfigurations() { nyQLInstance.configurations } /** *

* Executes a given file indicated by the script name and returns the final result * which was output of the last statement in the script ran. *

*

* This method will automatically parse the script and execute using internally * configured executor. *

* * @param scriptName name of the script to be run. * @return the result of the script execution. * @throws NyException any exception thrown while parsing or executing. */ @CompileStatic static T execute(String scriptName) throws NyException { nyQLInstance.execute(scriptName) } /** *

* Executes a given file indicated by the script name using given set of variables * and returns the final result * which was output of the last statement in the script ran. *

*

* This method will automatically parse the script and execute using internally * configured executor. *

* Note:
* You should pass all parameter values required for the query execution. * * @param scriptName name of the script to be run. * @param data set of variables to be passed to the script run. * @return the result of the script execution. * @throws NyException any exception thrown while parsing or executing. */ @CompileStatic static T execute(String scriptName, Map data) throws NyException { nyQLInstance.execute(scriptName, data) } /** * Executes the given script and returns the result as a json string. *

* If you still want to parse the json again, use the other execute method * execute(String, Map). *

* * @param scriptName name of the script to run. * @param data set of variables required for script. * @return result as json string. * @throws NyException any exception thrown while executing and parsing. */ @CompileStatic static String executeToJSON(String scriptName, Map data) throws NyException { nyQLInstance.executeToJSON(scriptName, data) } /** * Executes the given script and returns the result as a json string. *

* If you still want to parse the json again, use the other execute method * execute(String, Map). *

* * @param scriptName name of the script to run. * @return result as json string. * @throws NyException any exception thrown while executing and parsing. */ @CompileStatic static String executeToJSON(String scriptName) throws NyException { nyQLInstance.executeToJSON(scriptName) } @CompileStatic private static boolean asBoolean(String text) { text != null && (text.equalsIgnoreCase(TRUE_STR) || text.equalsIgnoreCase('yes')) } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy