blob: 9717745a19a3600b63032a415f30fb3a77f4eb53 [file] [log] [blame]
/*
* 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;
import java.io.InputStream;
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Collectors;
import org.apache.ignite.client.ClientException;
import org.apache.ignite.client.IgniteClient;
import org.apache.ignite.configuration.ClientConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.internal.IgnitionEx;
import org.apache.ignite.internal.client.thin.TcpIgniteClient;
import org.apache.ignite.internal.processors.security.sandbox.SandboxIgniteComponentProxy;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.thread.IgniteThread;
import org.jetbrains.annotations.Nullable;
import static org.apache.ignite.internal.processors.security.SecurityUtils.isInsideSandbox;
/**
* This class defines a factory for the main Ignite 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>{@link org.apache.ignite.startup.cmdline.CommandLineStartup}</li>
* <li>{@ignitelink org.apache.ignite.startup.servlet.ServletStartup}</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 custom configuration for <strong>URI deployment</strong>.
* <pre name="code" class="java">
* IgniteConfiguration cfg = new IgniteConfiguration();
*
* GridUriDeployment deploySpi = new GridUriDeployment();
*
* deploySpi.setUriList(Collections.singletonList("classes://tmp/output/classes"));
*
* cfg.setDeploymentSpi(deploySpi);
*
* Ignition.start(cfg);
* </pre>
* Here is how a grid instance can be configured from Spring XML configuration file. The
* example below configures a grid instance with additional user attributes
* (see {@link org.apache.ignite.cluster.ClusterNode#attributes()}) and specifies a Ignite instance name:
* <pre name="code" class="xml">
* &lt;bean id="grid.cfg" class="org.apache.ignite.configuration.IgniteConfiguration"&gt;
* ...
* &lt;property name="igniteInstanceName" value="grid"/&gt;
* &lt;property name="userAttributes"&gt;
* &lt;map&gt;
* &lt;entry key="group" value="worker"/&gt;
* &lt;/map&gt;
* &lt;/property&gt;
* ...
* &lt;/bean&gt;
* </pre>
* A grid instance with Spring configuration above can be started as following. Note that
* you do not need to pass path to Spring XML file if you are using
* {@code IGNITE_HOME/config/default-config.xml}. Also note, that the path can be
* absolute or relative to IGNITE_HOME.
* <pre name="code" class="java">
* ...
* Ignition.start("/path/to/spring/xml/file.xml");
* ...
* </pre>
* You can also instantiate grid directly from Spring without using {@code Ignition}.
* For more information refer to {@ignitelink org.apache.ignite.IgniteSpringBean} documentation.
*/
public class Ignition {
/**
* This is restart code that can be used by external tools, like Shell scripts,
* to auto-restart the Ignite JVM process. Note that there is no standard way
* for a JVM to restart itself from Java application and therefore we rely on
* external tools to provide that capability.
* <p>
* Note that standard <tt>ignite.{sh|bat}</tt> scripts support restarting when
* JVM process exits with this code.
*/
public static final int RESTART_EXIT_CODE = 250;
/**
* This is kill code that can be used by external tools, like Shell scripts,
* to auto-stop the Ignite JVM process without restarting.
*/
public static final int KILL_EXIT_CODE = 130;
/**
* Enforces singleton.
*/
protected Ignition() {
// 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.setDaemon(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 IgnitionEx.isDaemon();
}
/**
* Sets client mode thread-local flag.
* <p>
* This flag used when node is started if {@link IgniteConfiguration#isClientMode()}
* is {@code null}. When {@link IgniteConfiguration#isClientMode()} is set this flag is ignored.
*
* @param clientMode Client mode flag.
* @see IgniteConfiguration#isClientMode()
*/
public static void setClientMode(boolean clientMode) {
IgnitionEx.setClientMode(clientMode);
}
/**
* Gets client mode thread-local flag.
* <p>
* This flag used when node is started if {@link IgniteConfiguration#isClientMode()}
* is {@code null}. When {@link IgniteConfiguration#isClientMode()} is set this flag is ignored.
*
* @return Client mode flag.
* @see IgniteConfiguration#isClientMode()
*/
public static boolean isClientMode() {
return IgnitionEx.isClientMode();
}
/**
* Gets state of grid default grid.
*
* @return Default grid state.
*/
public static IgniteState state() {
return IgnitionEx.state();
}
/**
* Gets states of named Ignite instance. If name is {@code null}, then state of
* default no-name Ignite instance is returned.
*
* @param name Ignite instance name. If name is {@code null}, then state of
* default no-name Ignite instance is returned.
* @return Ignite instance state.
*/
public static IgniteState state(@Nullable String name) {
return IgnitionEx.state(name);
}
/**
* 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 IgnitionEx.stop(cancel, null);
}
/**
* Stops named Ignite instance. If {@code cancel} flag is set to {@code true} then
* all jobs currently executing on local node will be interrupted. If
* Ignite instance name is {@code null}, then default no-name Ignite instance will be stopped.
* If wait parameter is set to {@code true} then Ignite instance will wait for all
* tasks to be finished.
*
* @param name Ignite instance name. If {@code null}, then default no-name Ignite instance 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 Ignite instance was indeed found and stopped,
* {@code false} otherwise (the instance with given {@code name} was
* not found).
*/
public static boolean stop(String name, boolean cancel) {
return IgnitionEx.stop(name, cancel, null, false);
}
/**
* Stops <b>all</b> started grids in current JVM. 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) {
IgnitionEx.stopAll(cancel, null);
}
/**
* 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 Ignite's protocol for restarting. Currently only standard <tt>ignite.{sh|bat}</tt>
* scripts support restarting of JVM Ignite'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 #RESTART_EXIT_CODE
*/
public static void restart(boolean cancel) {
IgnitionEx.restart(cancel);
}
/**
* 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 #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 #KILL_EXIT_CODE
*/
public static void kill(boolean cancel) {
IgnitionEx.kill(cancel);
}
/**
* Starts grid with default configuration. By default this method will
* use grid configuration defined in {@code IGNITE_HOME/config/default-config.xml}
* configuration file. If such file is not found, then all system defaults will be used.
*
* @return Started grid.
* @throws IgniteException 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 IgniteException {
try {
return wrapToProxyIfNeeded(IgnitionEx.start());
}
catch (IgniteCheckedException e) {
throw U.convertException(e);
}
}
/**
* Starts grid with given configuration. Note that this method will throw an exception 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 IgniteException 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 IgniteException {
try {
return wrapToProxyIfNeeded(IgnitionEx.start(cfg));
}
catch (IgniteCheckedException e) {
throw U.convertException(e);
}
}
/**
* 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 IgniteException 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) throws IgniteException {
try {
return wrapToProxyIfNeeded(IgnitionEx.start(springCfgPath));
}
catch (IgniteCheckedException e) {
throw U.convertException(e);
}
}
/**
* 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 IgniteException 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 IgniteException {
try {
return wrapToProxyIfNeeded(IgnitionEx.start(springCfgUrl));
}
catch (IgniteCheckedException e) {
throw U.convertException(e);
}
}
/**
* Starts all grids specified within given Spring XML configuration input stream. 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 input stream will contain only one Grid definition. Note that
* Grid configuration bean(s) is retrieved form configuration input stream by type, so the name of
* the Grid configuration bean is ignored.
*
* @param springCfgStream Input stream containing Spring XML configuration. This cannot be {@code null}.
* @return Started grid. If Spring configuration contains multiple grid instances,
* then the 1st found instance is returned.
* @throws IgniteException 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(InputStream springCfgStream) throws IgniteException {
try {
return wrapToProxyIfNeeded(IgnitionEx.start(springCfgStream));
}
catch (IgniteCheckedException e) {
throw U.convertException(e);
}
}
/**
* Gets or starts new grid instance if it hasn't been started yet.
*
* @param cfg Grid configuration. This cannot be {@code null}.
* @return Grid instance.
* @throws IgniteException If grid could not be started.
*/
public static Ignite getOrStart(IgniteConfiguration cfg) throws IgniteException {
try {
return wrapToProxyIfNeeded(IgnitionEx.start(cfg, false));
}
catch (IgniteCheckedException e) {
throw U.convertException(e);
}
}
/**
* Loads Spring bean by its name from given Spring XML configuration file. If bean
* with such name doesn't exist, exception is thrown.
*
* @param springXmlPath Spring XML configuration file path (cannot be {@code null}).
* @param beanName Bean name (cannot be {@code null}).
* @param <T> Type of the loaded bean.
* @return Loaded bean instance.
* @throws IgniteException If bean with provided name was not found or in case any other error.
*/
public static <T> T loadSpringBean(String springXmlPath, String beanName) throws IgniteException {
try {
return IgnitionEx.loadSpringBean(springXmlPath, beanName);
}
catch (IgniteCheckedException e) {
throw U.convertException(e);
}
}
/**
* Loads Spring bean by its name from given Spring XML configuration file. If bean
* with such name doesn't exist, exception is thrown.
*
* @param springXmlUrl Spring XML configuration file URL (cannot be {@code null}).
* @param beanName Bean name (cannot be {@code null}).
* @param <T> Type of the loaded bean.
* @return Loaded bean instance.
* @throws IgniteException If bean with provided name was not found or in case any other error.
*/
public static <T> T loadSpringBean(URL springXmlUrl, String beanName) throws IgniteException {
try {
return IgnitionEx.loadSpringBean(springXmlUrl, beanName);
}
catch (IgniteCheckedException e) {
throw U.convertException(e);
}
}
/**
* Loads Spring bean by its name from given Spring XML configuration file. If bean
* with such name doesn't exist, exception is thrown.
*
* @param springXmlStream Input stream containing Spring XML configuration (cannot be {@code null}).
* @param beanName Bean name (cannot be {@code null}).
* @param <T> Type of the loaded bean.
* @return Loaded bean instance.
* @throws IgniteException If bean with provided name was not found or in case any other error.
*/
public static <T> T loadSpringBean(InputStream springXmlStream, String beanName) throws IgniteException {
try {
return IgnitionEx.loadSpringBean(springXmlStream, beanName);
}
catch (IgniteCheckedException e) {
throw U.convertException(e);
}
}
/**
* 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.
*
* @return An instance of default no-name grid. This method never returns
* {@code null}.
* @throws IgniteIllegalStateException Thrown if default grid was not properly
* initialized or grid instance was stopped or was not started.
*/
public static Ignite ignite() throws IgniteIllegalStateException {
return wrapToProxyIfNeeded(IgnitionEx.grid());
}
/**
* Gets a list of all grids started so far.
*
* @return List of all grids started so far.
*/
public static List<Ignite> allGrids() {
List<Ignite> res = IgnitionEx.allGrids();
if (F.isEmpty(res))
return res;
if (isInsideSandbox())
return res.stream().map(Ignition::wrapToProxy).collect(Collectors.toList());
return res;
}
/**
* 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 IgniteIllegalStateException Thrown if grid was not properly
* initialized or grid instance was stopped or was not started.
*/
public static Ignite ignite(UUID locNodeId) throws IgniteIllegalStateException {
return wrapToProxyIfNeeded(IgnitionEx.grid(locNodeId));
}
/**
* Gets a named Ignite instance. If Ignite instance name is {@code null} or empty string,
* then default no-name Ignite instance will be returned. Note that caller of this method
* should not assume that it will return the same instance every time.
* <p>
* The name allows having multiple Ignite instances with different names within the same Java VM.
*
* @param name Ignite instance name. If {@code null}, then a default no-name
* Ignite instance will be returned.
* @return A named Ignite instance. This method never returns {@code null}.
* @throws IgniteIllegalStateException Thrown if default Ignite instance was not properly
* initialized or Ignite instance was stopped or was not started.
*/
public static Ignite ignite(@Nullable String name) throws IgniteIllegalStateException {
return wrapToProxyIfNeeded(IgnitionEx.grid(name));
}
/**
* This method is used to address a local {@link Ignite} instance, principally from closure.
* <p>
* According to contract this method has to be called only under {@link IgniteThread}.
* An {@link IllegalArgumentException} will be thrown otherwise.
*
* @return A current {@link Ignite} instance to address from closure.
* @throws IgniteIllegalStateException Thrown if grid was not properly
* initialized or grid instance was stopped or was not started
* @throws IllegalArgumentException Thrown if current thread is not an {@link IgniteThread}.
*/
public static Ignite localIgnite() throws IgniteIllegalStateException, IllegalArgumentException {
return wrapToProxyIfNeeded(IgnitionEx.localIgnite());
}
/**
* @param ignite Ignite.
* @return Ignite component proxy.
*/
private static Ignite wrapToProxy(Ignite ignite) {
return AccessController.doPrivileged((PrivilegedAction<Ignite>)
() -> SandboxIgniteComponentProxy.igniteProxy(ignite)
);
}
/**
* @param ignite Ignite.
* @return Ignite component proxy if the Ignite Sandbox is enabled.
*/
private static Ignite wrapToProxyIfNeeded(Ignite ignite) {
return isInsideSandbox() ? wrapToProxy(ignite) : ignite;
}
/**
* Adds a lsnr for grid life cycle events.
* <p>
* Note that unlike other listeners in Ignite 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(IgnitionListener lsnr) {
IgnitionEx.addListener(lsnr);
}
/**
* Removes lsnr added by {@link #addListener(IgnitionListener)} method.
*
* @param lsnr Listener to remove.
* @return {@code true} if lsnr was added before, {@code false} otherwise.
*/
public static boolean removeListener(IgnitionListener lsnr) {
return IgnitionEx.removeListener(lsnr);
}
/**
* Initializes new instance of {@link IgniteClient}.
*
* @param cfg Thin client configuration.
* @return Client with successfully opened thin client connection.
*/
public static IgniteClient startClient(ClientConfiguration cfg) throws ClientException {
Objects.requireNonNull(cfg, "cfg");
return TcpIgniteClient.start(cfg);
}
}