You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by vo...@apache.org on 2015/02/02 11:29:19 UTC
[43/50] [abbrv] incubator-ignite git commit: GridNamedInstance ->
IgniteNamedInstance GridgainEx -> IgnitionEx
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/c5247ab3/modules/core/src/main/java/org/apache/ignite/internal/IgnitionEx.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgnitionEx.java b/modules/core/src/main/java/org/apache/ignite/internal/IgnitionEx.java
new file mode 100644
index 0000000..acab6d0
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/IgnitionEx.java
@@ -0,0 +1,2399 @@
+/*
+ * 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.internal;
+
+import org.apache.ignite.*;
+import org.apache.ignite.cache.*;
+import org.apache.ignite.cache.affinity.rendezvous.*;
+import org.apache.ignite.configuration.*;
+import org.apache.ignite.fs.*;
+import org.apache.ignite.internal.util.*;
+import org.apache.ignite.lang.*;
+import org.apache.ignite.lifecycle.*;
+import org.apache.ignite.logger.*;
+import org.apache.ignite.logger.java.*;
+import org.apache.ignite.marshaller.*;
+import org.apache.ignite.marshaller.jdk.*;
+import org.apache.ignite.marshaller.optimized.*;
+import org.apache.ignite.mxbean.*;
+import org.apache.ignite.spi.*;
+import org.apache.ignite.spi.authentication.*;
+import org.apache.ignite.spi.authentication.noop.*;
+import org.apache.ignite.spi.indexing.*;
+import org.apache.ignite.streamer.*;
+import org.apache.ignite.thread.*;
+import org.apache.ignite.internal.processors.resource.*;
+import org.apache.ignite.internal.processors.spring.*;
+import org.apache.ignite.plugin.segmentation.*;
+import org.apache.ignite.spi.checkpoint.*;
+import org.apache.ignite.spi.checkpoint.noop.*;
+import org.apache.ignite.spi.collision.*;
+import org.apache.ignite.spi.collision.noop.*;
+import org.apache.ignite.spi.communication.*;
+import org.apache.ignite.spi.communication.tcp.*;
+import org.apache.ignite.spi.deployment.*;
+import org.apache.ignite.spi.deployment.local.*;
+import org.apache.ignite.spi.discovery.*;
+import org.apache.ignite.spi.discovery.tcp.*;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.*;
+import org.apache.ignite.spi.eventstorage.*;
+import org.apache.ignite.spi.eventstorage.memory.*;
+import org.apache.ignite.spi.failover.*;
+import org.apache.ignite.spi.failover.always.*;
+import org.apache.ignite.spi.loadbalancing.*;
+import org.apache.ignite.spi.loadbalancing.roundrobin.*;
+import org.apache.ignite.spi.securesession.*;
+import org.apache.ignite.spi.securesession.noop.*;
+import org.apache.ignite.spi.swapspace.*;
+import org.apache.ignite.spi.swapspace.file.*;
+import org.apache.ignite.spi.swapspace.noop.*;
+import org.apache.ignite.internal.util.typedef.*;
+import org.apache.ignite.internal.util.typedef.internal.*;
+import org.jdk8.backport.*;
+import org.jetbrains.annotations.*;
+
+import javax.management.*;
+import java.io.*;
+import java.lang.management.*;
+import java.lang.reflect.*;
+import java.net.*;
+import java.util.*;
+import java.util.Map.*;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.*;
+import java.util.logging.*;
+
+import static org.apache.ignite.configuration.IgniteConfiguration.*;
+import static org.apache.ignite.IgniteState.*;
+import static org.apache.ignite.IgniteSystemProperties.*;
+import static org.apache.ignite.cache.CacheAtomicityMode.*;
+import static org.apache.ignite.cache.CacheDistributionMode.*;
+import static org.apache.ignite.cache.CacheMode.*;
+import static org.apache.ignite.cache.CachePreloadMode.*;
+import static org.apache.ignite.cache.CacheWriteSynchronizationMode.*;
+import static org.apache.ignite.internal.IgniteComponentType.*;
+import static org.apache.ignite.plugin.segmentation.GridSegmentationPolicy.*;
+
+/**
+ * This class defines a factory for the main GridGain API. It controls Grid life cycle
+ * and allows listening for grid events.
+ * <h1 class="header">Grid Loaders</h1>
+ * Although user can apply grid factory directly to start and stop grid, grid is
+ * often started and stopped by grid loaders. Grid loaders can be found in
+ * {@link org.apache.ignite.startup} package, for example:
+ * <ul>
+ * <li>{@code GridCommandLineStartup}</li>
+ * <li>{@code GridServletStartup}</li>
+ * </ul>
+ * <h1 class="header">Examples</h1>
+ * Use {@link #start()} method to start grid with default configuration. You can also use
+ * {@link org.apache.ignite.configuration.IgniteConfiguration} to override some default configuration. Below is an
+ * example on how to start grid with <strong>URI deployment</strong>.
+ * <pre name="code" class="java">
+ * GridConfiguration cfg = new GridConfiguration();
+ */
+public class IgnitionEx {
+ /** Default configuration path relative to GridGain home. */
+ public static final String DFLT_CFG = "config/default-config.xml";
+
+ /** Map of named grids. */
+ private static final ConcurrentMap<Object, IgniteNamedInstance> grids = new ConcurrentHashMap8<>();
+
+ /** Map of grid states ever started in this JVM. */
+ private static final Map<Object, IgniteState> gridStates = new ConcurrentHashMap8<>();
+
+ /** Mutex to synchronize updates of default grid reference. */
+ private static final Object dfltGridMux = new Object();
+
+ /** Default grid. */
+ private static volatile IgniteNamedInstance dfltGrid;
+
+ /** Default grid state. */
+ private static volatile IgniteState dfltGridState;
+
+ /** List of state listeners. */
+ private static final Collection<IgniteListener> lsnrs = new GridConcurrentHashSet<>(4);
+
+ /** */
+ private static volatile boolean daemon;
+
+ /**
+ * Checks runtime version to be 1.7.x or 1.8.x.
+ * This will load pretty much first so we must do these checks here.
+ */
+ static {
+ // Check 1.8 just in case for forward compatibility.
+ if (!U.jdkVersion().contains("1.7") &&
+ !U.jdkVersion().contains("1.8"))
+ throw new IllegalStateException("GridGain requires Java 7 or above. Current Java version " +
+ "is not supported: " + U.jdkVersion());
+
+ // To avoid nasty race condition in UUID.randomUUID() in JDK prior to 6u34.
+ // For details please see:
+ // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7071826
+ // http://www.oracle.com/technetwork/java/javase/2col/6u34-bugfixes-1733379.html
+ // http://hg.openjdk.java.net/jdk6/jdk6/jdk/rev/563d392b3e5c
+ UUID.randomUUID();
+ }
+
+ /**
+ * Enforces singleton.
+ */
+ private IgnitionEx() {
+ // No-op.
+ }
+
+ /**
+ * Sets daemon flag.
+ * <p>
+ * If daemon flag is set then all grid instances created by the factory will be
+ * daemon, i.e. the local node for these instances will be a daemon node. Note that
+ * if daemon flag is set - it will override the same settings in {@link org.apache.ignite.configuration.IgniteConfiguration#isDaemon()}.
+ * Note that you can set on and off daemon flag at will.
+ *
+ * @param daemon Daemon flag to set.
+ */
+ public static void setDaemon(boolean daemon) {
+ IgnitionEx.daemon = daemon;
+ }
+
+ /**
+ * Gets daemon flag.
+ * <p>
+ * If daemon flag it set then all grid instances created by the factory will be
+ * daemon, i.e. the local node for these instances will be a daemon node. Note that
+ * if daemon flag is set - it will override the same settings in {@link org.apache.ignite.configuration.IgniteConfiguration#isDaemon()}.
+ * Note that you can set on and off daemon flag at will.
+ *
+ * @return Daemon flag.
+ */
+ public static boolean isDaemon() {
+ return daemon;
+ }
+
+ /**
+ * Gets state of grid default grid.
+ *
+ * @return Default grid state.
+ */
+ public static IgniteState state() {
+ return state(null);
+ }
+
+ /**
+ * Gets states of named grid. If name is {@code null}, then state of
+ * default no-name grid is returned.
+ *
+ * @param name Grid name. If name is {@code null}, then state of
+ * default no-name grid is returned.
+ * @return Grid state.
+ */
+ public static IgniteState state(@Nullable String name) {
+ IgniteNamedInstance grid = name != null ? grids.get(name) : dfltGrid;
+
+ if (grid == null) {
+ IgniteState state = name != null ? gridStates.get(name) : dfltGridState;
+
+ return state != null ? state : STOPPED;
+ }
+
+ return grid.state();
+ }
+
+ /**
+ * Stops default grid. This method is identical to {@code G.stop(null, cancel)} apply.
+ * Note that method does not wait for all tasks to be completed.
+ *
+ * @param cancel If {@code true} then all jobs currently executing on
+ * default grid will be cancelled by calling {@link org.apache.ignite.compute.ComputeJob#cancel()}
+ * method. Note that just like with {@link Thread#interrupt()}, it is
+ * up to the actual job to exit from execution
+ * @return {@code true} if default grid instance was indeed stopped,
+ * {@code false} otherwise (if it was not started).
+ */
+ public static boolean stop(boolean cancel) {
+ return stop(null, cancel);
+ }
+
+ /**
+ * Stops named grid. If {@code cancel} flag is set to {@code true} then
+ * all jobs currently executing on local node will be interrupted. If
+ * grid name is {@code null}, then default no-name grid will be stopped.
+ * If wait parameter is set to {@code true} then grid will wait for all
+ * tasks to be finished.
+ *
+ * @param name Grid name. If {@code null}, then default no-name grid will
+ * be stopped.
+ * @param cancel If {@code true} then all jobs currently will be cancelled
+ * by calling {@link org.apache.ignite.compute.ComputeJob#cancel()} method. Note that just like with
+ * {@link Thread#interrupt()}, it is up to the actual job to exit from
+ * execution. If {@code false}, then jobs currently running will not be
+ * canceled. In either case, grid node will wait for completion of all
+ * jobs running on it before stopping.
+ * @return {@code true} if named grid instance was indeed found and stopped,
+ * {@code false} otherwise (the instance with given {@code name} was
+ * not found).
+ */
+ public static boolean stop(@Nullable String name, boolean cancel) {
+ IgniteNamedInstance grid = name != null ? grids.get(name) : dfltGrid;
+
+ if (grid != null && grid.state() == STARTED) {
+ grid.stop(cancel);
+
+ boolean fireEvt;
+
+ if (name != null)
+ fireEvt = grids.remove(name, grid);
+ else {
+ synchronized (dfltGridMux) {
+ fireEvt = dfltGrid == grid;
+
+ if (fireEvt)
+ dfltGrid = null;
+ }
+ }
+
+ if (fireEvt)
+ notifyStateChange(grid.getName(), grid.state());
+
+ return true;
+ }
+
+ // We don't have log at this point...
+ U.warn(null, "Ignoring stopping grid instance that was already stopped or never started: " + name);
+
+ return false;
+ }
+
+ /**
+ * Stops <b>all</b> started grids. If {@code cancel} flag is set to {@code true} then
+ * all jobs currently executing on local node will be interrupted.
+ * If wait parameter is set to {@code true} then grid will wait for all
+ * tasks to be finished.
+ * <p>
+ * <b>Note:</b> it is usually safer and more appropriate to stop grid instances individually
+ * instead of blanket operation. In most cases, the party that started the grid instance
+ * should be responsible for stopping it.
+ *
+ * @param cancel If {@code true} then all jobs currently executing on
+ * all grids will be cancelled by calling {@link org.apache.ignite.compute.ComputeJob#cancel()}
+ * method. Note that just like with {@link Thread#interrupt()}, it is
+ * up to the actual job to exit from execution
+ */
+ public static void stopAll(boolean cancel) {
+ IgniteNamedInstance dfltGrid0 = dfltGrid;
+
+ if (dfltGrid0 != null) {
+ dfltGrid0.stop(cancel);
+
+ boolean fireEvt;
+
+ synchronized (dfltGridMux) {
+ fireEvt = dfltGrid == dfltGrid0;
+
+ if (fireEvt)
+ dfltGrid = null;
+ }
+
+ if (fireEvt)
+ notifyStateChange(dfltGrid0.getName(), dfltGrid0.state());
+ }
+
+ // Stop the rest and clear grids map.
+ for (IgniteNamedInstance grid : grids.values()) {
+ grid.stop(cancel);
+
+ boolean fireEvt = grids.remove(grid.getName(), grid);
+
+ if (fireEvt)
+ notifyStateChange(grid.getName(), grid.state());
+ }
+ }
+
+ /**
+ * Restarts <b>all</b> started grids. If {@code cancel} flag is set to {@code true} then
+ * all jobs currently executing on the local node will be interrupted.
+ * If {@code wait} parameter is set to {@code true} then grid will wait for all
+ * tasks to be finished.
+ * <p>
+ * <b>Note:</b> it is usually safer and more appropriate to stop grid instances individually
+ * instead of blanket operation. In most cases, the party that started the grid instance
+ * should be responsible for stopping it.
+ * <p>
+ * Note also that restarting functionality only works with the tools that specifically
+ * support GridGain's protocol for restarting. Currently only standard <tt>ggstart.{sh|bat}</tt>
+ * scripts support restarting of JVM GridGain's process.
+ *
+ * @param cancel If {@code true} then all jobs currently executing on
+ * all grids will be cancelled by calling {@link org.apache.ignite.compute.ComputeJob#cancel()}
+ * method. Note that just like with {@link Thread#interrupt()}, it is
+ * up to the actual job to exit from execution.
+ * @see org.apache.ignite.Ignition#RESTART_EXIT_CODE
+ */
+ public static void restart(boolean cancel) {
+ String file = System.getProperty(GG_SUCCESS_FILE);
+
+ if (file == null)
+ U.warn(null, "Cannot restart node when restart not enabled.");
+ else {
+ try {
+ new File(file).createNewFile();
+ }
+ catch (IOException e) {
+ U.error(null, "Failed to create restart marker file (restart aborted): " + e.getMessage());
+
+ return;
+ }
+
+ U.log(null, "Restarting node. Will exit (" + Ignition.RESTART_EXIT_CODE + ").");
+
+ // Set the exit code so that shell process can recognize it and loop
+ // the start up sequence again.
+ System.setProperty(GG_RESTART_CODE, Integer.toString(Ignition.RESTART_EXIT_CODE));
+
+ stopAll(cancel);
+
+ // This basically leaves loaders hang - we accept it.
+ System.exit(Ignition.RESTART_EXIT_CODE);
+ }
+ }
+
+ /**
+ * Stops <b>all</b> started grids. If {@code cancel} flag is set to {@code true} then
+ * all jobs currently executing on the local node will be interrupted.
+ * If {@code wait} parameter is set to {@code true} then grid will wait for all
+ * tasks to be finished.
+ * <p>
+ * <b>Note:</b> it is usually safer and more appropriate to stop grid instances individually
+ * instead of blanket operation. In most cases, the party that started the grid instance
+ * should be responsible for stopping it.
+ * <p>
+ * Note that upon completion of this method, the JVM with forcefully exist with
+ * exit code {@link org.apache.ignite.Ignition#KILL_EXIT_CODE}.
+ *
+ * @param cancel If {@code true} then all jobs currently executing on
+ * all grids will be cancelled by calling {@link org.apache.ignite.compute.ComputeJob#cancel()}
+ * method. Note that just like with {@link Thread#interrupt()}, it is
+ * up to the actual job to exit from execution.
+ * @see org.apache.ignite.Ignition#KILL_EXIT_CODE
+ */
+ public static void kill(boolean cancel) {
+ stopAll(cancel);
+
+ // This basically leaves loaders hang - we accept it.
+ System.exit(Ignition.KILL_EXIT_CODE);
+ }
+
+ /**
+ * Starts grid with default configuration. By default this method will
+ * use grid configuration defined in {@code GRIDGAIN_HOME/config/default-config.xml}
+ * configuration file. If such file is not found, then all system defaults will be used.
+ *
+ * @return Started grid.
+ * @throws IgniteCheckedException If default grid could not be started. This exception will be thrown
+ * also if default grid has already been started.
+ */
+ public static Ignite start() throws IgniteCheckedException {
+ return start((GridSpringResourceContext)null);
+ }
+
+ /**
+ * Starts grid with default configuration. By default this method will
+ * use grid configuration defined in {@code GRIDGAIN_HOME/config/default-config.xml}
+ * configuration file. If such file is not found, then all system defaults will be used.
+ *
+ * @param springCtx Optional Spring application context, possibly {@code null}.
+ * Spring bean definitions for bean injection are taken from this context.
+ * If provided, this context can be injected into grid tasks and grid jobs using
+ * {@link org.apache.ignite.resources.IgniteSpringApplicationContextResource @IgniteSpringApplicationContextResource} annotation.
+ * @return Started grid.
+ * @throws IgniteCheckedException If default grid could not be started. This exception will be thrown
+ * also if default grid has already been started.
+ */
+ public static Ignite start(@Nullable GridSpringResourceContext springCtx) throws IgniteCheckedException {
+ URL url = U.resolveGridGainUrl(DFLT_CFG);
+
+ if (url != null)
+ return start(DFLT_CFG, null, springCtx);
+
+ U.warn(null, "Default Spring XML file not found (is GRIDGAIN_HOME set?): " + DFLT_CFG);
+
+ return start0(new GridStartContext(new IgniteConfiguration(), null, springCtx)).grid();
+ }
+
+ /**
+ * Starts grid with given configuration. Note that this method is no-op if grid with the name
+ * provided in given configuration is already started.
+ *
+ * @param cfg Grid configuration. This cannot be {@code null}.
+ * @return Started grid.
+ * @throws IgniteCheckedException If grid could not be started. This exception will be thrown
+ * also if named grid has already been started.
+ */
+ public static Ignite start(IgniteConfiguration cfg) throws IgniteCheckedException {
+ return start(cfg, null);
+ }
+
+ /**
+ * Starts grid with given configuration. Note that this method is no-op if grid with the name
+ * provided in given configuration is already started.
+ *
+ * @param cfg Grid configuration. This cannot be {@code null}.
+ * @param springCtx Optional Spring application context, possibly {@code null}.
+ * Spring bean definitions for bean injection are taken from this context.
+ * If provided, this context can be injected into grid tasks and grid jobs using
+ * {@link org.apache.ignite.resources.IgniteSpringApplicationContextResource @IgniteSpringApplicationContextResource} annotation.
+ * @return Started grid.
+ * @throws IgniteCheckedException If grid could not be started. This exception will be thrown
+ * also if named grid has already been started.
+ */
+ public static Ignite start(IgniteConfiguration cfg, @Nullable GridSpringResourceContext springCtx) throws IgniteCheckedException {
+ A.notNull(cfg, "cfg");
+
+ return start0(new GridStartContext(cfg, null, springCtx)).grid();
+ }
+
+ /**
+ * Starts all grids specified within given Spring XML configuration file. If grid with given name
+ * is already started, then exception is thrown. In this case all instances that may
+ * have been started so far will be stopped too.
+ * <p>
+ * Usually Spring XML configuration file will contain only one Grid definition. Note that
+ * Grid configuration bean(s) is retrieved form configuration file by type, so the name of
+ * the Grid configuration bean is ignored.
+ *
+ * @param springCfgPath Spring XML configuration file path or URL.
+ * @return Started grid. If Spring configuration contains multiple grid instances,
+ * then the 1st found instance is returned.
+ * @throws IgniteCheckedException If grid could not be started or configuration
+ * read. This exception will be thrown also if grid with given name has already
+ * been started or Spring XML configuration file is invalid.
+ */
+ public static Ignite start(@Nullable String springCfgPath) throws IgniteCheckedException {
+ return springCfgPath == null ? start() : start(springCfgPath, null);
+ }
+
+ /**
+ * Starts all grids specified within given Spring XML configuration file. If grid with given name
+ * is already started, then exception is thrown. In this case all instances that may
+ * have been started so far will be stopped too.
+ * <p>
+ * Usually Spring XML configuration file will contain only one Grid definition. Note that
+ * Grid configuration bean(s) is retrieved form configuration file by type, so the name of
+ * the Grid configuration bean is ignored.
+ *
+ * @param springCfgPath Spring XML configuration file path or URL.
+ * @param gridName Grid name that will override default.
+ * @return Started grid. If Spring configuration contains multiple grid instances,
+ * then the 1st found instance is returned.
+ * @throws IgniteCheckedException If grid could not be started or configuration
+ * read. This exception will be thrown also if grid with given name has already
+ * been started or Spring XML configuration file is invalid.
+ */
+ public static Ignite start(@Nullable String springCfgPath, @Nullable String gridName) throws IgniteCheckedException {
+ if (springCfgPath == null) {
+ IgniteConfiguration cfg = new IgniteConfiguration();
+
+ if (cfg.getGridName() == null && !F.isEmpty(gridName))
+ cfg.setGridName(gridName);
+
+ return start(cfg);
+ }
+ else
+ return start(springCfgPath, gridName, null);
+ }
+
+ /**
+ * Start Grid for interop scenario.
+ *
+ * @param springCfgPath Spring config path.
+ * @param gridName Grid name.
+ * @param cfgClo Configuration closure.
+ * @return Started Grid.
+ * @throws IgniteCheckedException If failed.
+ */
+ public static Ignite startInterop(@Nullable String springCfgPath, @Nullable String gridName,
+ IgniteClosure<IgniteConfiguration, IgniteConfiguration> cfgClo) throws IgniteCheckedException {
+ URL url = resolveSpringUrl(springCfgPath);
+
+ return start(url, gridName, null, cfgClo);
+ }
+
+ /**
+ * Loads all grid configurations specified within given Spring XML configuration file.
+ * <p>
+ * Usually Spring XML configuration file will contain only one Grid definition. Note that
+ * Grid configuration bean(s) is retrieved form configuration file by type, so the name of
+ * the Grid configuration bean is ignored.
+ *
+ * @param springCfgUrl Spring XML configuration file path or URL. This cannot be {@code null}.
+ * @return Tuple containing all loaded configurations and Spring context used to load them.
+ * @throws IgniteCheckedException If grid could not be started or configuration
+ * read. This exception will be thrown also if grid with given name has already
+ * been started or Spring XML configuration file is invalid.
+ */
+ public static IgniteBiTuple<Collection<IgniteConfiguration>, ? extends GridSpringResourceContext> loadConfigurations(
+ URL springCfgUrl) throws IgniteCheckedException {
+ IgniteSpringProcessor spring = SPRING.create(false);
+
+ return spring.loadConfigurations(springCfgUrl);
+ }
+
+ /**
+ * Loads all grid configurations specified within given Spring XML configuration file.
+ * <p>
+ * Usually Spring XML configuration file will contain only one Grid definition. Note that
+ * Grid configuration bean(s) is retrieved form configuration file by type, so the name of
+ * the Grid configuration bean is ignored.
+ *
+ * @param springCfgPath Spring XML configuration file path. This cannot be {@code null}.
+ * @return Tuple containing all loaded configurations and Spring context used to load them.
+ * @throws IgniteCheckedException If grid could not be started or configuration
+ * read. This exception will be thrown also if grid with given name has already
+ * been started or Spring XML configuration file is invalid.
+ */
+ public static IgniteBiTuple<Collection<IgniteConfiguration>, ? extends GridSpringResourceContext> loadConfigurations(
+ String springCfgPath) throws IgniteCheckedException {
+ A.notNull(springCfgPath, "springCfgPath");
+
+ URL url;
+
+ try {
+ url = new URL(springCfgPath);
+ }
+ catch (MalformedURLException e) {
+ url = U.resolveGridGainUrl(springCfgPath);
+
+ if (url == null)
+ throw new IgniteCheckedException("Spring XML configuration path is invalid: " + springCfgPath +
+ ". Note that this path should be either absolute or a relative local file system path, " +
+ "relative to META-INF in classpath or valid URL to GRIDGAIN_HOME.", e);
+ }
+
+ return loadConfigurations(url);
+ }
+
+ /**
+ * Loads first found grid configuration specified within given Spring XML configuration file.
+ * <p>
+ * Usually Spring XML configuration file will contain only one Grid definition. Note that
+ * Grid configuration bean(s) is retrieved form configuration file by type, so the name of
+ * the Grid configuration bean is ignored.
+ *
+ * @param springCfgUrl Spring XML configuration file path or URL. This cannot be {@code null}.
+ * @return First found configuration and Spring context used to load it.
+ * @throws IgniteCheckedException If grid could not be started or configuration
+ * read. This exception will be thrown also if grid with given name has already
+ * been started or Spring XML configuration file is invalid.
+ */
+ public static IgniteBiTuple<IgniteConfiguration, GridSpringResourceContext> loadConfiguration(URL springCfgUrl)
+ throws IgniteCheckedException {
+ IgniteBiTuple<Collection<IgniteConfiguration>, ? extends GridSpringResourceContext> t = loadConfigurations(springCfgUrl);
+
+ return F.t(F.first(t.get1()), t.get2());
+ }
+
+ /**
+ * Loads first found grid configuration specified within given Spring XML configuration file.
+ * <p>
+ * Usually Spring XML configuration file will contain only one Grid definition. Note that
+ * Grid configuration bean(s) is retrieved form configuration file by type, so the name of
+ * the Grid configuration bean is ignored.
+ *
+ * @param springCfgPath Spring XML configuration file path. This cannot be {@code null}.
+ * @return First found configuration and Spring context used to load it.
+ * @throws IgniteCheckedException If grid could not be started or configuration
+ * read. This exception will be thrown also if grid with given name has already
+ * been started or Spring XML configuration file is invalid.
+ */
+ public static IgniteBiTuple<IgniteConfiguration, GridSpringResourceContext> loadConfiguration(String springCfgPath)
+ throws IgniteCheckedException {
+ IgniteBiTuple<Collection<IgniteConfiguration>, ? extends GridSpringResourceContext> t =
+ loadConfigurations(springCfgPath);
+
+ return F.t(F.first(t.get1()), t.get2());
+ }
+
+ /**
+ * Starts all grids specified within given Spring XML configuration file. If grid with given name
+ * is already started, then exception is thrown. In this case all instances that may
+ * have been started so far will be stopped too.
+ * <p>
+ * Usually Spring XML configuration file will contain only one Grid definition. Note that
+ * Grid configuration bean(s) is retrieved form configuration file by type, so the name of
+ * the Grid configuration bean is ignored.
+ *
+ * @param springCfgPath Spring XML configuration file path or URL. This cannot be {@code null}.
+ * @param gridName Grid name that will override default.
+ * @param springCtx Optional Spring application context, possibly {@code null}.
+ * Spring bean definitions for bean injection are taken from this context.
+ * If provided, this context can be injected into grid tasks and grid jobs using
+ * {@link org.apache.ignite.resources.IgniteSpringApplicationContextResource @IgniteSpringApplicationContextResource} annotation.
+ * @return Started grid. If Spring configuration contains multiple grid instances,
+ * then the 1st found instance is returned.
+ * @throws IgniteCheckedException If grid could not be started or configuration
+ * read. This exception will be thrown also if grid with given name has already
+ * been started or Spring XML configuration file is invalid.
+ */
+ public static Ignite start(String springCfgPath, @Nullable String gridName,
+ @Nullable GridSpringResourceContext springCtx) throws IgniteCheckedException {
+ URL url = resolveSpringUrl(springCfgPath);
+
+ return start(url, gridName, springCtx);
+ }
+
+ /**
+ * Starts all grids specified within given Spring XML configuration file URL. If grid with given name
+ * is already started, then exception is thrown. In this case all instances that may
+ * have been started so far will be stopped too.
+ * <p>
+ * Usually Spring XML configuration file will contain only one Grid definition. Note that
+ * Grid configuration bean(s) is retrieved form configuration file by type, so the name of
+ * the Grid configuration bean is ignored.
+ *
+ * @param springCfgUrl Spring XML configuration file URL. This cannot be {@code null}.
+ * @return Started grid. If Spring configuration contains multiple grid instances,
+ * then the 1st found instance is returned.
+ * @throws IgniteCheckedException If grid could not be started or configuration
+ * read. This exception will be thrown also if grid with given name has already
+ * been started or Spring XML configuration file is invalid.
+ */
+ public static Ignite start(URL springCfgUrl) throws IgniteCheckedException {
+ return start(springCfgUrl, null, null);
+ }
+
+ /**
+ * Starts all grids specified within given Spring XML configuration file URL. If grid with given name
+ * is already started, then exception is thrown. In this case all instances that may
+ * have been started so far will be stopped too.
+ * <p>
+ * Usually Spring XML configuration file will contain only one Grid definition. Note that
+ * Grid configuration bean(s) is retrieved form configuration file by type, so the name of
+ * the Grid configuration bean is ignored.
+ *
+ * @param springCfgUrl Spring XML configuration file URL. This cannot be {@code null}.
+ * @param gridName Grid name that will override default.
+ * @param springCtx Optional Spring application context, possibly {@code null}.
+ * Spring bean definitions for bean injection are taken from this context.
+ * If provided, this context can be injected into grid tasks and grid jobs using
+ * {@link org.apache.ignite.resources.IgniteSpringApplicationContextResource @IgniteSpringApplicationContextResource} annotation.
+ * @return Started grid. If Spring configuration contains multiple grid instances,
+ * then the 1st found instance is returned.
+ * @throws IgniteCheckedException If grid could not be started or configuration
+ * read. This exception will be thrown also if grid with given name has already
+ * been started or Spring XML configuration file is invalid.
+ */
+ public static Ignite start(URL springCfgUrl, @Nullable String gridName,
+ @Nullable GridSpringResourceContext springCtx) throws IgniteCheckedException {
+ return start(springCfgUrl, gridName, springCtx, null);
+ }
+
+ /**
+ * Internal Spring-based start routine.
+ *
+ * @param springCfgUrl Spring XML configuration file URL. This cannot be {@code null}.
+ * @param gridName Grid name that will override default.
+ * @param springCtx Optional Spring application context.
+ * @param cfgClo Optional closure to change configuration before it is used to start the grid.
+ * @return Started grid.
+ * @throws IgniteCheckedException If failed.
+ */
+ private static Ignite start(URL springCfgUrl, @Nullable String gridName,
+ @Nullable GridSpringResourceContext springCtx,
+ @Nullable IgniteClosure<IgniteConfiguration, IgniteConfiguration> cfgClo)
+ throws IgniteCheckedException {
+ A.notNull(springCfgUrl, "springCfgUrl");
+
+ boolean isLog4jUsed = U.gridClassLoader().getResource("org/apache/log4j/Appender.class") != null;
+
+ IgniteBiTuple<Object, Object> t = null;
+
+ Collection<Handler> savedHnds = null;
+
+ if (isLog4jUsed)
+ t = U.addLog4jNoOpLogger();
+ else
+ savedHnds = U.addJavaNoOpLogger();
+
+ IgniteBiTuple<Collection<IgniteConfiguration>, ? extends GridSpringResourceContext> cfgMap;
+
+ try {
+ cfgMap = loadConfigurations(springCfgUrl);
+ }
+ finally {
+ if (isLog4jUsed && t != null)
+ U.removeLog4jNoOpLogger(t);
+
+ if (!isLog4jUsed)
+ U.removeJavaNoOpLogger(savedHnds);
+ }
+
+ List<IgniteNamedInstance> grids = new ArrayList<>(cfgMap.size());
+
+ try {
+ for (IgniteConfiguration cfg : cfgMap.get1()) {
+ assert cfg != null;
+
+ if (cfg.getGridName() == null && !F.isEmpty(gridName))
+ cfg.setGridName(gridName);
+
+ if (cfgClo != null) {
+ cfg = cfgClo.apply(cfg);
+
+ assert cfg != null;
+ }
+
+ // Use either user defined context or our one.
+ IgniteNamedInstance grid = start0(
+ new GridStartContext(cfg, springCfgUrl, springCtx == null ? cfgMap.get2() : springCtx));
+
+ // Add it if it was not stopped during startup.
+ if (grid != null)
+ grids.add(grid);
+ }
+ }
+ catch (IgniteCheckedException e) {
+ // Stop all instances started so far.
+ for (IgniteNamedInstance grid : grids) {
+ try {
+ grid.stop(true);
+ }
+ catch (Exception e1) {
+ U.error(grid.log, "Error when stopping grid: " + grid, e1);
+ }
+ }
+
+ throw e;
+ }
+
+ // Return the first grid started.
+ IgniteNamedInstance res = !grids.isEmpty() ? grids.get(0) : null;
+
+ return res != null ? res.grid() : null;
+ }
+
+ /**
+ * Resolve Spring configuration URL.
+ *
+ * @param springCfgPath Spring XML configuration file path or URL. This cannot be {@code null}.
+ * @return URL.
+ * @throws IgniteCheckedException If failed.
+ */
+ private static URL resolveSpringUrl(String springCfgPath) throws IgniteCheckedException {
+ A.notNull(springCfgPath, "springCfgPath");
+
+ URL url;
+
+ try {
+ url = new URL(springCfgPath);
+ }
+ catch (MalformedURLException e) {
+ url = U.resolveGridGainUrl(springCfgPath);
+
+ if (url == null)
+ throw new IgniteCheckedException("Spring XML configuration path is invalid: " + springCfgPath +
+ ". Note that this path should be either absolute or a relative local file system path, " +
+ "relative to META-INF in classpath or valid URL to GRIDGAIN_HOME.", e);
+ }
+
+ return url;
+ }
+
+ /**
+ * Starts grid with given configuration.
+ *
+ * @param startCtx Start context.
+ * @return Started grid.
+ * @throws IgniteCheckedException If grid could not be started.
+ */
+ private static IgniteNamedInstance start0(GridStartContext startCtx) throws IgniteCheckedException {
+ assert startCtx != null;
+
+ String name = startCtx.config().getGridName();
+
+ if (name != null && name.isEmpty())
+ throw new IgniteCheckedException("Non default grid instances cannot have empty string name.");
+
+ IgniteNamedInstance grid = new IgniteNamedInstance(name);
+
+ IgniteNamedInstance old;
+
+ if (name != null)
+ old = grids.putIfAbsent(name, grid);
+ else {
+ synchronized (dfltGridMux) {
+ old = dfltGrid;
+
+ if (old == null)
+ dfltGrid = grid;
+ }
+ }
+
+ if (old != null) {
+ if (name == null)
+ throw new IgniteCheckedException("Default grid instance has already been started.");
+ else
+ throw new IgniteCheckedException("Grid instance with this name has already been started: " + name);
+ }
+
+ if (startCtx.config().getWarmupClosure() != null)
+ startCtx.config().getWarmupClosure().apply(startCtx.config());
+
+ startCtx.single(grids.size() == 1);
+
+ boolean success = false;
+
+ try {
+ grid.start(startCtx);
+
+ notifyStateChange(name, STARTED);
+
+ success = true;
+ }
+ finally {
+ if (!success) {
+ if (name != null)
+ grids.remove(name, grid);
+ else {
+ synchronized (dfltGridMux) {
+ if (dfltGrid == grid)
+ dfltGrid = null;
+ }
+ }
+
+ grid = null;
+ }
+ }
+
+ if (grid == null)
+ throw new IgniteCheckedException("Failed to start grid with provided configuration.");
+
+ return grid;
+ }
+
+ /**
+ * Gets an instance of default no-name grid. Note that
+ * caller of this method should not assume that it will return the same
+ * instance every time.
+ * <p>
+ * This method is identical to {@code G.grid(null)} apply.
+ *
+ * @return An instance of default no-name grid. This method never returns
+ * {@code null}.
+ * @throws org.apache.ignite.IgniteIllegalStateException Thrown if default grid was not properly
+ * initialized or grid instance was stopped or was not started.
+ */
+ public static Ignite grid() throws IgniteIllegalStateException {
+ return grid((String)null);
+ }
+
+ /**
+ * Gets a list of all grids started so far.
+ *
+ * @return List of all grids started so far.
+ */
+ public static List<Ignite> allGrids() {
+ List<Ignite> allIgnites = new ArrayList<>(grids.size() + 1);
+
+ for (IgniteNamedInstance grid : grids.values()) {
+ Ignite g = grid.grid();
+
+ if (g != null)
+ allIgnites.add(g);
+ }
+
+ IgniteNamedInstance dfltGrid0 = dfltGrid;
+
+ if (dfltGrid0 != null) {
+ IgniteKernal g = dfltGrid0.grid();
+
+ if (g != null)
+ allIgnites.add(g);
+ }
+
+ return allIgnites;
+ }
+
+ /**
+ * Gets a grid instance for given local node ID. Note that grid instance and local node have
+ * one-to-one relationship where node has ID and instance has name of the grid to which
+ * both grid instance and its node belong. Note also that caller of this method
+ * should not assume that it will return the same instance every time.
+ *
+ * @param locNodeId ID of local node the requested grid instance is managing.
+ * @return An instance of named grid. This method never returns
+ * {@code null}.
+ * @throws org.apache.ignite.IgniteIllegalStateException Thrown if grid was not properly
+ * initialized or grid instance was stopped or was not started.
+ */
+ public static Ignite grid(UUID locNodeId) throws IgniteIllegalStateException {
+ A.notNull(locNodeId, "locNodeId");
+
+ IgniteNamedInstance dfltGrid0 = dfltGrid;
+
+ if (dfltGrid0 != null) {
+ IgniteKernal g = dfltGrid0.grid();
+
+ if (g != null && g.getLocalNodeId().equals(locNodeId))
+ return g;
+ }
+
+ for (IgniteNamedInstance grid : grids.values()) {
+ IgniteKernal g = grid.grid();
+
+ if (g != null && g.getLocalNodeId().equals(locNodeId))
+ return g;
+ }
+
+ throw new IgniteIllegalStateException("Grid instance with given local node ID was not properly " +
+ "started or was stopped: " + locNodeId);
+ }
+
+ /**
+ * Gets an named grid instance. If grid name is {@code null} or empty string,
+ * then default no-name grid will be returned. Note that caller of this method
+ * should not assume that it will return the same instance every time.
+ * <p>
+ * Note that Java VM can run multiple grid instances and every grid instance (and its
+ * node) can belong to a different grid. Grid name defines what grid a particular grid
+ * instance (and correspondingly its node) belongs to.
+ *
+ * @param name Grid name to which requested grid instance belongs to. If {@code null},
+ * then grid instance belonging to a default no-name grid will be returned.
+ * @return An instance of named grid. This method never returns
+ * {@code null}.
+ * @throws org.apache.ignite.IgniteIllegalStateException Thrown if default grid was not properly
+ * initialized or grid instance was stopped or was not started.
+ */
+ public static Ignite grid(@Nullable String name) throws IgniteIllegalStateException {
+ IgniteNamedInstance grid = name != null ? grids.get(name) : dfltGrid;
+
+ Ignite res;
+
+ if (grid == null || (res = grid.grid()) == null)
+ throw new IgniteIllegalStateException("Grid instance was not properly started " +
+ "or was already stopped: " + name);
+
+ return res;
+ }
+
+ /**
+ * Gets grid instance without waiting its initialization.
+ *
+ * @param name Grid name.
+ * @return Grid instance.
+ */
+ public static IgniteKernal gridx(@Nullable String name) {
+ IgniteNamedInstance grid = name != null ? grids.get(name) : dfltGrid;
+
+ IgniteKernal res;
+
+ if (grid == null || (res = grid.gridx()) == null)
+ throw new IllegalStateException("Grid instance was not properly started or was already stopped: " + name);
+
+ return res;
+ }
+
+ /**
+ * Adds a lsnr for grid life cycle events.
+ * <p>
+ * Note that unlike other listeners in GridGain this listener will be
+ * notified from the same thread that triggers the state change. Because of
+ * that it is the responsibility of the user to make sure that listener logic
+ * is light-weight and properly handles (catches) any runtime exceptions, if any
+ * are expected.
+ *
+ * @param lsnr Listener for grid life cycle events. If this listener was already added
+ * this method is no-op.
+ */
+ public static void addListener(IgniteListener lsnr) {
+ A.notNull(lsnr, "lsnr");
+
+ lsnrs.add(lsnr);
+ }
+
+ /**
+ * Removes lsnr added by {@link #addListener(org.apache.ignite.lifecycle.IgniteListener)} method.
+ *
+ * @param lsnr Listener to remove.
+ * @return {@code true} if lsnr was added before, {@code false} otherwise.
+ */
+ public static boolean removeListener(IgniteListener lsnr) {
+ A.notNull(lsnr, "lsnr");
+
+ return lsnrs.remove(lsnr);
+ }
+
+ /**
+ * @param gridName Grid instance name.
+ * @param state Factory state.
+ */
+ private static void notifyStateChange(@Nullable String gridName, IgniteState state) {
+ if (gridName != null)
+ gridStates.put(gridName, state);
+ else
+ dfltGridState = state;
+
+ for (IgniteListener lsnr : lsnrs)
+ lsnr.onStateChange(gridName, state);
+ }
+
+ /**
+ * Start context encapsulates all starting parameters.
+ */
+ private static final class GridStartContext {
+ /** User-defined configuration. */
+ private IgniteConfiguration cfg;
+
+ /** Optional configuration path. */
+ private URL cfgUrl;
+
+ /** Optional Spring application context. */
+ private GridSpringResourceContext springCtx;
+
+ /** Whether or not this is a single grid instance in current VM. */
+ private boolean single;
+
+ /**
+ *
+ * @param cfg User-defined configuration.
+ * @param cfgUrl Optional configuration path.
+ * @param springCtx Optional Spring application context.
+ */
+ GridStartContext(IgniteConfiguration cfg, @Nullable URL cfgUrl, @Nullable GridSpringResourceContext springCtx) {
+ assert(cfg != null);
+
+ this.cfg = cfg;
+ this.cfgUrl = cfgUrl;
+ this.springCtx = springCtx;
+ }
+
+ /**
+ * @return Whether or not this is a single grid instance in current VM.
+ */
+ public boolean single() {
+ return single;
+ }
+
+ /**
+ * @param single Whether or not this is a single grid instance in current VM.
+ */
+ public void single(boolean single) {
+ this.single = single;
+ }
+
+ /**
+ * @return User-defined configuration.
+ */
+ IgniteConfiguration config() {
+ return cfg;
+ }
+
+ /**
+ * @param cfg User-defined configuration.
+ */
+ void config(IgniteConfiguration cfg) {
+ this.cfg = cfg;
+ }
+
+ /**
+ * @return Optional configuration path.
+ */
+ URL configUrl() {
+ return cfgUrl;
+ }
+
+ /**
+ * @param cfgUrl Optional configuration path.
+ */
+ void configUrl(URL cfgUrl) {
+ this.cfgUrl = cfgUrl;
+ }
+
+ /**
+ * @return Optional Spring application context.
+ */
+ public GridSpringResourceContext springContext() {
+ return springCtx;
+ }
+ }
+
+ /**
+ * Grid data container.
+ */
+ private static final class IgniteNamedInstance {
+ /** Map of registered MBeans. */
+ private static final Map<MBeanServer, GridMBeanServerData> mbeans =
+ new HashMap<>();
+
+ /** */
+ private static final String[] EMPTY_STR_ARR = new String[0];
+
+ /** Empty array of caches. */
+ private static final CacheConfiguration[] EMPTY_CACHE_CONFIGS = new CacheConfiguration[0];
+
+ /** Grid name. */
+ private final String name;
+
+ /** Grid instance. */
+ private volatile IgniteKernal grid;
+
+ /** Executor service. */
+ private ExecutorService execSvc;
+
+ /** Auto executor service flag. */
+ private boolean isAutoExecSvc;
+
+ /** Executor service shutdown flag. */
+ private boolean execSvcShutdown;
+
+ /** System executor service. */
+ private ExecutorService sysExecSvc;
+
+ /** Auto system service flag. */
+ private boolean isAutoSysSvc;
+
+ /** System executor service shutdown flag. */
+ private boolean sysSvcShutdown;
+
+ /** Management executor service. */
+ private ExecutorService mgmtExecSvc;
+
+ /** Auto management service flag. */
+ private boolean isAutoMgmtSvc;
+
+ /** Management executor service shutdown flag. */
+ private boolean mgmtSvcShutdown;
+
+ /** P2P executor service. */
+ private ExecutorService p2pExecSvc;
+
+ /** Auto P2P service flag. */
+ private boolean isAutoP2PSvc;
+
+ /** P2P executor service shutdown flag. */
+ private boolean p2pSvcShutdown;
+
+ /** GGFS executor service. */
+ private ExecutorService ggfsExecSvc;
+
+ /** Auto GGFS service flag. */
+ private boolean isAutoGgfsSvc;
+
+ /** GGFS executor service shutdown flag. */
+ private boolean ggfsSvcShutdown;
+
+ /** REST requests executor service. */
+ private ExecutorService restExecSvc;
+
+ /** Auto REST service flag. */
+ private boolean isAutoRestSvc;
+
+ /** REST executor service shutdown flag. */
+ private boolean restSvcShutdown;
+
+ /** Utility cache executor service. */
+ private ExecutorService utilityCacheExecSvc;
+
+ /** Grid state. */
+ private volatile IgniteState state = STOPPED;
+
+ /** Shutdown hook. */
+ private Thread shutdownHook;
+
+ /** Grid log. */
+ private IgniteLogger log;
+
+ /** Start guard. */
+ private final AtomicBoolean startGuard = new AtomicBoolean();
+
+ /** Start latch. */
+ private final CountDownLatch startLatch = new CountDownLatch(1);
+
+ /**
+ * Thread that starts this named instance. This field can be non-volatile since
+ * it makes sense only for thread where it was originally initialized.
+ */
+ @SuppressWarnings("FieldAccessedSynchronizedAndUnsynchronized")
+ private Thread starterThread;
+
+ /**
+ * Creates un-started named instance.
+ *
+ * @param name Grid name (possibly {@code null} for default grid).
+ */
+ IgniteNamedInstance(@Nullable String name) {
+ this.name = name;
+ }
+
+ /**
+ * Gets grid name.
+ *
+ * @return Grid name.
+ */
+ String getName() {
+ return name;
+ }
+
+ /**
+ * Gets grid instance.
+ *
+ * @return Grid instance.
+ */
+ IgniteKernal grid() {
+ if (starterThread != Thread.currentThread())
+ U.awaitQuiet(startLatch);
+
+ return grid;
+ }
+
+ /**
+ * Gets grid instance without waiting for its initialization.
+ *
+ * @return Grid instance.
+ */
+ public IgniteKernal gridx() {
+ return grid;
+ }
+
+ /**
+ * Gets grid state.
+ *
+ * @return Grid state.
+ */
+ IgniteState state() {
+ if (starterThread != Thread.currentThread())
+ U.awaitQuiet(startLatch);
+
+ return state;
+ }
+
+ /**
+ * @param spi SPI implementation.
+ * @throws IgniteCheckedException Thrown in case if multi-instance is not supported.
+ */
+ private void ensureMultiInstanceSupport(IgniteSpi spi) throws IgniteCheckedException {
+ IgniteSpiMultipleInstancesSupport ann = U.getAnnotation(spi.getClass(),
+ IgniteSpiMultipleInstancesSupport.class);
+
+ if (ann == null || !ann.value())
+ throw new IgniteCheckedException("SPI implementation doesn't support multiple grid instances in " +
+ "the same VM: " + spi);
+ }
+
+ /**
+ * @param spis SPI implementations.
+ * @throws IgniteCheckedException Thrown in case if multi-instance is not supported.
+ */
+ private void ensureMultiInstanceSupport(IgniteSpi[] spis) throws IgniteCheckedException {
+ for (IgniteSpi spi : spis)
+ ensureMultiInstanceSupport(spi);
+ }
+
+ /**
+ * Starts grid with given configuration.
+ *
+ * @param startCtx Starting context.
+ * @throws IgniteCheckedException If start failed.
+ */
+ synchronized void start(GridStartContext startCtx) throws IgniteCheckedException {
+ if (startGuard.compareAndSet(false, true)) {
+ try {
+ starterThread = Thread.currentThread();
+
+ start0(startCtx);
+ }
+ catch (Exception e) {
+ if (log != null)
+ stopExecutors(log);
+
+ throw e;
+ }
+ finally {
+ startLatch.countDown();
+ }
+ }
+ else
+ U.awaitQuiet(startLatch);
+ }
+
+ /**
+ * @param startCtx Starting context.
+ * @throws IgniteCheckedException If start failed.
+ */
+ @SuppressWarnings({"unchecked", "TooBroadScope"})
+ private void start0(GridStartContext startCtx) throws IgniteCheckedException {
+ assert grid == null : "Grid is already started: " + name;
+
+ IgniteConfiguration cfg = startCtx.config();
+
+ if (cfg == null)
+ cfg = new IgniteConfiguration();
+
+ IgniteConfiguration myCfg = new IgniteConfiguration();
+
+ String ggHome = cfg.getGridGainHome();
+
+ // Set GridGain home.
+ if (ggHome == null)
+ ggHome = U.getGridGainHome();
+ else
+ // If user provided GRIDGAIN_HOME - set it as a system property.
+ U.setGridGainHome(ggHome);
+
+ U.setWorkDirectory(cfg.getWorkDirectory(), ggHome);
+
+ /*
+ * Set up all defaults and perform all checks.
+ */
+
+ // Ensure invariant.
+ // It's a bit dirty - but this is a result of late refactoring
+ // and I don't want to reshuffle a lot of code.
+ assert F.eq(name, cfg.getGridName());
+
+ // Set configuration URL, if any, into system property.
+ if (startCtx.configUrl() != null)
+ System.setProperty(GG_CONFIG_URL, startCtx.configUrl().toString());
+
+ myCfg.setGridName(cfg.getGridName());
+
+ UUID nodeId = cfg.getNodeId();
+
+ if (nodeId == null)
+ nodeId = UUID.randomUUID();
+
+ IgniteLogger cfgLog = initLogger(cfg.getGridLogger(), nodeId);
+
+ assert cfgLog != null;
+
+ cfgLog = new GridLoggerProxy(cfgLog, null, name, U.id8(nodeId));
+
+ // Initialize factory's log.
+ log = cfgLog.getLogger(G.class);
+
+ // Check GridGain home folder (after log is available).
+ if (ggHome != null) {
+ File ggHomeFile = new File(ggHome);
+
+ if (!ggHomeFile.exists() || !ggHomeFile.isDirectory())
+ throw new IgniteCheckedException("Invalid GridGain installation home folder: " + ggHome);
+ }
+
+ myCfg.setGridGainHome(ggHome);
+
+ // Copy values that don't need extra processing.
+ myCfg.setLicenseUrl(cfg.getLicenseUrl());
+ myCfg.setPeerClassLoadingEnabled(cfg.isPeerClassLoadingEnabled());
+ myCfg.setDeploymentMode(cfg.getDeploymentMode());
+ myCfg.setNetworkTimeout(cfg.getNetworkTimeout());
+ myCfg.setClockSyncSamples(cfg.getClockSyncSamples());
+ myCfg.setClockSyncFrequency(cfg.getClockSyncFrequency());
+ myCfg.setDiscoveryStartupDelay(cfg.getDiscoveryStartupDelay());
+ myCfg.setMetricsHistorySize(cfg.getMetricsHistorySize());
+ myCfg.setMetricsExpireTime(cfg.getMetricsExpireTime());
+ myCfg.setMetricsUpdateFrequency(cfg.getMetricsUpdateFrequency());
+ myCfg.setLifecycleBeans(cfg.getLifecycleBeans());
+ myCfg.setLocalEventListeners(cfg.getLocalEventListeners());
+ myCfg.setPeerClassLoadingMissedResourcesCacheSize(cfg.getPeerClassLoadingMissedResourcesCacheSize());
+ myCfg.setIncludeEventTypes(cfg.getIncludeEventTypes());
+ myCfg.setDaemon(cfg.isDaemon());
+ myCfg.setIncludeProperties(cfg.getIncludeProperties());
+ myCfg.setLifeCycleEmailNotification(cfg.isLifeCycleEmailNotification());
+ myCfg.setMetricsLogFrequency(cfg.getMetricsLogFrequency());
+ myCfg.setNetworkSendRetryDelay(cfg.getNetworkSendRetryDelay());
+ myCfg.setNetworkSendRetryCount(cfg.getNetworkSendRetryCount());
+ myCfg.setSecurityCredentialsProvider(cfg.getSecurityCredentialsProvider());
+ myCfg.setServiceConfiguration(cfg.getServiceConfiguration());
+ myCfg.setWarmupClosure(cfg.getWarmupClosure());
+ myCfg.setInteropConfiguration(cfg.getInteropConfiguration());
+ myCfg.setPluginConfigurations(cfg.getPluginConfigurations());
+ myCfg.setTransactionsConfiguration(new TransactionsConfiguration(cfg.getTransactionsConfiguration()));
+ myCfg.setQueryConfiguration(cfg.getQueryConfiguration());
+
+ ClientConnectionConfiguration clientCfg = cfg.getClientConnectionConfiguration();
+
+ if (clientCfg == null) {
+ // If client config is not provided then create config copying values from GridConfiguration.
+ if (cfg.isRestEnabled()) {
+ clientCfg = new ClientConnectionConfiguration();
+
+ clientCfg.setClientMessageInterceptor(cfg.getClientMessageInterceptor());
+ clientCfg.setRestAccessibleFolders(cfg.getRestAccessibleFolders());
+ clientCfg.setRestExecutorService(cfg.getRestExecutorService());
+ clientCfg.setRestExecutorServiceShutdown(cfg.getRestExecutorServiceShutdown());
+ clientCfg.setRestIdleTimeout(cfg.getRestIdleTimeout());
+ clientCfg.setRestJettyPath(cfg.getRestJettyPath());
+ clientCfg.setRestPortRange(cfg.getRestPortRange());
+ clientCfg.setRestSecretKey(cfg.getRestSecretKey());
+ clientCfg.setRestTcpDirectBuffer(cfg.isRestTcpDirectBuffer());
+ clientCfg.setRestTcpHost(cfg.getRestTcpHost());
+ clientCfg.setRestTcpNoDelay(cfg.isRestTcpNoDelay());
+ clientCfg.setRestTcpPort(cfg.getRestTcpPort());
+ clientCfg.setRestTcpReceiveBufferSize(cfg.getRestTcpReceiveBufferSize());
+ clientCfg.setRestTcpSelectorCount(cfg.getRestTcpSelectorCount());
+ clientCfg.setRestTcpSendBufferSize(cfg.getRestTcpSendBufferSize());
+ clientCfg.setRestTcpSendQueueLimit(cfg.getRestTcpSendQueueLimit());
+ clientCfg.setRestTcpSslClientAuth(cfg.isRestTcpSslClientAuth());
+ clientCfg.setRestTcpSslContextFactory(cfg.getRestTcpSslContextFactory());
+ clientCfg.setRestTcpSslEnabled(cfg.isRestTcpSslEnabled());
+ }
+ }
+ else
+ clientCfg = new ClientConnectionConfiguration(clientCfg);
+
+
+ String ntfStr = IgniteSystemProperties.getString(GG_LIFECYCLE_EMAIL_NOTIFY);
+
+ if (ntfStr != null)
+ myCfg.setLifeCycleEmailNotification(Boolean.parseBoolean(ntfStr));
+
+ // Local host.
+ String locHost = IgniteSystemProperties.getString(GG_LOCAL_HOST);
+
+ myCfg.setLocalHost(F.isEmpty(locHost) ? cfg.getLocalHost() : locHost);
+
+ // Override daemon flag if it was set on the factory.
+ if (daemon)
+ myCfg.setDaemon(true);
+
+ // Check for deployment mode override.
+ String depModeName = IgniteSystemProperties.getString(GG_DEP_MODE_OVERRIDE);
+
+ if (!F.isEmpty(depModeName)) {
+ if (!F.isEmpty(cfg.getCacheConfiguration())) {
+ U.quietAndInfo(log, "Skipping deployment mode override for caches (custom closure " +
+ "execution may not work for console Visor)");
+ }
+ else {
+ try {
+ IgniteDeploymentMode depMode = IgniteDeploymentMode.valueOf(depModeName);
+
+ if (myCfg.getDeploymentMode() != depMode)
+ myCfg.setDeploymentMode(depMode);
+ }
+ catch (IllegalArgumentException e) {
+ throw new IgniteCheckedException("Failed to override deployment mode using system property " +
+ "(are there any misspellings?)" +
+ "[name=" + GG_DEP_MODE_OVERRIDE + ", value=" + depModeName + ']', e);
+ }
+ }
+ }
+
+ Map<String, ?> attrs = cfg.getUserAttributes();
+
+ if (attrs == null)
+ attrs = Collections.emptyMap();
+
+ MBeanServer mbSrv = cfg.getMBeanServer();
+
+ IgniteMarshaller marsh = cfg.getMarshaller();
+
+ String[] p2pExclude = cfg.getPeerClassLoadingLocalClassPathExclude();
+
+ CommunicationSpi commSpi = cfg.getCommunicationSpi();
+ DiscoverySpi discoSpi = cfg.getDiscoverySpi();
+ EventStorageSpi evtSpi = cfg.getEventStorageSpi();
+ CollisionSpi colSpi = cfg.getCollisionSpi();
+ AuthenticationSpi authSpi = cfg.getAuthenticationSpi();
+ SecureSessionSpi sesSpi = cfg.getSecureSessionSpi();
+ DeploymentSpi deploySpi = cfg.getDeploymentSpi();
+ CheckpointSpi[] cpSpi = cfg.getCheckpointSpi();
+ FailoverSpi[] failSpi = cfg.getFailoverSpi();
+ LoadBalancingSpi[] loadBalancingSpi = cfg.getLoadBalancingSpi();
+ SwapSpaceSpi swapspaceSpi = cfg.getSwapSpaceSpi();
+ GridIndexingSpi indexingSpi = cfg.getIndexingSpi();
+
+ execSvc = cfg.getExecutorService();
+ sysExecSvc = cfg.getSystemExecutorService();
+ p2pExecSvc = cfg.getPeerClassLoadingExecutorService();
+ mgmtExecSvc = cfg.getManagementExecutorService();
+ ggfsExecSvc = cfg.getGgfsExecutorService();
+
+ if (execSvc == null) {
+ isAutoExecSvc = true;
+
+ execSvc = new IgniteThreadPoolExecutor(
+ "pub-" + cfg.getGridName(),
+ DFLT_PUBLIC_CORE_THREAD_CNT,
+ DFLT_PUBLIC_MAX_THREAD_CNT,
+ DFLT_PUBLIC_KEEP_ALIVE_TIME,
+ new LinkedBlockingQueue<Runnable>(DFLT_PUBLIC_THREADPOOL_QUEUE_CAP));
+
+ // Pre-start all threads as they are guaranteed to be needed.
+ ((ThreadPoolExecutor)execSvc).prestartAllCoreThreads();
+ }
+
+ if (sysExecSvc == null) {
+ isAutoSysSvc = true;
+
+ // Note that since we use 'LinkedBlockingQueue', number of
+ // maximum threads has no effect.
+ sysExecSvc = new IgniteThreadPoolExecutor(
+ "sys-" + cfg.getGridName(),
+ DFLT_SYSTEM_CORE_THREAD_CNT,
+ DFLT_SYSTEM_MAX_THREAD_CNT,
+ DFLT_SYSTEM_KEEP_ALIVE_TIME,
+ new LinkedBlockingQueue<Runnable>(DFLT_SYSTEM_THREADPOOL_QUEUE_CAP));
+
+ // Pre-start all threads as they are guaranteed to be needed.
+ ((ThreadPoolExecutor)sysExecSvc).prestartAllCoreThreads();
+ }
+
+ if (mgmtExecSvc == null) {
+ isAutoMgmtSvc = true;
+
+ // Note that since we use 'LinkedBlockingQueue', number of
+ // maximum threads has no effect.
+ // Note, that we do not pre-start threads here as management pool may
+ // not be needed.
+ mgmtExecSvc = new IgniteThreadPoolExecutor(
+ "mgmt-" + cfg.getGridName(),
+ DFLT_MGMT_THREAD_CNT,
+ DFLT_MGMT_THREAD_CNT,
+ 0,
+ new LinkedBlockingQueue<Runnable>());
+ }
+
+ if (p2pExecSvc == null) {
+ isAutoP2PSvc = true;
+
+ // Note that since we use 'LinkedBlockingQueue', number of
+ // maximum threads has no effect.
+ // Note, that we do not pre-start threads here as class loading pool may
+ // not be needed.
+ p2pExecSvc = new IgniteThreadPoolExecutor(
+ "p2p-" + cfg.getGridName(),
+ DFLT_P2P_THREAD_CNT,
+ DFLT_P2P_THREAD_CNT,
+ 0,
+ new LinkedBlockingQueue<Runnable>());
+ }
+
+ if (ggfsExecSvc == null) {
+ isAutoGgfsSvc = true;
+
+ int procCnt = Runtime.getRuntime().availableProcessors();
+
+ // Note that we do not pre-start threads here as ggfs pool may not be needed.
+ ggfsExecSvc = new IgniteThreadPoolExecutor(
+ "ggfs-" + cfg.getGridName(),
+ procCnt,
+ procCnt,
+ 0,
+ new LinkedBlockingQueue<Runnable>());
+ }
+
+ restExecSvc = clientCfg != null ? clientCfg.getRestExecutorService() : null;
+
+ if (restExecSvc != null && !cfg.isRestEnabled()) {
+ U.warn(log, "REST executor service is configured, but REST is disabled in configuration " +
+ "(safely ignoring).");
+ }
+ else if (restExecSvc == null && clientCfg != null) {
+ isAutoRestSvc = true;
+
+ restExecSvc = new IgniteThreadPoolExecutor(
+ "rest-" + cfg.getGridName(),
+ DFLT_REST_CORE_THREAD_CNT,
+ DFLT_REST_MAX_THREAD_CNT,
+ DFLT_REST_KEEP_ALIVE_TIME,
+ new LinkedBlockingQueue<Runnable>(DFLT_REST_THREADPOOL_QUEUE_CAP)
+ );
+
+ clientCfg.setRestExecutorService(restExecSvc);
+ }
+
+ utilityCacheExecSvc = new IgniteThreadPoolExecutor(
+ "utility-" + cfg.getGridName(),
+ DFLT_SYSTEM_CORE_THREAD_CNT,
+ DFLT_SYSTEM_MAX_THREAD_CNT,
+ DFLT_SYSTEM_KEEP_ALIVE_TIME,
+ new LinkedBlockingQueue<Runnable>(DFLT_SYSTEM_THREADPOOL_QUEUE_CAP));
+
+ execSvcShutdown = cfg.getExecutorServiceShutdown();
+ sysSvcShutdown = cfg.getSystemExecutorServiceShutdown();
+ mgmtSvcShutdown = cfg.getManagementExecutorServiceShutdown();
+ p2pSvcShutdown = cfg.getPeerClassLoadingExecutorServiceShutdown();
+ ggfsSvcShutdown = cfg.getGgfsExecutorServiceShutdown();
+ restSvcShutdown = clientCfg != null && clientCfg.isRestExecutorServiceShutdown();
+
+ if (marsh == null) {
+ if (!U.isHotSpot()) {
+ U.warn(log, "GridOptimizedMarshaller is not supported on this JVM " +
+ "(only Java HotSpot VMs are supported). Switching to standard JDK marshalling - " +
+ "object serialization performance will be significantly slower.",
+ "To enable fast marshalling upgrade to recent 1.6 or 1.7 HotSpot VM release.");
+
+ marsh = new IgniteJdkMarshaller();
+ }
+ else if (!IgniteOptimizedMarshaller.available()) {
+ U.warn(log, "GridOptimizedMarshaller is not supported on this JVM " +
+ "(only recent 1.6 and 1.7 versions HotSpot VMs are supported). " +
+ "To enable fast marshalling upgrade to recent 1.6 or 1.7 HotSpot VM release. " +
+ "Switching to standard JDK marshalling - " +
+ "object serialization performance will be significantly slower.",
+ "To enable fast marshalling upgrade to recent 1.6 or 1.7 HotSpot VM release.");
+
+ marsh = new IgniteJdkMarshaller();
+ }
+ else
+ marsh = new IgniteOptimizedMarshaller();
+ }
+ else if (marsh instanceof IgniteOptimizedMarshaller && !U.isHotSpot()) {
+ U.warn(log, "Using GridOptimizedMarshaller on untested JVM (only Java HotSpot VMs were tested) - " +
+ "object serialization behavior could yield unexpected results.",
+ "Using GridOptimizedMarshaller on untested JVM.");
+ }
+
+ myCfg.setUserAttributes(attrs);
+ myCfg.setMBeanServer(mbSrv == null ? ManagementFactory.getPlatformMBeanServer() : mbSrv);
+ myCfg.setGridLogger(cfgLog);
+ myCfg.setMarshaller(marsh);
+ myCfg.setMarshalLocalJobs(cfg.isMarshalLocalJobs());
+ myCfg.setExecutorService(execSvc);
+ myCfg.setSystemExecutorService(sysExecSvc);
+ myCfg.setManagementExecutorService(mgmtExecSvc);
+ myCfg.setPeerClassLoadingExecutorService(p2pExecSvc);
+ myCfg.setGgfsExecutorService(ggfsExecSvc);
+ myCfg.setExecutorServiceShutdown(execSvcShutdown);
+ myCfg.setSystemExecutorServiceShutdown(sysSvcShutdown);
+ myCfg.setManagementExecutorServiceShutdown(mgmtSvcShutdown);
+ myCfg.setPeerClassLoadingExecutorServiceShutdown(p2pSvcShutdown);
+ myCfg.setGgfsExecutorServiceShutdown(ggfsSvcShutdown);
+ myCfg.setNodeId(nodeId);
+
+ IgniteFsConfiguration[] ggfsCfgs = cfg.getGgfsConfiguration();
+
+ if (ggfsCfgs != null) {
+ IgniteFsConfiguration[] clone = ggfsCfgs.clone();
+
+ for (int i = 0; i < ggfsCfgs.length; i++)
+ clone[i] = new IgniteFsConfiguration(ggfsCfgs[i]);
+
+ myCfg.setGgfsConfiguration(clone);
+ }
+
+ StreamerConfiguration[] streamerCfgs = cfg.getStreamerConfiguration();
+
+ if (streamerCfgs != null) {
+ StreamerConfiguration[] clone = streamerCfgs.clone();
+
+ for (int i = 0; i < streamerCfgs.length; i++)
+ clone[i] = new StreamerConfiguration(streamerCfgs[i]);
+
+ myCfg.setStreamerConfiguration(clone);
+ }
+
+ if (p2pExclude == null)
+ p2pExclude = EMPTY_STR_ARR;
+
+ myCfg.setPeerClassLoadingLocalClassPathExclude(p2pExclude);
+
+ /*
+ * Initialize default SPI implementations.
+ */
+
+ if (commSpi == null)
+ commSpi = new TcpCommunicationSpi();
+
+ if (discoSpi == null)
+ discoSpi = new TcpDiscoverySpi();
+
+ if (discoSpi instanceof TcpDiscoverySpi) {
+ TcpDiscoverySpi tcpDisco = (TcpDiscoverySpi)discoSpi;
+
+ if (tcpDisco.getIpFinder() == null)
+ tcpDisco.setIpFinder(new TcpDiscoveryMulticastIpFinder());
+ }
+
+ if (evtSpi == null)
+ evtSpi = new MemoryEventStorageSpi();
+
+ if (colSpi == null)
+ colSpi = new NoopCollisionSpi();
+
+ if (authSpi == null)
+ authSpi = new NoopAuthenticationSpi();
+
+ if (sesSpi == null)
+ sesSpi = new NoopSecureSessionSpi();
+
+ if (deploySpi == null)
+ deploySpi = new LocalDeploymentSpi();
+
+ if (cpSpi == null)
+ cpSpi = new CheckpointSpi[] {new NoopCheckpointSpi()};
+
+ if (failSpi == null)
+ failSpi = new FailoverSpi[] {new AlwaysFailoverSpi()};
+
+ if (loadBalancingSpi == null)
+ loadBalancingSpi = new LoadBalancingSpi[] {new RoundRobinLoadBalancingSpi()};
+
+ if (swapspaceSpi == null) {
+ boolean needSwap = false;
+
+ CacheConfiguration[] caches = cfg.getCacheConfiguration();
+
+ if (caches != null) {
+ for (CacheConfiguration c : caches) {
+ if (c.isSwapEnabled()) {
+ needSwap = true;
+
+ break;
+ }
+ }
+ }
+
+ swapspaceSpi = needSwap ? new FileSwapSpaceSpi() : new NoopSwapSpaceSpi();
+ }
+
+ if (indexingSpi == null)
+ indexingSpi = new GridNoopIndexingSpi();
+
+ myCfg.setCommunicationSpi(commSpi);
+ myCfg.setDiscoverySpi(discoSpi);
+ myCfg.setCheckpointSpi(cpSpi);
+ myCfg.setEventStorageSpi(evtSpi);
+ myCfg.setAuthenticationSpi(authSpi);
+ myCfg.setSecureSessionSpi(sesSpi);
+ myCfg.setDeploymentSpi(deploySpi);
+ myCfg.setFailoverSpi(failSpi);
+ myCfg.setCollisionSpi(colSpi);
+ myCfg.setLoadBalancingSpi(loadBalancingSpi);
+ myCfg.setSwapSpaceSpi(swapspaceSpi);
+ myCfg.setIndexingSpi(indexingSpi);
+
+ myCfg.setAddressResolver(cfg.getAddressResolver());
+
+ // Set SMTP configuration.
+ myCfg.setSmtpFromEmail(cfg.getSmtpFromEmail());
+ myCfg.setSmtpHost(cfg.getSmtpHost());
+ myCfg.setSmtpPort(cfg.getSmtpPort());
+ myCfg.setSmtpSsl(cfg.isSmtpSsl());
+ myCfg.setSmtpUsername(cfg.getSmtpUsername());
+ myCfg.setSmtpPassword(cfg.getSmtpPassword());
+ myCfg.setAdminEmails(cfg.getAdminEmails());
+
+ // REST configuration.
+ myCfg.setClientConnectionConfiguration(clientCfg);
+
+ // Portable configuration.
+ myCfg.setPortableConfiguration(cfg.getPortableConfiguration());
+
+ // Hadoop configuration.
+ myCfg.setHadoopConfiguration(cfg.getHadoopConfiguration());
+
+ // Validate segmentation configuration.
+ GridSegmentationPolicy segPlc = cfg.getSegmentationPolicy();
+
+ // 1. Warn on potential configuration problem: grid is not configured to wait
+ // for correct segment after segmentation happens.
+ if (!F.isEmpty(cfg.getSegmentationResolvers()) && segPlc == RESTART_JVM && !cfg.isWaitForSegmentOnStart()) {
+ U.warn(log, "Found potential configuration problem (forgot to enable waiting for segment" +
+ "on start?) [segPlc=" + segPlc + ", wait=false]");
+ }
+
+ myCfg.setSegmentationResolvers(cfg.getSegmentationResolvers());
+ myCfg.setSegmentationPolicy(segPlc);
+ myCfg.setSegmentCheckFrequency(cfg.getSegmentCheckFrequency());
+ myCfg.setWaitForSegmentOnStart(cfg.isWaitForSegmentOnStart());
+ myCfg.setAllSegmentationResolversPassRequired(cfg.isAllSegmentationResolversPassRequired());
+
+ // Override SMTP configuration from system properties
+ // and environment variables, if specified.
+ String fromEmail = IgniteSystemProperties.getString(GG_SMTP_FROM);
+
+ if (fromEmail != null)
+ myCfg.setSmtpFromEmail(fromEmail);
+
+ String smtpHost = IgniteSystemProperties.getString(GG_SMTP_HOST);
+
+ if (smtpHost != null)
+ myCfg.setSmtpHost(smtpHost);
+
+ String smtpUsername = IgniteSystemProperties.getString(GG_SMTP_USERNAME);
+
+ if (smtpUsername != null)
+ myCfg.setSmtpUsername(smtpUsername);
+
+ String smtpPwd = IgniteSystemProperties.getString(GG_SMTP_PWD);
+
+ if (smtpPwd != null)
+ myCfg.setSmtpPassword(smtpPwd);
+
+ int smtpPort = IgniteSystemProperties.getInteger(GG_SMTP_PORT, -1);
+
+ if(smtpPort != -1)
+ myCfg.setSmtpPort(smtpPort);
+
+ myCfg.setSmtpSsl(IgniteSystemProperties.getBoolean(GG_SMTP_SSL));
+
+ String adminEmails = IgniteSystemProperties.getString(GG_ADMIN_EMAILS);
+
+ if (adminEmails != null)
+ myCfg.setAdminEmails(adminEmails.split(","));
+
+ CacheConfiguration[] cacheCfgs = cfg.getCacheConfiguration();
+
+ boolean hasHadoop = IgniteComponentType.HADOOP.inClassPath();
+
+ CacheConfiguration[] copies;
+
+ if (cacheCfgs != null && cacheCfgs.length > 0) {
+ if (!U.discoOrdered(discoSpi) && !U.relaxDiscoveryOrdered())
+ throw new IgniteCheckedException("Discovery SPI implementation does not support node ordering and " +
+ "cannot be used with cache (use SPI with @GridDiscoverySpiOrderSupport annotation, " +
+ "like GridTcpDiscoverySpi)");
+
+ for (CacheConfiguration ccfg : cacheCfgs) {
+ if (CU.isHadoopSystemCache(ccfg.getName()))
+ throw new IgniteCheckedException("Cache name cannot be \"" + CU.SYS_CACHE_HADOOP_MR +
+ "\" because it is reserved for internal purposes.");
+
+ if (CU.isUtilityCache(ccfg.getName()))
+ throw new IgniteCheckedException("Cache name cannot start with \"" + CU.UTILITY_CACHE_NAME +
+ "\" because this prefix is reserved for internal purposes.");
+ }
+
+ copies = new CacheConfiguration[cacheCfgs.length + (hasHadoop ? 2 : 1)];
+
+ int cloneIdx = 1;
+
+ if (hasHadoop)
+ copies[cloneIdx++] = CU.hadoopSystemCache();
+
+ for (CacheConfiguration ccfg : cacheCfgs)
+ copies[cloneIdx++] = new CacheConfiguration(ccfg);
+ }
+ else if (hasHadoop) {
+ // Populate system caches
+ copies = new CacheConfiguration[hasHadoop ? 2 : 1];
+
+ copies[1] = CU.hadoopSystemCache();
+ }
+ else
+ copies = new CacheConfiguration[1];
+
+ // Always add utility cache.
+ copies[0] = utilitySystemCache(discoSpi instanceof TcpClientDiscoverySpi);
+
+ myCfg.setCacheConfiguration(copies);
+
+ myCfg.setCacheSanityCheckEnabled(cfg.isCacheSanityCheckEnabled());
+
+ try {
+ // Use reflection to avoid loading undesired classes.
+ Class helperCls = Class.forName("org.gridgain.grid.util.GridConfigurationHelper");
+
+ helperCls.getMethod("overrideConfiguration", IgniteConfiguration.class, Properties.class,
+ String.class, IgniteLogger.class).invoke(helperCls, myCfg, System.getProperties(), name, log);
+ }
+ catch (Exception ignored) {
+ // No-op.
+ }
+
+ // Ensure that SPIs support multiple grid instances, if required.
+ if (!startCtx.single()) {
+ ensureMultiInstanceSupport(deploySpi);
+ ensureMultiInstanceSupport(commSpi);
+ ensureMultiInstanceSupport(discoSpi);
+ ensureMultiInstanceSupport(cpSpi);
+ ensureMultiInstanceSupport(evtSpi);
+ ensureMultiInstanceSupport(colSpi);
+ ensureMultiInstanceSupport(failSpi);
+ ensureMultiInstanceSupport(authSpi);
+ ensureMultiInstanceSupport(sesSpi);
+ ensureMultiInstanceSupport(loadBalancingSpi);
+ ensureMultiInstanceSupport(swapspaceSpi);
+ }
+
+ // Register GridGain MBean for current grid instance.
+ registerFactoryMbean(myCfg.getMBeanServer());
+
+ boolean started = false;
+
+ try {
+ IgniteKernal grid0 = new IgniteKernal(startCtx.springContext());
+
+ // Init here to make grid available to lifecycle listeners.
+ grid = grid0;
+
+ grid0.start(myCfg, utilityCacheExecSvc, new CA() {
+ @Override public void apply() {
+ startLatch.countDown();
+ }
+ });
+
+ state = STARTED;
+
+ if (log.isDebugEnabled())
+ log.debug("Grid factory started ok: " + name);
+
+ started = true;
+ }
+ catch (IgniteCheckedException e) {
+ unregisterFactoryMBean();
+
+ throw e;
+ }
+ // Catch Throwable to protect against any possible failure.
+ catch (Throwable e) {
+ unregisterFactoryMBean();
+
+ throw new IgniteCheckedException("Unexpected exception when starting grid.", e);
+ }
+ finally {
+ if (!started)
+ // Grid was not started.
+ grid = null;
+ }
+
+ // Do NOT set it up only if GRIDGAIN_NO_SHUTDOWN_HOOK=TRUE is provided.
+ if (!IgniteSystemProperties.getBoolean(GG_NO_SHUTDOWN_HOOK, false)) {
+ try {
+ Runtime.getRuntime().addShutdownHook(shutdownHook = new Thread() {
+ @Override public void run() {
+ if (log.isInfoEnabled())
+ log.info("Invoking shutdown hook...");
+
+ IgniteNamedInstance.this.stop(true);
+ }
+ });
+
+ if (log.isDebugEnabled())
+ log.debug("Shutdown hook is installed.");
+ }
+ catch (IllegalStateException e) {
+ stop(true);
+
+ throw new IgniteCheckedException("Failed to install shutdown hook.", e);
+ }
+ }
+ else {
+ if (log.isDebugEnabled())
+ log.debug("Shutdown hook has not been installed because environment " +
+ "or system property " + GG_NO_SHUTDOWN_HOOK + " is set.");
+ }
+ }
+
+ /**
+ * @param cfgLog Configured logger.
+ * @param nodeId Local node ID.
+ * @return Initialized logger.
+ * @throws IgniteCheckedException If failed.
+ */
+ private IgniteLogger initLogger(@Nullable IgniteLogger cfgLog, UUID nodeId) throws IgniteCheckedException {
+ try {
+ if (cfgLog == null) {
+ Class<?> log4jCls;
+
+ try {
+ log4jCls = Class.forName("org.gridgain.grid.logger.log4j.GridLog4jLogger");
+ }
+ catch (ClassNotFoundException | NoClassDefFoundError ignored) {
+ log4jCls = null;
+ }
+
+ if (log4jCls != null) {
+ URL url = U.resolveGridGainUrl("config/gridgain-log4j.xml");
+
+ if (url == null) {
+ File cfgFile = new File("config/gridgain-log4j.xml");
+
+ if (!cfgFile.exists())
+ cfgFile = new File("../config/gridgain-log4j.xml");
+
+ if (cfgFile.exists()) {
+ try {
+ url = cfgFile.toURI().toURL();
+ }
+ catch (MalformedURLException ignore) {
+ // No-op.
+ }
+ }
+ }
+
+ if (url != null) {
+ boolean configured = (Boolean)log4jCls.getMethod("isConfigured").invoke(null);
+
+ if (configured)
+ url = null;
+ }
+
+ if (url != null) {
+ Constructor<?> ctor = log4jCls.getConstructor(URL.class);
+
+ cfgLog = (IgniteLogger)ctor.newInstance(url);
+ }
+ else
+ cfgLog = (IgniteLogger)log4jCls.newInstance();
+ }
+ else
+ cfgLog = new IgniteJavaLogger();
+ }
+
+ // Set node IDs for all file appenders.
+ if (cfgLog instanceof IgniteLoggerNodeIdAware)
+ ((IgniteLoggerNodeIdAware)cfgLog).setNodeId(nodeId);
+
+ return cfgLog;
+ }
+ catch (Exception e) {
+ throw new IgniteCheckedException("Failed to create logger.", e);
+ }
+ }
+
+ /**
+ * Creates utility system cache configuration.
+ *
+ * @param client If {@code true} creates client-only cache configuration.
+ * @return Utility system cache configuration.
+ */
+ private CacheConfiguration utilitySystemCache(boolean client) {
+ CacheConfiguration cache = new CacheConfiguration();
+
+ cache.setName(CU.UTILITY_CACHE_NAME);
+ cache.setCacheMode(REPLICATED);
+ cache.setAtomicityMode(TRANSACTIONAL);
+ cache.setSwapEnabled(false);
+ cache.setQueryIndexEnabled(false);
+ cache.setPreloadMode(SYNC);
+ cache.setWriteSynchronizationMode(FULL_SYNC);
+ cache.setAffinity(new CacheRendezvousAffinityFunction(false, 100));
+
+ if (client)
+ cache.setDistributionMode(CLIENT_ONLY);
+
+ return cache;
+ }
+
+ /**
+ * Stops grid.
+ *
+ * @param cancel Flag indicating whether all currently running jobs
+ * should be cancelled.
+ */
+ void stop(boolean cancel) {
+ // Stop cannot be called prior to start from public API,
+ // since it checks for STARTED state. So, we can assert here.
+ assert startGuard.get();
+
+ stop0(cancel);
+ }
+
+ /**
+ * @param cancel Flag indicating whether all currently running jobs
+ * should be cancelled.
+ */
+ private synchronized void stop0(boolean cancel) {
+ IgniteKernal grid0 = grid;
+
+ // Double check.
+ if (grid0 == null) {
+ if (log != null)
+ U.warn(log, "Attempting to stop an already stopped grid instance (ignore): " + name);
+
+ return;
+ }
+
+ if (shutdownHook != null)
+ try {
+ Runtime.getRuntime().removeShutdownHook(shutdownHook);
+
+ shutdownHook = null;
+
+ if (log.isDebugEnabled())
+ log.debug("Shutdown hook is removed.");
+ }
+ catch (IllegalStateException e) {
+ // Shutdown is in progress...
+ if (log.isDebugEnabled())
+ log.debug("Shutdown is in progress (ignoring): " + e.getMessage());
+ }
+
+ // Unregister GridGain MBean.
+ unregisterFactoryMBean();
+
+ try {
+ grid0.stop(cancel);
+
+ if (log.isDebugEnabled())
+
<TRUNCATED>