Package de.zib.scalaris

Source Code of de.zib.scalaris.ScalarisVM$GetInfoResult

/*
*  Copyright 2007-2011 Zuse Institute Berlin
*
*   Licensed 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 de.zib.scalaris;

import java.net.Inet4Address;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import com.ericsson.otp.erlang.OtpErlangAtom;
import com.ericsson.otp.erlang.OtpErlangInt;
import com.ericsson.otp.erlang.OtpErlangList;
import com.ericsson.otp.erlang.OtpErlangObject;
import com.ericsson.otp.erlang.OtpErlangString;
import com.ericsson.otp.erlang.OtpErlangTuple;

/**
* Provides methods to interact with a specific Scalaris (Erlang) VM.
*
* @author Nico Kruber, kruber@zib.de
* @version 3.10
* @since 3.6
*/
public class ScalarisVM {
    /**
     * Connection to a Scalaris node.
     */
    private final Connection connection;

    /**
     * Creates a connection to the erlang VM of the given Scalaris node. Uses
     * the connection policy of the global connection factory.
     *
     * @param node
     *            Scalaris node to connect with
     * @throws ConnectionException
     *             if the connection fails or the connection policy is not
     *             cloneable
     */
    public ScalarisVM(final String node) throws ConnectionException {
        final ConnectionFactory cf = ConnectionFactory.getInstance();
        connection = cf.createConnection(new FixedNodeConnectionPolicy(node));
    }

    /**
     * Gets the version of the Scalaris VM of the current connection.
     *
     * @return Scalaris version string
     *
     * @throws ConnectionException
     *             if the connection is not active or a communication error
     *             occurs or an exit signal was received or the remote node
     *             sends a message containing an invalid cookie
     * @throws UnknownException
     *             if any other error occurs
     */
    public String getVersion()
            throws ConnectionException, UnknownException {
        final OtpErlangObject received_raw = connection.doRPC("api_vm", "get_version",
                    new OtpErlangObject[] {});
        try {
            return new ErlangValue(received_raw).stringValue();
        } catch (final ClassCastException e) {
            throw new UnknownException(e, received_raw);
        }
    }

    /**
     * Plain old data object for results of {@link ScalarisVM#getInfo()}.
     *
     * @author Nico Kruber, kruber@zib.de
     * @version 3.6
     * @since 3.6
     */
    public static class GetInfoResult {
        /**
         * Scalaris version string.
         */
        public final String scalarisVersion;
        /**
         * Erlang version string.
         */
        public final String erlangVersion;
        /**
         * Total amount of memory currently allocated.
         */
        public final int memTotal;
        /**
         * Uptime of the Erlang VM.
         */
        public final int uptime;
        /**
         * Erlang node name.
         */
        public final String erlangNode;
        /**
         * IP address to reach the Scalaris node inside the Erlang VM.
         */
        public final Inet4Address ip;
        /**
         * Port to reach the Scalaris node inside the Erlang VM.
         */
        public final int port;
        /**
         * Yaws port to reach the JSON API and web debug interface.
         */
        public final int yawsPort;

        /**
         * @param scalarisVersion
         * @param erlangVersion
         * @param memTotal
         * @param uptime
         * @param erlangNode
         * @param ip
         * @param port
         * @param yawsPort
         */
        public GetInfoResult(final String scalarisVersion, final String erlangVersion,
                final int memTotal, final int uptime, final String erlangNode, final Inet4Address ip,
                final int port, final int yawsPort) {
            super();
            this.scalarisVersion = scalarisVersion;
            this.erlangVersion = erlangVersion;
            this.memTotal = memTotal;
            this.uptime = uptime;
            this.erlangNode = erlangNode;
            this.ip = ip;
            this.port = port;
            this.yawsPort = yawsPort;
        }
    }

    /**
     * Gets some information about the VM and Scalaris.
     *
     * @return VM information
     *
     * @throws ConnectionException
     *             if the connection is not active or a communication error
     *             occurs or an exit signal was received or the remote node
     *             sends a message containing an invalid cookie
     * @throws UnknownException
     *             if any other error occurs
     */
    public GetInfoResult getInfo()
            throws ConnectionException, UnknownException {
        final OtpErlangObject received_raw = connection.doRPC("api_vm", "get_info",
                    new OtpErlangObject[] {});
        try {
            final OtpErlangList received = (OtpErlangList) received_raw;
            final Map<String, OtpErlangObject> result = new LinkedHashMap<String, OtpErlangObject>(
                    received.arity());
            for (final OtpErlangObject iter : received) {
                final OtpErlangTuple iter_tpl = (OtpErlangTuple) iter;
                if (iter_tpl.arity() == 2) {
                    final String key = ((OtpErlangAtom) (iter_tpl.elementAt(0))).atomValue();
                    result.put(key, iter_tpl.elementAt(1));
                } else {
                    throw new UnknownException(received_raw);
                }
            }
            final String scalarisVersion = new ErlangValue(result.get("scalaris_version")).stringValue();
            final String erlangVersion = new ErlangValue(result.get("erlang_version")).stringValue();
            final int memTotal = new ErlangValue(result.get("mem_total")).intValue();
            final int uptime = new ErlangValue(result.get("uptime")).intValue();
            final String erlangNode = new ErlangValue(result.get("erlang_node")).stringValue();
            final OtpErlangTuple erlIP = (OtpErlangTuple) result.get("ip");
            final Inet4Address ip = (Inet4Address) Inet4Address.getByName(
                    erlIP.elementAt(0) + "." + erlIP.elementAt(1) + "." + erlIP.elementAt(2) + "." + erlIP.elementAt(3));
            final int port = new ErlangValue(result.get("port")).intValue();
            final int yawsPort = new ErlangValue(result.get("yaws_port")).intValue();
            return new GetInfoResult(scalarisVersion, erlangVersion, memTotal, uptime, erlangNode, ip, port, yawsPort);
        } catch (final ClassCastException e) {
            throw new UnknownException(e, received_raw);
        } catch (final NullPointerException e) {
            throw new UnknownException(e, received_raw);
        } catch (final UnknownHostException e) {
            throw new UnknownException(e, received_raw);
        }
    }

    /**
     * Gets the number of nodes in the Scalaris VM of the current connection.
     *
     * @return number of nodes
     *
     * @throws ConnectionException
     *             if the connection is not active or a communication error
     *             occurs or an exit signal was received or the remote node
     *             sends a message containing an invalid cookie
     * @throws UnknownException
     *             if any other error occurs
     */
    public int getNumberOfNodes()
            throws ConnectionException, UnknownException {
        final OtpErlangObject received_raw = connection.doRPC("api_vm", "number_of_nodes",
                    new OtpErlangObject[] {});
        try {
            return new ErlangValue(received_raw).intValue();
        } catch (final ClassCastException e) {
            throw new UnknownException(e, received_raw);
        }
    }

    /**
     * Gets the names of the nodes in the Scalaris VM of the current connection.
     *
     * @return the names of the nodes
     *
     * @throws ConnectionException
     *             if the connection is not active or a communication error
     *             occurs or an exit signal was received or the remote node
     *             sends a message containing an invalid cookie
     * @throws UnknownException
     *             if any other error occurs
     */
    public List<String> getNodes()
            throws ConnectionException, UnknownException {
        final OtpErlangObject received_raw = connection.doRPC("api_vm", "get_nodes",
                    new OtpErlangObject[] {});
        try {
            return new ErlangValue(received_raw).stringListValue();
        } catch (final ClassCastException e) {
            throw new UnknownException(e, received_raw);
        }
    }

    /**
     * Plain old data object for results of {@link ScalarisVM#addNodes(int)}.
     *
     * @author Nico Kruber, kruber@zib.de
     * @version 3.6
     * @since 3.6
     */
    public static class AddNodesResult {
        /**
         * Names of successfully added nodes.
         */
        public final List<String> successful;
        /**
         * Error string for nodes that could not be started (empty if all nodes
         * have been started successfully).
         */
        public final String errors;

        protected AddNodesResult(final List<String> successful, final String errors) {
            this.successful = successful;
            this.errors = errors;
        }
    }

    /**
     * Adds the given number of nodes to the Scalaris VM of the current connection.
     *
     * @param number
     *            number of nodes to add
     *
     * @return result of the operation
     *
     * @throws ConnectionException
     *             if the connection is not active or a communication error
     *             occurs or an exit signal was received or the remote node
     *             sends a message containing an invalid cookie
     * @throws UnknownException
     *             if any other error occurs
     */
    public AddNodesResult addNodes(final int number)
            throws ConnectionException, UnknownException {
        final OtpErlangObject received_raw = connection.doRPC("api_vm", "add_nodes",
                    new OtpErlangObject[] { new OtpErlangInt(number) });
        try {
            final OtpErlangTuple received = (OtpErlangTuple) received_raw;
            final List<String> successful = new ErlangValue(received.elementAt(0)).stringListValue();
            final OtpErlangList errors = ErlangValue.otpObjectToOtpList(received.elementAt(1));
            String error_str;
            if (errors.arity() == 0) {
                error_str = "";
            } else {
                error_str = errors.toString();
            }
            return new AddNodesResult(successful, error_str);
        } catch (final ClassCastException e) {
            throw new UnknownException(e, received_raw);
        }
    }

    /**
     * Shuts down the given node (graceful leave) inside the Scalaris VM of the
     * current connection.
     *
     * @param name
     *            the name of a node
     *
     * @return <tt>true</tt> if the node was shut down,
     *         <tt>false</tt> if the node was not found
     *
     * @throws ConnectionException
     *             if the connection is not active or a communication error
     *             occurs or an exit signal was received or the remote node
     *             sends a message containing an invalid cookie
     * @throws UnknownException
     *             if any other error occurs
     */
    public boolean shutdownNode(final String name)
            throws ConnectionException, UnknownException {
        final OtpErlangObject received_raw = connection.doRPC("api_vm", "shutdown_node",
                    new OtpErlangObject[] { new OtpErlangString(name) });
        if (received_raw.equals(CommonErlangObjects.okAtom)) {
            return true;
        } else if (received_raw.equals(CommonErlangObjects.notFoundAtom)) {
            return false;
        }
        throw new UnknownException(received_raw);
    }

    /**
     * Kills the given node inside the Scalaris VM of the current connection.
     *
     * @param name
     *            the name of a node
     *
     * @return <tt>true</tt> if the node was shut down,
     *         <tt>false</tt> if the node was not found
     *
     * @throws ConnectionException
     *             if the connection is not active or a communication error
     *             occurs or an exit signal was received or the remote node
     *             sends a message containing an invalid cookie
     * @throws UnknownException
     *             if any other error occurs
     */
    public boolean killNode(final String name)
            throws ConnectionException, UnknownException {
        final OtpErlangObject received_raw = connection.doRPC("api_vm", "kill_node",
                    new OtpErlangObject[] { new OtpErlangString(name) });
        if (received_raw.equals(CommonErlangObjects.okAtom)) {
            return true;
        } else if (received_raw.equals(CommonErlangObjects.notFoundAtom)) {
            return false;
        }
        throw new UnknownException(received_raw);
    }

    /**
     * Plain old data object for results of
     * {@link ScalarisVM#shutdownNodes(int)}, {@link ScalarisVM#shutdownNodesByName(List)},
     * {@link ScalarisVM#killNodes(int)} and {@link ScalarisVM#killNodes(List)}.
     *
     * @author Nico Kruber, kruber@zib.de
     * @version 3.6
     * @since 3.6
     */
    public static class DeleteNodesByNameResult {
        /**
         * Names of successfully deleted nodes.
         */
        public final List<String> successful;
        /**
         * Nodes which do not exist (anymore) in the VM.
         */
        public final List<String> notFound;

        protected DeleteNodesByNameResult(final List<String> successful, final List<String> notFound) {
            this.successful = successful;
            this.notFound = notFound;
        }
    }

    /**
     * Shuts down the given number of nodes (graceful leave) inside the
     * Scalaris VM of the current connection.
     *
     * @param number
     *            number of nodes to shut down
     *
     * @return result of the operation
     *
     * @throws ConnectionException
     *             if the connection is not active or a communication error
     *             occurs or an exit signal was received or the remote node
     *             sends a message containing an invalid cookie
     * @throws UnknownException
     *             if any other error occurs
     */
    public List<String> shutdownNodes(final int number)
            throws ConnectionException, UnknownException {
        final OtpErlangObject received_raw = connection.doRPC("api_vm", "shutdown_nodes",
                    new OtpErlangObject[] { new OtpErlangInt(number) });
        return makeDeleteResult(received_raw);
    }

    /**
     * Shuts down the given nodes (graceful leave) inside the Scalaris VM of the
     * current connection.
     *
     * @param names
     *            names of the nodes to shut down
     *
     * @return result of the operation
     *
     * @throws ConnectionException
     *             if the connection is not active or a communication error
     *             occurs or an exit signal was received or the remote node
     *             sends a message containing an invalid cookie
     * @throws UnknownException
     *             if any other error occurs
     */
    public DeleteNodesByNameResult shutdownNodesByName(final List<String> names)
            throws ConnectionException, UnknownException {
        final OtpErlangObject received_raw = connection.doRPC("api_vm", "shutdown_nodes_by_name",
                    new OtpErlangObject[] { ErlangValue.convertToErlang(names) });
        return makeDeleteByNameResult(received_raw);
    }

    /**
     * Kills the given number of nodes inside the Scalaris VM of the current
     * connection.
     *
     * @param number
     *            number of nodes to kill
     *
     * @return result of the operation
     *
     * @throws ConnectionException
     *             if the connection is not active or a communication error
     *             occurs or an exit signal was received or the remote node
     *             sends a message containing an invalid cookie
     * @throws UnknownException
     *             if any other error occurs
     */
    public List<String> killNodes(final int number)
            throws ConnectionException, UnknownException {
        final OtpErlangObject received_raw = connection.doRPC("api_vm", "kill_nodes",
                    new OtpErlangObject[] { new OtpErlangInt(number) });
        return makeDeleteResult(received_raw);
    }

    /**
     * Kills the given nodes inside the Scalaris VM of the current connection.
     *
     * @param names
     *            names of the nodes to kill
     *
     * @return result of the operation
     *
     * @throws ConnectionException
     *             if the connection is not active or a communication error
     *             occurs or an exit signal was received or the remote node
     *             sends a message containing an invalid cookie
     * @throws UnknownException
     *             if any other error occurs
     */
    public DeleteNodesByNameResult killNodes(final List<String> names)
            throws ConnectionException, UnknownException {
        final OtpErlangObject received_raw = connection.doRPC("api_vm", "kill_nodes_by_name",
                    new OtpErlangObject[] { ErlangValue.convertToErlang(names) });
        return makeDeleteByNameResult(received_raw);
    }

    /**
     * Transforms the given result from a "delete nodes"-operation into a
     * {@link DeleteResult}.
     *
     * @param received_raw
     *            raw erlang result
     *
     * @return {@link DeleteResult} object
     *
     * @throws UnknownException
     *             if an error occurs during transformation
     */
    private final List<String> makeDeleteResult(
            final OtpErlangObject received_raw) throws UnknownException {
        try {
            return new ErlangValue(received_raw).stringListValue();
        } catch (final ClassCastException e) {
            throw new UnknownException(e, received_raw);
        }
    }

    /**
     * Transforms the given result from a "delete nodes by name"-operation into
     * a {@link DeleteNodesByNameResult}.
     *
     * @param received_raw
     *            raw erlang result
     *
     * @return {@link DeleteResult} object
     *
     * @throws UnknownException
     *             if an error occurs during transformation
     */
    private final DeleteNodesByNameResult makeDeleteByNameResult(
            final OtpErlangObject received_raw) throws UnknownException {
        try {
            final OtpErlangTuple received = (OtpErlangTuple) received_raw;
            final List<String> successful = new ErlangValue(received.elementAt(0)).stringListValue();
            final List<String> not_found = new ErlangValue(received.elementAt(1)).stringListValue();
            return new DeleteNodesByNameResult(successful, not_found);
        } catch (final ClassCastException e) {
            throw new UnknownException(e, received_raw);
        }
    }

    /**
     * Retrieves additional nodes from the Scalaris VM of the current
     * connection for use by {@link ConnectionFactory#addNode(String)}.
     *
     * @param max
     *            maximum number of nodes to return (> 0)
     *
     * @return a list of nodes (may be empty!)
     *
     * @throws ConnectionException
     *             if the connection is not active or a communication error
     *             occurs or an exit signal was received or the remote node
     *             sends a message containing an invalid cookie
     * @throws UnknownException
     *             if any other error occurs
     */
    public List<String> getOtherVMs(final int max)
            throws ConnectionException, UnknownException {
        if (max <= 0) {
            throw new IllegalArgumentException("max must be an integer > 0");
        }
        final OtpErlangObject received_raw = connection.doRPC("api_vm", "get_other_vms",
                    new OtpErlangObject[] { ErlangValue.convertToErlang(max) });
        try {
            final OtpErlangList list = ErlangValue.otpObjectToOtpList(received_raw);
            final ArrayList<String> result = new ArrayList<String>(list.arity());
            for (int i = 0; i < list.arity(); ++i) {
                final OtpErlangTuple connTuple = ((OtpErlangTuple) list.elementAt(i));
                if (connTuple.arity() != 4) {
                    throw new UnknownException(received_raw);
                }
                final OtpErlangAtom name_otp = (OtpErlangAtom) connTuple.elementAt(i);
                result.add(name_otp.atomValue());
            }
            return result;
        } catch (final ClassCastException e) {
            throw new UnknownException(e, received_raw);
        }
    }

    /**
     * Tells the Scalaris VM of the current connection to shut down gracefully.
     *
     * @throws ConnectionException
     *             if the connection is not active or a communication error
     *             occurs or an exit signal was received or the remote node
     *             sends a message containing an invalid cookie
     * @throws UnknownException
     *             if any other error occurs
     */
    public void shutdownVM() throws ConnectionException {
        connection.sendRPC("api_vm", "shutdown_vm", new OtpErlangObject[] {});
    }

    /**
     * Kills the Scalaris VM of the current connection.
     *
     * @throws ConnectionException
     *             if the connection is not active or a communication error
     *             occurs or an exit signal was received or the remote node
     *             sends a message containing an invalid cookie
     * @throws UnknownException
     *             if any other error occurs
     */
    public void killVM() throws ConnectionException {
        connection.sendRPC("api_vm", "kill_vm", new OtpErlangObject[] {});
    }

    /**
     * Closes the transaction's connection to a scalaris node.
     *
     * Note: Subsequent calls to the other methods will throw
     * {@link ConnectionException}s!
     */
    public void closeConnection() {
        connection.close();
    }
}
TOP

Related Classes of de.zib.scalaris.ScalarisVM$GetInfoResult

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.
y>