Package org.jboss.as.test.integration.management.util

Source Code of org.jboss.as.test.integration.management.util.CLIWrapper

/*
* JBoss, Home of Professional Open Source.
* Copyright 2011, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.as.test.integration.management.util;

import static org.jboss.as.arquillian.container.Authentication.PASSWORD;
import static org.jboss.as.arquillian.container.Authentication.USERNAME;


import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.io.StringReader;
import java.text.ParseException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

/**
*
* @author Dominik Pospisil <dpospisi@redhat.com>
*/
public class CLIWrapper implements Runnable {

    private static String cliCommand = null;
    private static final String outThreadHame = "CLI-out";
    private static final String errThreadHame = "CLI-err";
    private Process cliProcess;
    private PrintWriter writer;
    private BufferedReader outputReader;
    private BufferedReader errorReader;
    private BlockingQueue<String> outputQueue = new LinkedBlockingQueue<String>();

    /**
     * Creates new CLI wrapper.
     *
     * @throws Exception
     */
    public CLIWrapper() throws Exception {
        this(false);
    }

    /**
     * Creates new CLI wrapper. If the connect parameter is set to true the CLI will connect to the server using
     * <code>connect</code> command.
     *
     * @param connect indicates if the CLI should connect to server automatically.
     * @throws Exception
     */
    public CLIWrapper(boolean connect) throws Exception {
        init();
        if (!connect) {
            return;
        }

        //connect

        // wait for cli welcome message
        String line = readLine(10000);

        while (!line.contains("You are disconnected")) {
            line = readLine(10000);
        }

        sendLine("connect", false);
        line = readLine(5000);

        if (!(line.indexOf("disconnected") >= 0)) {
            throw new CLIException("Disconnect check failed. Line received: " + line);
        }
        sendLine("version", false);
        line = readLine(5000);
        if (!(line.indexOf("[standalone@") >= 0)) {
            throw new CLIException("Connect failed. Line received: " + line);
        }
    }

    /**
     * Sends command line to CLI.
     *
     * @param line specifies the command line.
     * @param waitForEcho if set to true reads the echo response form the CLI.
     * @throws Exception
     */
    public void sendLine(String line, boolean waitForEcho) throws Exception {
        System.out.println("[CLI-inp] " + line);
        writer.println(line);
        writer.flush();

        if (!waitForEcho) {
            return;
        }

        boolean found = false;
        StringBuilder lines = new StringBuilder();
        while (!found) {
            String eLine = readLine(5000);
            if (eLine == null) {
                throw new Exception("CLI command failed. Sent:" + line + ", received:" + lines.toString());
            }
            lines.append(eLine);
            lines.append(System.getProperty("line.separator"));
            if (eLine.indexOf(line) >= 0) {
                found = true;
            }
        }
    }

    /**
     * Sends command line to CLI.
     *
     * @param line specifies the command line.
     * @throws Exception
     */
    public void sendLine(String line) throws Exception {
        sendLine(line, true);
    }

    /**
     * Non blocking read from CLI output.
     *
     * @return next line from CLI output or null if the output is empty
     */
    public String readLine() {
        return outputQueue.poll();
    }

    /**
     * Blocking read from CLI output.
     *
     * @param timeout number of milliseconds to wait for line
     * @return next line from CLI output
     * @throws Exception is thrown if there is no output available and timeout expired
     */
    public String readLine(long timeout) throws Exception {
        String line = null;
        try {
            line = outputQueue.poll(timeout, TimeUnit.MILLISECONDS);
        } catch (InterruptedException ioe) {
        }
        if (line == null) {
            throw new Exception("CLI read timeout.");
        }
        return line;
    }

    /**
     * Consumes all available output from CLI.
     *
     * @param timeout number of milliseconds to wait for first line
     * @param lineTimeout number of milliseconds to wait for each subsequent line
     * @return array of CLI output lines
     */
    public String[] readAll(long timeout, long lineTimeout) {
        Vector<String> lines = new Vector<String>();
        try {
            String line = outputQueue.poll(timeout, TimeUnit.MILLISECONDS);
            while (line != null) {
                lines.add(line);
                line = outputQueue.poll(lineTimeout, TimeUnit.MILLISECONDS);
            }
        } catch (InterruptedException ioe) {
        }

        return lines.toArray(new String[]{});
    }

    /**
     * Consumes all available output from CLI.
     *
     * @param timeout number of milliseconds to wait for first line
     * @param lineTimeout number of milliseconds to wait for each subsequent line
     * @return array of CLI output lines
     */
    public String readAllUnformated(long timeout, long lineTimeout) {
        String[] lines = readAll(timeout, lineTimeout);
        StringBuilder buf = new StringBuilder();
        for (String line : lines) {
            buf.append(line + " ");
        }
        return buf.toString();

    }

    /**
     * Consumes all available output from CLI and converts the output to ModelNode operation format
     *
     * @param timeout number of milliseconds to wait for first line
     * @param lineTimeout number of milliseconds to wait for each subsequent line
     * @return array of CLI output lines
     */
    public CLIOpResult readAllAsOpResult(long timeout, long lineTimeout) throws Exception {
        String output = readAllUnformated(timeout, lineTimeout);
        StreamTokenizer st = new StreamTokenizer(new StringReader(output));
        st.resetSyntax();
        st.whitespaceChars(' ', ' ');
        st.wordChars('#', '+');
        st.wordChars('-', 'Z');
        st.wordChars('a', 'z');
        st.quoteChar('"');

        int token = st.nextToken();
        if (token != '{') {
            throw new CLIException("Parse error. '{' expected, received: '" + token + "'.");
        }
        Map compound = parseCompound(st);
        CLIOpResult res = new CLIOpResult();
        res.setIsOutcomeSuccess("success".equals(compound.get("outcome")));
        res.setResult(compound.get("result"));
        return res;
    }

    private Map<String, Object> parseCompound(StreamTokenizer st) throws IOException, ParseException {
        Map<String, Object> map = new HashMap<String, Object>();

        int token = st.nextToken();
        while (token != '}') {
            String key = st.sval;
            st.nextToken();
            if (!"=>".equals(st.sval)) {
                throw new ParseException("=> expected, got:" + st.sval, st.lineno());
            }
            token = st.nextToken();
            if (token == '{') {
                // compound attribute
                map.put(key, parseCompound(st));
            } else if (token == '[') {
                // list attribure
                map.put(key, parseList(st));
            } else {
                // primitive attribute
                map.put(key, st.sval);
            }
            token = st.nextToken();
            if (token == ',') {
                token = st.nextToken();
            }
        }
        return map;
    }

    private List parseList(StreamTokenizer st) throws IOException, ParseException {
        List list = new LinkedList();

        int token = st.nextToken();
        while (token != ']') {
            if (token == '{') {
                // compound attribute
                list.add(parseCompound(st));
            } else if (token == '[') {
                // list attribure
                list.add(parseList(st));
            } else {
                // primitive attribute
                list.add(st.sval);
            }
            token = st.nextToken();
            if (token == ',') {
                token = st.nextToken();
            }
        }
        return list;
    }

    /**
     * Discards all CLI output.
     */
    public void flush() {
        outputQueue.clear();
    }

    /**
     * Sends quit command to CLI.
     *
     * @throws Exception
     */
    public synchronized void quit() throws Exception {
        sendLine("quit", false);
        while ((outputReader != null) || (errorReader != null)) {
            try {
                wait();
            } catch (InterruptedException ie) {
            }
        }

    }

    private void init() throws Exception {
        System.out.println("CLI command:" + getCliCommand());

        cliProcess = Runtime.getRuntime().exec(getCliCommand());
        writer = new PrintWriter(cliProcess.getOutputStream());
        outputReader = new BufferedReader(new InputStreamReader(cliProcess.getInputStream()));
        errorReader = new BufferedReader(new InputStreamReader(cliProcess.getErrorStream()));

        Thread readOutputThread = new Thread(this, outThreadHame);
        readOutputThread.start();
        Thread readErrorThread = new Thread(this, errThreadHame);
        readErrorThread.start();

    }

    private static String getCliCommand() throws Exception {
        if (cliCommand != null) {
            return cliCommand;
        }

        String asDist = System.getProperty("jboss.dist");
        String asInst = System.getProperty("jboss.inst");

        String javaExec = System.getProperty("java.home") + File.separatorChar + "bin" + File.separatorChar + "java";
        if (javaExec.contains(" ")) {
            javaExec = "\"" + javaExec + "\"";
        }

        cliCommand = javaExec + " -Djboss.home.dir=" + asInst
                + " -Djboss.modules.dir=" + asDist + "/modules"
                + " -Djline.WindowsTerminal.directConsole=false"
                + " -jar " + asDist + "/jboss-modules.jar"
                + " -mp " + asDist + "/modules"
                + " -logmodule org.jboss.logmanager org.jboss.as.cli"
                + " --user=" + USERNAME
                + " --password=" + PASSWORD;
        return cliCommand;
    }

    /**
     *
     */
    public void run() {
        String threadName = Thread.currentThread().getName();
        BufferedReader reader = threadName.equals(outThreadHame) ? outputReader : errorReader;
        try {
            String line = reader.readLine();
            while (line != null) {
                if (threadName.equals(outThreadHame)) {
                    outputLineReceived(line);
                } else {
                    errorLineReceived(line);
                }
                line = reader.readLine();
            }
        } catch (Exception e) {
        } finally {
            synchronized (this) {
                if (threadName.equals(outThreadHame)) {
                    outputReader = null;
                } else {
                    errorReader = null;
                }
                notifyAll();
            }
        }
    }

    private synchronized void outputLineReceived(String line) {
        System.out.println("[" + outThreadHame + "] " + line);
        outputQueue.add(line);
        notifyAll();
    }

    private synchronized void errorLineReceived(String line) {
        System.out.println("[" + outThreadHame + "] " + line);
        notifyAll();
    }
}
TOP

Related Classes of org.jboss.as.test.integration.management.util.CLIWrapper

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.