/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF 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.apache.ignite.spi;

import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
import javax.management.JMException;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteException;
import org.apache.ignite.IgniteLogger;
import org.apache.ignite.cluster.ClusterNode;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.events.DiscoveryEvent;
import org.apache.ignite.events.Event;
import org.apache.ignite.internal.IgniteEx;
import org.apache.ignite.internal.IgniteKernal;
import org.apache.ignite.internal.IgniteNodeAttributes;
import org.apache.ignite.internal.managers.communication.GridMessageListener;
import org.apache.ignite.internal.managers.eventstorage.GridLocalEventListener;
import org.apache.ignite.internal.processors.timeout.GridSpiTimeoutObject;
import org.apache.ignite.internal.util.IgniteExceptionRegistry;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.internal.SB;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.lang.IgniteBiPredicate;
import org.apache.ignite.lang.IgniteFuture;
import org.apache.ignite.plugin.extensions.communication.Message;
import org.apache.ignite.plugin.extensions.communication.MessageFactory;
import org.apache.ignite.plugin.extensions.communication.MessageFormatter;
import org.apache.ignite.plugin.extensions.communication.MessageReader;
import org.apache.ignite.plugin.extensions.communication.MessageWriter;
import org.apache.ignite.plugin.security.SecuritySubject;
import org.apache.ignite.resources.IgniteInstanceResource;
import org.apache.ignite.resources.LoggerResource;
import org.apache.ignite.spi.discovery.DiscoveryDataBag;
import org.apache.ignite.spi.metric.ReadOnlyMetricRegistry;
import org.jetbrains.annotations.Nullable;

import static org.apache.ignite.IgniteSystemProperties.IGNITE_SKIP_CONFIGURATION_CONSISTENCY_CHECK;
import static org.apache.ignite.configuration.IgniteConfiguration.DFLT_FAILURE_DETECTION_TIMEOUT;
import static org.apache.ignite.events.EventType.EVT_NODE_JOINED;

/**
 * This class provides convenient adapter for SPI implementations.
 */
public abstract class IgniteSpiAdapter implements IgniteSpi {
    /** */
    private ObjectName spiMBean;

    /** SPI start timestamp. */
    private long startTstamp;

    /** */
    @LoggerResource
    protected IgniteLogger log;

    /** Ignite instance. */
    protected Ignite ignite;

    /** Ignite instance name. */
    protected String igniteInstanceName;

    /** SPI name. */
    private String name;

    /** Grid SPI context. */
    private volatile IgniteSpiContext spiCtx = new GridDummySpiContext(null, false, null);

    /** Discovery listener. */
    private GridLocalEventListener paramsLsnr;

    /** Local node. */
    private ClusterNode locNode;

    /** Failure detection timeout usage switch. */
    private boolean failureDetectionTimeoutEnabled = true;

    /**
     * Failure detection timeout for client nodes. Initialized with the value of
     * {@link IgniteConfiguration#getClientFailureDetectionTimeout()}.
     */
    private long clientFailureDetectionTimeout;

    /**
     * Failure detection timeout. Initialized with the value of
     * {@link IgniteConfiguration#getFailureDetectionTimeout()}.
     */
    private long failureDetectionTimeout;

    /** Start flag to deny repeating start attempts. */
    private final AtomicBoolean startedFlag = new AtomicBoolean();

    /**
     * Creates new adapter and initializes it from the current (this) class.
     * SPI name will be initialized to the simple name of the class
     * (see {@link Class#getSimpleName()}).
     */
    protected IgniteSpiAdapter() {
        name = U.getSimpleName(getClass());
    }

    /**
     * Starts startup stopwatch.
     */
    protected void startStopwatch() {
        startTstamp = U.currentTimeMillis();
    }

    /**
     * This method is called by built-in managers implementation to avoid
     * repeating SPI start attempts.
     */
    public final void onBeforeStart() {
        if (!startedFlag.compareAndSet(false, true))
            throw new IllegalStateException("SPI has already been started " +
                "(always create new configuration instance for each starting Ignite instances) " +
                "[spi=" + this + ']');
    }

    /**
     * Checks if {@link #onBeforeStart()} has been called on this SPI instance.
     *
     * @return {@code True} if {@link #onBeforeStart()} has already been called.
     */
    public final boolean started() {
        return startedFlag.get();
    }

    /**
     * @return Local node.
     */
    protected ClusterNode getLocalNode() {
        if (locNode != null)
            return locNode;

        locNode = getSpiContext().localNode();

        return locNode;
    }

    /** {@inheritDoc} */
    @Override public String getName() {
        return name;
    }

    /**
     * Gets ignite instance.
     *
     * @return Ignite instance.
     */
    public Ignite ignite() {
        return ignite;
    }

    /**
     * Sets SPI name.
     *
     * @param name SPI name.
     * @return {@code this} for chaining.
     */
    @IgniteSpiConfiguration(optional = true)
    public IgniteSpiAdapter setName(String name) {
        this.name = name;

        return this;
    }

    /** {@inheritDoc} */
    @Override public final void onContextInitialized(final IgniteSpiContext spiCtx) throws IgniteSpiException {
        assert spiCtx != null;

        this.spiCtx = spiCtx;

        if (!Boolean.getBoolean(IGNITE_SKIP_CONFIGURATION_CONSISTENCY_CHECK)) {
            spiCtx.addLocalEventListener(paramsLsnr = new GridLocalEventListener() {
                @Override public void onEvent(Event evt) {
                    assert evt instanceof DiscoveryEvent : "Invalid event [expected=" + EVT_NODE_JOINED +
                        ", actual=" + evt.type() + ", evt=" + evt + ']';

                    ClusterNode node = spiCtx.node(((DiscoveryEvent)evt).eventNode().id());

                    if (node != null)
                        try {
                            checkConfigurationConsistency(spiCtx, node, false);
                            checkConfigurationConsistency0(spiCtx, node, false);
                        }
                        catch (IgniteSpiException e) {
                            U.error(log, "Spi consistency check failed [node=" + node.id() + ", spi=" + getName() + ']',
                                e);
                        }
                }
            }, EVT_NODE_JOINED);

            final Collection<ClusterNode> remotes = F.concat(false, spiCtx.remoteNodes(), spiCtx.remoteDaemonNodes());

            for (ClusterNode node : remotes) {
                checkConfigurationConsistency(spiCtx, node, true);
                checkConfigurationConsistency0(spiCtx, node, true);
            }
        }

        onContextInitialized0(spiCtx);
    }

    /**
     * Method to be called in the end of onContextInitialized method.
     *
     * @param spiCtx SPI context.
     * @throws IgniteSpiException In case of errors.
     */
    protected void onContextInitialized0(final IgniteSpiContext spiCtx) throws IgniteSpiException {
        // No-op.
    }

    /** {@inheritDoc} */
    @Override public final void onContextDestroyed() {
        onContextDestroyed0();

        if (spiCtx != null && paramsLsnr != null)
            spiCtx.removeLocalEventListener(paramsLsnr);

        ClusterNode locNode = spiCtx == null ? null : spiCtx.localNode();

        // Set dummy no-op context.
        spiCtx = new GridDummySpiContext(locNode, true, spiCtx);
    }

    /** {@inheritDoc} */
    @Override public void onClientDisconnected(IgniteFuture<?> reconnectFut) {
        // No-op.
    }

    /** {@inheritDoc} */
    @Override public void onClientReconnected(boolean clusterRestarted) {
        // No-op.
    }

    /**
     * Inject ignite instance.
     *
     * @param ignite Ignite instance.
     */
    @IgniteInstanceResource
    protected void injectResources(Ignite ignite) {
        this.ignite = ignite;

        if (ignite != null)
            igniteInstanceName = ignite.name();
    }

    /**
     * Method to be called in the beginning of onContextDestroyed() method.
     */
    protected void onContextDestroyed0() {
        // No-op.
    }

    /**
     * This method returns SPI internal instances that need to be injected as well.
     * Usually these will be instances provided to SPI externally by user, e.g. during
     * SPI configuration.
     *
     * @return Internal SPI objects that also need to be injected.
     */
    public Collection<Object> injectables() {
        return Collections.emptyList();
    }

    /**
     * Gets SPI context.
     *
     * @return SPI context.
     */
    public IgniteSpiContext getSpiContext() {
        return spiCtx;
    }

    /**
     * Gets Exception registry.
     *
     * @return Exception registry.
     */
    public IgniteExceptionRegistry getExceptionRegistry() {
        return IgniteExceptionRegistry.get();
    }

    /** {@inheritDoc} */
    @Override public Map<String, Object> getNodeAttributes() throws IgniteSpiException {
        return Collections.emptyMap();
    }

    /**
     * Throws exception with uniform error message if given parameter's assertion condition
     * is {@code false}.
     *
     * @param cond Assertion condition to check.
     * @param condDesc Description of failed condition. Note that this description should include
     *      JavaBean name of the property (<b>not</b> a variable name) as well condition in
     *      Java syntax like, for example:
     *      <pre name="code" class="java">
     *      ...
     *      assertParameter(dirPath != null, "dirPath != null");
     *      ...
     *      </pre>
     *      Note that in case when variable name is the same as JavaBean property you
     *      can just copy Java condition expression into description as a string.
     * @throws IgniteSpiException Thrown if given condition is {@code false}
     */
    protected final void assertParameter(boolean cond, String condDesc) throws IgniteSpiException {
        if (!cond)
            throw new IgniteSpiException("SPI parameter failed condition check: " + condDesc);
    }

    /**
     * Gets uniformly formatted message for SPI start.
     *
     * @return Uniformly formatted message for SPI start.
     */
    protected final String startInfo() {
        return "SPI started ok [startMs=" + startTstamp + ", spiMBean=" + spiMBean + ']';
    }

    /**
     * Gets SPI startup time.
     * @return Time in millis.
     */
    final long getStartTstamp() {
        return startTstamp;
    }

    /**
     * Gets uniformly format message for SPI stop.
     *
     * @return Uniformly format message for SPI stop.
     */
    protected final String stopInfo() {
        return "SPI stopped ok.";
    }

    /**
     * Gets uniformed string for configuration parameter.
     *
     * @param name Parameter name.
     * @param val Parameter value.
     * @return Uniformed string for configuration parameter.
     */
    protected final String configInfo(String name, Object val) {
        assert name != null;

        return "Using parameter [" + name + '=' + val + ']';
    }

    /**
     * @param msg Error message.
     * @param locVal Local node value.
     * @return Error text.
     */
    private static String format(String msg, Object locVal) {
        return msg + U.nl() +
            ">>> => Local node:  " + locVal + U.nl();
    }

    /**
     * @param msg Error message.
     * @param locVal Local node value.
     * @param rmtVal Remote node value.
     * @return Error text.
     */
    private static String format(String msg, Object locVal, Object rmtVal) {
        return msg + U.nl() +
            ">>> => Local node:  " + locVal + U.nl() +
            ">>> => Remote node: " + rmtVal + U.nl();
    }

    /**
     * Registers SPI MBean. Note that SPI can only register one MBean.
     *
     * @param igniteInstanceName Ignite instance name. If null, then name will be empty.
     * @param impl MBean implementation.
     * @param mbeanItf MBean interface (if {@code null}, then standard JMX
     *    naming conventions are used.
     * @param <T> Type of the MBean
     * @throws IgniteSpiException If registration failed.
     */
    protected final <T extends IgniteSpiManagementMBean> void registerMBean(String igniteInstanceName, T impl, Class<T> mbeanItf
       ) throws IgniteSpiException {
        if (ignite == null || U.IGNITE_MBEANS_DISABLED)
            return;

        MBeanServer jmx = ignite.configuration().getMBeanServer();

        assert mbeanItf == null || mbeanItf.isInterface();
        assert jmx != null;

        try {
            spiMBean = U.registerMBean(jmx, igniteInstanceName, "SPIs", getName(), impl, mbeanItf);

            if (log.isDebugEnabled())
                log.debug("Registered SPI MBean: " + spiMBean);
        }
        catch (JMException e) {
            throw new IgniteSpiException("Failed to register SPI MBean: " + spiMBean, e);
        }
    }

    /**
     * Unregisters MBean.
     *
     * @throws IgniteSpiException If bean could not be unregistered.
     */
    protected final void unregisterMBean() throws IgniteSpiException {
        // Unregister SPI MBean.
        if (spiMBean != null && ignite != null) {
            assert !U.IGNITE_MBEANS_DISABLED;

            MBeanServer jmx = ignite.configuration().getMBeanServer();

            assert jmx != null;

            try {
                jmx.unregisterMBean(spiMBean);

                if (log.isDebugEnabled())
                    log.debug("Unregistered SPI MBean: " + spiMBean);
            }
            catch (JMException e) {
                throw new IgniteSpiException("Failed to unregister SPI MBean: " + spiMBean, e);
            }
        }
    }

    /**
     * @return {@code True} if node is stopping.
     */
    protected final boolean isNodeStopping() {
        return spiCtx.isStopping();
    }

    /**
     * @return {@code true} if this check is optional.
     */
    private boolean checkOptional() {
        IgniteSpiConsistencyChecked ann = U.getAnnotation(getClass(), IgniteSpiConsistencyChecked.class);

        return ann != null && ann.optional();
    }

    /**
     * @return {@code true} if this check is enabled.
     */
    private boolean checkEnabled() {
        return U.getAnnotation(getClass(), IgniteSpiConsistencyChecked.class) != null;
    }

    /**
     * @return {@code true} if client cluster nodes should be checked.
     */
    private boolean checkClient() {
        IgniteSpiConsistencyChecked ann = U.getAnnotation(getClass(), IgniteSpiConsistencyChecked.class);

        return ann != null && ann.checkClient();
    }

    /**
     * Method which is called in the end of checkConfigurationConsistency() method. May be overriden in SPIs.
     *
     * @param spiCtx SPI context.
     * @param node Remote node.
     * @param starting If this node is starting or not.
     * @throws IgniteSpiException in case of errors.
     */
    protected void checkConfigurationConsistency0(IgniteSpiContext spiCtx, ClusterNode node, boolean starting)
        throws IgniteSpiException {
        // No-op.
    }

    /**
     * Checks remote node SPI configuration and prints warnings if necessary.
     *
     * @param spiCtx SPI context.
     * @param node Remote node.
     * @param starting Flag indicating whether this method is called during SPI start or not.
     * @throws IgniteSpiException If check fatally failed.
     */
    @SuppressWarnings("IfMayBeConditional")
    private void checkConfigurationConsistency(IgniteSpiContext spiCtx, ClusterNode node, boolean starting)
        throws IgniteSpiException {
        assert spiCtx != null;
        assert node != null;

        /*
         * Optional SPI means that we should not print warning if SPIs are different but
         * still need to compare attributes if SPIs are the same.
         */
        boolean optional = checkOptional();
        boolean enabled = checkEnabled();
        boolean checkClient = checkClient();

        if (!enabled)
            return;

        if (!checkClient && (getLocalNode().isClient() || node.isClient()))
            return;

        String clsAttr = createSpiAttributeName(IgniteNodeAttributes.ATTR_SPI_CLASS);

        String name = getName();

        SB sb = new SB();

        /*
         * If there are any attributes do compare class and version
         * (do not print warning for the optional SPIs).
         */

        /* Check SPI class and version. */
        String locCls = spiCtx.localNode().attribute(clsAttr);
        String rmtCls = node.attribute(clsAttr);

        assert locCls != null : "Local SPI class name attribute not found: " + clsAttr;

        boolean isSpiConsistent = false;

        String tipStr = " (fix configuration or set " +
            "-D" + IGNITE_SKIP_CONFIGURATION_CONSISTENCY_CHECK + "=true system property)";

        if (rmtCls == null) {
            if (!optional && starting)
                throw new IgniteSpiException("Remote SPI with the same name is not configured" + tipStr +
                    " [name=" + name + ", loc=" + locCls + ", locNode=" + spiCtx.localNode() + ", rmt=" + rmtCls +
                    ", rmtNode=" + node + ']');

            sb.a(format(">>> Remote SPI with the same name is not configured: " + name, locCls));
        }
        else if (!locCls.equals(rmtCls)) {
            if (!optional && starting)
                throw new IgniteSpiException("Remote SPI with the same name is of different type" + tipStr +
                    " [name=" + name + ", loc=" + locCls + ", rmt=" + rmtCls + ']');

            sb.a(format(">>> Remote SPI with the same name is of different type: " + name, locCls, rmtCls));
        }
        else
            isSpiConsistent = true;

        // It makes no sense to compare inconsistent SPIs attributes.
        if (!optional && isSpiConsistent) {
            List<String> attrs = getConsistentAttributeNames();

            // Process all SPI specific attributes.
            for (String attr : attrs) {
                // Ignore class and version attributes processed above.
                if (!attr.equals(clsAttr)) {
                    // This check is considered as optional if no attributes
                    Object rmtVal = node.attribute(attr);
                    Object locVal = spiCtx.localNode().attribute(attr);

                    if (locVal == null && rmtVal == null)
                        continue;

                    if (locVal == null || rmtVal == null || !locVal.equals(rmtVal))
                        sb.a(format(">>> Remote node has different " + getName() + " SPI attribute " +
                            attr, locVal, rmtVal));
                }
            }
        }

        if (sb.length() > 0) {
            String msg;

            if (starting)
                msg = U.nl() + U.nl() +
                    ">>> +--------------------------------------------------------------------+" + U.nl() +
                    ">>> + Courtesy notice that starting node has inconsistent configuration. +" + U.nl() +
                    ">>> + Ignore this message if you are sure that this is done on purpose.  +" + U.nl() +
                    ">>> +--------------------------------------------------------------------+" + U.nl() +
                    ">>> Remote Node ID: " + node.id().toString().toUpperCase() + U.nl() + sb;
            else
                msg = U.nl() + U.nl() +
                    ">>> +-------------------------------------------------------------------+" + U.nl() +
                    ">>> + Courtesy notice that joining node has inconsistent configuration. +" + U.nl() +
                    ">>> + Ignore this message if you are sure that this is done on purpose. +" + U.nl() +
                    ">>> +-------------------------------------------------------------------+" + U.nl() +
                    ">>> Remote Node ID: " + node.id().toString().toUpperCase() + U.nl() + sb;

            U.courtesy(log, msg);
        }
    }

    /**
     * Returns back a list of attributes that should be consistent
     * for this SPI. Consistency means that remote node has to
     * have the same attribute with the same value.
     *
     * @return List or attribute names.
     */
    protected List<String> getConsistentAttributeNames() {
        return Collections.emptyList();
    }

    /**
     * Creates new name for the given attribute. Name contains
     * SPI name prefix.
     *
     * @param attrName SPI attribute name.
     * @return New name with SPI name prefix.
     */
    protected String createSpiAttributeName(String attrName) {
        return U.spiAttribute(this, attrName);
    }

    /**
     * @param obj Timeout object.
     * @see IgniteSpiContext#addTimeoutObject(IgniteSpiTimeoutObject)
     */
    protected void addTimeoutObject(IgniteSpiTimeoutObject obj) {
        spiCtx.addTimeoutObject(obj);
    }

    /**
     * @param obj Timeout object.
     * @see IgniteSpiContext#removeTimeoutObject(IgniteSpiTimeoutObject)
     */
    protected void removeTimeoutObject(IgniteSpiTimeoutObject obj) {
        spiCtx.removeTimeoutObject(obj);
    }

    /**
     * Initiates and checks failure detection timeout value.
     */
    protected void initFailureDetectionTimeout() {
        if (failureDetectionTimeoutEnabled) {
            failureDetectionTimeout = ignite.configuration().getFailureDetectionTimeout();

            if (failureDetectionTimeout <= 0)
                throw new IgniteSpiException("Invalid failure detection timeout value: " + failureDetectionTimeout);
            else if (failureDetectionTimeout <= 10)
                // Because U.currentTimeInMillis() is updated once in 10 milliseconds.
                log.warning("Failure detection timeout is too low, it may lead to unpredictable behaviour " +
                    "[failureDetectionTimeout=" + failureDetectionTimeout + ']');
            else if (failureDetectionTimeout <= ignite.configuration().getMetricsUpdateFrequency())
                log.warning("'IgniteConfiguration.failureDetectionTimeout' should be greater then " +
                    "'IgniteConfiguration.metricsUpdateFrequency' to prevent unnecessary status checking.");
        }
        // Intentionally compare references using '!=' below
        else if (ignite.configuration().getFailureDetectionTimeout() != DFLT_FAILURE_DETECTION_TIMEOUT)
            log.warning("Failure detection timeout will be ignored (one of SPI parameters has been set explicitly)");

        clientFailureDetectionTimeout = ignite.configuration().getClientFailureDetectionTimeout();

        if (clientFailureDetectionTimeout <= 0)
            throw new IgniteSpiException("Invalid client failure detection timeout value: " +
                clientFailureDetectionTimeout);
        else if (clientFailureDetectionTimeout <= 10)
            // Because U.currentTimeInMillis() is updated once in 10 milliseconds.
            log.warning("Client failure detection timeout is too low, it may lead to unpredictable behaviour " +
                "[clientFailureDetectionTimeout=" + clientFailureDetectionTimeout + ']');

        if (clientFailureDetectionTimeout < ignite.configuration().getMetricsUpdateFrequency())
            throw new IgniteSpiException("Inconsistent configuration " +
                "('IgniteConfiguration.clientFailureDetectionTimeout' must be greater or equal to " +
                "'IgniteConfiguration.metricsUpdateFrequency').");
    }

    /**
     * Enables or disables failure detection timeout.
     *
     * @param enabled {@code true} if enable, {@code false} otherwise.
     */
    public void failureDetectionTimeoutEnabled(boolean enabled) {
        failureDetectionTimeoutEnabled = enabled;
    }

    /**
     * Checks whether failure detection timeout is enabled for this {@link IgniteSpi}.
     *
     * @return {@code true} if enabled, {@code false} otherwise.
     */
    public boolean failureDetectionTimeoutEnabled() {
        return failureDetectionTimeoutEnabled;
    }

    /**
     * Returns client failure detection timeout set to use for network related operations.
     *
     * @return client failure detection timeout in milliseconds or {@code 0} if the timeout is disabled.
     */
    public long clientFailureDetectionTimeout() {
        return clientFailureDetectionTimeout;
    }

    /**
     * Returns failure detection timeout set to use for network related operations.
     *
     * @return failure detection timeout in milliseconds or {@code 0} if the timeout is disabled.
     */
    public long failureDetectionTimeout() {
        return failureDetectionTimeout;
    }

    /**
     * Temporarily SPI context.
     */
    private class GridDummySpiContext implements IgniteSpiContext {
        /** */
        private final ClusterNode locNode;

        /** */
        private final boolean stopping;

        /** */
        private final MessageFactory msgFactory;

        /** */
        private final MessageFormatter msgFormatter;

        /**
         * Create temp SPI context.
         *
         * @param locNode Local node.
         * @param stopping Node stopping flag.
         * @param spiCtx SPI context.
         */
        GridDummySpiContext(ClusterNode locNode, boolean stopping, @Nullable IgniteSpiContext spiCtx) {
            this.locNode = locNode;
            this.stopping = stopping;

            MessageFactory msgFactory0 = spiCtx != null ? spiCtx.messageFactory() : null;
            MessageFormatter msgFormatter0 = spiCtx != null ? spiCtx.messageFormatter() : null;

            if (msgFactory0 == null) {
                msgFactory0 = new MessageFactory() {
                    @Nullable @Override public Message create(short type) {
                        throw new IgniteException("Failed to read message, node is not started.");
                    }
                };
            }

            if (msgFormatter0 == null) {
                msgFormatter0 = new MessageFormatter() {
                    @Override public MessageWriter writer(UUID rmtNodeId) {
                        throw new IgniteException("Failed to write message, node is not started.");
                    }

                    @Override public MessageReader reader(UUID rmtNodeId, MessageFactory msgFactory) {
                        throw new IgniteException("Failed to read message, node is not started.");
                    }
                };
            }

            this.msgFactory = msgFactory0;
            this.msgFormatter = msgFormatter0;
        }

        /** {@inheritDoc} */
        @Override public void addLocalEventListener(GridLocalEventListener lsnr, int... types) {
            /* No-op. */
        }

        /** {@inheritDoc} */
        @Override public void addMessageListener(GridMessageListener lsnr, String topic) {
            /* No-op. */
        }

        /** {@inheritDoc} */
        @Override public void addLocalMessageListener(Object topic, IgniteBiPredicate<UUID, ?> p) {
            /* No-op. */
        }

        /** {@inheritDoc} */
        @Override public void recordEvent(Event evt) {
            /* No-op. */
        }

        /** {@inheritDoc} */
        @Override public void registerPort(int port, IgnitePortProtocol proto) {
            /* No-op. */
        }

        /** {@inheritDoc} */
        @Override public void deregisterPort(int port, IgnitePortProtocol proto) {
            /* No-op. */
        }

        /** {@inheritDoc} */
        @Override public void deregisterPorts() {
            /* No-op. */
        }

        /** {@inheritDoc} */
        @Override public <K, V> V get(String cacheName, K key) {
            return null;
        }

        /** {@inheritDoc} */
        @Override public <K, V> V put(String cacheName, K key, V val, long ttl) {
            return null;
        }

        /** {@inheritDoc} */
        @Override public <K, V> V putIfAbsent(String cacheName, K key, V val, long ttl) {
            return null;
        }

        /** {@inheritDoc} */
        @Override public <K, V> V remove(String cacheName, K key) {
            return null;
        }

        /** {@inheritDoc} */
        @Override public <K> boolean containsKey(String cacheName, K key) {
            return false;
        }

        /** {@inheritDoc} */
        @Override public int partition(String cacheName, Object key) {
            return -1;
        }

        /** {@inheritDoc} */
        @Override public Collection<ClusterNode> nodes() {
            return locNode == null ? Collections.emptyList() : Collections.singletonList(locNode);
        }

        /** {@inheritDoc} */
        @Override public ClusterNode localNode() {
            return locNode;
        }

        /** {@inheritDoc} */
        @Override public Collection<ClusterNode> remoteDaemonNodes() {
            return Collections.emptyList();
        }

        /** {@inheritDoc} */
        @Nullable @Override public ClusterNode node(UUID nodeId) {
            return null;
        }

        /** {@inheritDoc} */
        @Override public Collection<ClusterNode> remoteNodes() {
            return Collections.emptyList();
        }

        /** {@inheritDoc} */
        @Override public boolean pingNode(UUID nodeId) {
            return locNode != null && nodeId.equals(locNode.id());
        }

        /** {@inheritDoc} */
        @Override public boolean removeLocalEventListener(GridLocalEventListener lsnr) {
            return false;
        }

        /** {@inheritDoc} */
        @Override public boolean isEventRecordable(int... types) {
            return true;
        }

        /** {@inheritDoc} */
        @Override public void removeLocalMessageListener(Object topic, IgniteBiPredicate<UUID, ?> p) {
             /* No-op. */
        }

        /** {@inheritDoc} */
        @Override public boolean removeMessageListener(GridMessageListener lsnr, String topic) {
            return false;
        }

        /** {@inheritDoc} */
        @Override public void send(ClusterNode node, Serializable msg, String topic) {
            /* No-op. */
        }

        /** {@inheritDoc} */
        @Nullable @Override public IgniteNodeValidationResult validateNode(ClusterNode node) {
            return null;
        }

        /** {@inheritDoc} */
        @Nullable @Override public IgniteNodeValidationResult validateNode(ClusterNode node, DiscoveryDataBag discoData) {
            return null;
        }

        /** {@inheritDoc} */
        @Override public Collection<SecuritySubject> authenticatedSubjects() {
            return Collections.emptyList();
        }

        /** {@inheritDoc} */
        @Override public SecuritySubject authenticatedSubject(UUID subjId) {
            return null;
        }

        /** {@inheritDoc} */
        @Override public MessageFormatter messageFormatter() {
            return msgFormatter;
        }

        /** {@inheritDoc} */
        @Override public MessageFactory messageFactory() {
            return msgFactory;
        }

        /** {@inheritDoc} */
        @Override public boolean isStopping() {
            return stopping;
        }

        /** {@inheritDoc} */
        @Override public boolean tryFailNode(UUID nodeId, @Nullable String warning) {
            return false;
        }

        /** {@inheritDoc} */
        @Override public void failNode(UUID nodeId, @Nullable String warning) {
            // No-op.
        }

        /** {@inheritDoc} */
        @Override public void addTimeoutObject(IgniteSpiTimeoutObject obj) {
            Ignite ignite0 = ignite;

            if (!(ignite0 instanceof IgniteKernal))
                throw new IgniteSpiException("Wrong Ignite instance is set: " + ignite0);

            ((IgniteEx)ignite0).context().timeout().addTimeoutObject(new GridSpiTimeoutObject(obj));
        }

        /** {@inheritDoc} */
        @Override public void removeTimeoutObject(IgniteSpiTimeoutObject obj) {
            Ignite ignite0 = ignite;

            if (!(ignite0 instanceof IgniteKernal))
                throw new IgniteSpiException("Wrong Ignite instance is set: " + ignite0);

            ((IgniteEx)ignite0).context().timeout().removeTimeoutObject(new GridSpiTimeoutObject(obj));
        }

        /** {@inheritDoc} */
        @Override public Map<String, Object> nodeAttributes() {
            return Collections.emptyMap();
        }

        /** {@inheritDoc} */
        @Override public boolean communicationFailureResolveSupported() {
            return false;
        }

        /** {@inheritDoc} */
        @Override public void resolveCommunicationFailure(ClusterNode node, Exception err) {
            throw new UnsupportedOperationException();
        }

        /** {@inheritDoc} */
        @Override public ReadOnlyMetricRegistry getOrCreateMetricRegistry(String name) {
            return null;
        }

        /** {@inheritDoc} */
        @Override public void removeMetricRegistry(String name) {
            // No-op.
        }

        /** {@inheritDoc} */
        @Override public Iterable<ReadOnlyMetricRegistry> metricRegistries() {
            return null;
        }

        /** {@inheritDoc} */
        @Override public void addMetricRegistryCreationListener(Consumer<ReadOnlyMetricRegistry> lsnr) {
            // No-op.
        }
    }
}
