Package org.elasticsearch.shell

Source Code of org.elasticsearch.shell.BasicShell

/*
* Licensed to Luca Cavanna (the "Author") under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. Elastic Search licenses this
* file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.shell;


import java.io.PrintStream;
import java.util.concurrent.atomic.AtomicBoolean;

import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.shell.client.ClientFactory;
import org.elasticsearch.shell.command.ScriptLoader;
import org.elasticsearch.shell.console.Console;
import org.elasticsearch.shell.http.ShellHttpClient;
import org.elasticsearch.shell.json.ToXContentAsString;
import org.elasticsearch.shell.node.Node;
import org.elasticsearch.shell.node.NodeFactory;
import org.elasticsearch.shell.scheduler.Scheduler;
import org.elasticsearch.shell.script.ScriptExecutor;
import org.elasticsearch.shell.source.CompilableSource;
import org.elasticsearch.shell.source.CompilableSourceReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Basic shell implementation: it reads a compilable source and executes it
*
* @author Luca Cavanna
*/
public class BasicShell<ShellNativeClient, JsonInput, JsonOutput> implements Shell {

    private static final Logger logger = LoggerFactory.getLogger(BasicShell.class);

    protected final Console<PrintStream> console;
    protected final CompilableSourceReader compilableSourceReader;
    protected final ScriptExecutor scriptExecutor;
    protected final Unwrapper unwrapper;
    protected final ShellScope<?> shellScope;
    protected final ClientFactory<ShellNativeClient> clientFactory;
    protected final NodeFactory<ShellNativeClient, JsonInput, JsonOutput> nodeFactory;
    protected final ScriptLoader scriptLoader;
    protected final Scheduler scheduler;
    protected final ShellSettings shellSettings;
    protected final ToXContentAsString toXContentAsString;
    protected final ShellHttpClient shellHttpClient;

    protected final AtomicBoolean closed = new AtomicBoolean(false);

    /**
     * Creates a new <code>BasicShell</code>
     *
     * @param console the console used to read commands and prints the results
     * @param compilableSourceReader reader that receives a potential script and determines whether
     *                               it really is a compilable script or eventually waits for more input
     * @param scriptExecutor executor used to execute a compilable source
     * @param unwrapper unwraps a script object and converts it to its Java representation
     * @param shellScope the generic shell scope
     * @param scheduler the scheduler that handles all the scheduled actions
     */
    public BasicShell(Console<PrintStream> console, CompilableSourceReader compilableSourceReader,
                      ScriptExecutor scriptExecutor, Unwrapper unwrapper, ShellScope<?> shellScope,
                      ClientFactory<ShellNativeClient> clientFactory,
                      NodeFactory<ShellNativeClient, JsonInput, JsonOutput> nodeFactory,
                      ScriptLoader scriptLoader, Scheduler scheduler,
                      ShellSettings shellSettings,
                      ToXContentAsString toXContentAsString,
                      ShellHttpClient shellHttpClient) {
        this.console = console;
        this.compilableSourceReader = compilableSourceReader;
        this.scriptExecutor = scriptExecutor;
        this.unwrapper = unwrapper;
        this.shellScope = shellScope;
        this.clientFactory = clientFactory;
        this.nodeFactory = nodeFactory;
        this.scriptLoader = scriptLoader;
        this.scheduler = scheduler;
        this.shellSettings = shellSettings;
        this.toXContentAsString = toXContentAsString;
        this.shellHttpClient = shellHttpClient;
    }

    @Override
    public void run() {
        init();

        printLogoAndWelcomeMessage();
        loadStartupScript();

        if (shellSettings.settings().getAsBoolean(ShellSettings.PLAYGROUND_MODE, false)) {
            enablePlaygroundMode();
        } else {
            tryRegisterDefaultClient();
        }

        try {
            doRun();
        } finally {
            close();
        }
    }

    protected void doRun() {
        while (true) {
            CompilableSource source = null;
            try {
                source = compilableSourceReader.read(getPrompt());
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
                console.println("Error while checking the input: " + e.toString());
            }
            if (source != null) {
                Object jsResult = scriptExecutor.execute(source);
                Object javaResult = unwrap(jsResult);
                if (javaResult instanceof ExitSignal) {
                    shutdown();
                    return;
                }
                if (javaResult != null) {
                    console.println(javaToString(javaResult));
                }
            }
        }
    }

    protected String getPrompt() {
        return MessagesProvider.getMessage(ShellSettings.PROMPT_MESSAGE);
    }

    /**
     * Initializes the shell: nothing to do here but can be overridden
     */
    void init() {

    }

    /**
     * Loads the optional startup script
     */
    void loadStartupScript() {
        final String startupScript = shellSettings.settings().get(ShellSettings.STARTUP_SCRIPT);
        if (startupScript != null) {
            console.print("Loading startup script " + startupScript);

            new ExecutorWithProgress<Void>(console, new ExecutorWithProgress.ActionCallback<Void>() {
                @Override
                public Void execute() {
                    try {
                        scriptLoader.loadScript(startupScript);
                    } catch(Throwable t) {
                        logger.error("Error loading the startup script [{}]", startupScript, t);
                    }
                    return null;
                }
            }).execute();
        }
    }

    /**
     * Close the shell: nothing to do here but can be overridden
     */
    void close() {

    }

    protected void printLogoAndWelcomeMessage() {

        StringBuilder logoBuilder = new StringBuilder();
        logoBuilder.append("               ___       \n");
        logoBuilder.append("             //   \\\\   \n");
        logoBuilder.append("         (( ((     ))    ").append(MessagesProvider.getMessage(ShellSettings.WELCOME_MESSAGE));
        logoBuilder.append("         ((  \\\\___//   \n");
        logoBuilder.append("        {{     //        \n");
        logoBuilder.append("         ((   //  ))     \n");
        logoBuilder.append("         ((  //    }}    \n");
        logoBuilder.append("         ((_______))     \n");

        console.println(logoBuilder.toString());
    }

    protected void enablePlaygroundMode() {
        console.print("Enabling playground mode");

        final StringBuilder messageBuilder = new StringBuilder();

        new ExecutorWithProgress<Void>(console, new ExecutorWithProgress.ActionCallback<Void>() {
            @Override
            public Void execute() {
                Node<ShellNativeClient,JsonInput,JsonOutput> node = nodeFactory.newLocalNode();
                shellScope.registerJavaObject("node", node);
                messageBuilder.append(node.toString()).append(" available as node").append("\n");
                ShellNativeClient shellNativeClient = node.client();
                shellScope.registerJavaObject("es", shellNativeClient);
                messageBuilder.append(shellNativeClient.toString()).append(" available as es");
                return null;
            }
        }).execute();

        console.println(messageBuilder.toString());
    }

    protected void tryRegisterDefaultClient() {
        ShellNativeClient shellNativeClient = clientFactory.newTransportClient();
        if (shellNativeClient != null) {
            registerClient(shellNativeClient);
        }
    }

    protected void registerClient(ShellNativeClient shellNativeClient) {
        shellScope.registerJavaObject("es", shellNativeClient);
        console.println(shellNativeClient.toString() + " available as es");
    }

    /**
     * Converts a javascript object returned by the shell to its Java representation
     * @param scriptObject the javascript object to convert
     * @return the Java representation of the input javascript object
     */
    protected Object unwrap(Object scriptObject) {
        return unwrapper.unwrap(scriptObject, true);
    }

    /**
     * Converts a Java object to its textual representation that can be shown as a result of a script execution
     * @param javaObject the Java object to convert to its textual representation
     * @return the textual representation of the input Java object
     */
    protected String javaToString(Object javaObject) {

        //We wanna show a string output whenever there's a ToXContent, which we can convert to json
        if (javaObject instanceof ToXContent) {
            ToXContent toXContent = (ToXContent) javaObject;
            try {
                return toXContentAsString.asString(toXContent);
            } catch (Exception e) {
                logger.warn("Error while trying to convert a {} to XContent", javaObject.getClass().getSimpleName(), e);
            }
        }

        return javaObject.toString();
    }

    @Override
    public void shutdown() {
        if (closed.compareAndSet(false, true)) {
            if (scheduler != null) {
                logger.debug("Shutting down the scheduler");
                scheduler.shutdown();
            }
            shellScope.closeAllResources();

            shellHttpClient.shutdown();

            console.println();
            console.println(MessagesProvider.getMessage(ShellSettings.BYE_MESSAGE));

            console.shutdown();
        }
    }
}
TOP

Related Classes of org.elasticsearch.shell.BasicShell

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.