Repository: incubator-ignite Updated Branches: refs/heads/sprint-2 5a2d62e6d -> af603c00f
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/af603c00/docs/wiki/distributed-data-structures/id-generator.md ---------------------------------------------------------------------- diff --git a/docs/wiki/distributed-data-structures/id-generator.md b/docs/wiki/distributed-data-structures/id-generator.md new file mode 100755 index 0000000..f45b19b --- /dev/null +++ b/docs/wiki/distributed-data-structures/id-generator.md @@ -0,0 +1,40 @@ +Distributed atomic sequence provided by `IgniteCacheAtomicSequence` interface is similar to distributed atomic long, but its value can only go up. It also supports reserving a range of values to avoid costly network trips or cache updates every time a sequence must provide a next value. That is, when you perform `incrementAndGet()` (or any other atomic operation) on an atomic sequence, the data structure reserves ahead a range of values, which are guaranteed to be unique across the cluster for this sequence instance. + +Here is an example of how atomic sequence can be created: +[block:code] +{ + "codes": [ + { + "code": "Ignite ignite = Ignition.ignite();\n \nIgniteAtomicSequence seq = ignite.atomicSequence(\n \"seqName\", // Sequence name.\n 0, // Initial value for sequence.\n true // Create if it does not exist.\n);", + "language": "java" + } + ] +} +[/block] +Below is a simple usage example: +[block:code] +{ + "codes": [ + { + "code": "Ignite ignite = Ignition.ignite();\n\n// Initialize atomic sequence.\nfinal IgniteAtomicSequence seq = ignite.atomicSequence(\"seqName\", 0, true);\n\n// Increment atomic sequence.\nfor (int i = 0; i < 20; i++) {\n long currentValue = seq.get();\n long newValue = seq.incrementAndGet();\n \n ...\n}", + "language": "java" + } + ] +} +[/block] + +[block:api-header] +{ + "type": "basic", + "title": "Sequence Reserve Size" +} +[/block] +The key parameter of `IgniteAtomicSequence` is `atomicSequenceReserveSize` which is the number of sequence values reserved, per node . When a node tries to obtain an instance of `IgniteAtomicSequence`, a number of sequence values will be reserved for that node and consequent increments of sequence will happen locally without communication with other nodes, until the next reservation has to be made. + +The default value for `atomicSequenceReserveSize` is `1000`. This default setting can be changed by modifying the `atomicSequenceReserveSize` property of `AtomicConfiguration`. +[block:callout] +{ + "type": "info", + "body": "Refer to [Atomic Configuration](/docs/atomic-types#atomic-configuration) for more information on various atomic configuration properties, and examples on how to configure them." +} +[/block] \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/af603c00/docs/wiki/distributed-data-structures/queue-and-set.md ---------------------------------------------------------------------- diff --git a/docs/wiki/distributed-data-structures/queue-and-set.md b/docs/wiki/distributed-data-structures/queue-and-set.md new file mode 100755 index 0000000..b61efee --- /dev/null +++ b/docs/wiki/distributed-data-structures/queue-and-set.md @@ -0,0 +1,116 @@ +Ignite In-Memory Data Fabric, in addition to providing standard key-value map-like storage, also provides an implementation of a fast Distributed Blocking Queue and Distributed Set. + +`IgniteQueue` and `IgniteSet`, an implementation of `java.util.concurrent.BlockingQueue` and `java.util.Set` interface respectively, also support all operations from `java.util.Collection` interface. Both, queue and set can be created in either collocated or non-collocated mode. + +Below is an example of how to create a distributed queue and set. +[block:code] +{ + "codes": [ + { + "code": "Ignite ignite = Ignition.ignite();\n\nIgniteQueue<String> queue = ignite.queue(\n \"queueName\", // Queue name.\n 0, // Queue capacity. 0 for unbounded queue.\n null // Collection configuration.\n);", + "language": "java", + "name": "Queue" + }, + { + "code": "Ignite ignite = Ignition.ignite();\n\nIgniteSet<String> set = ignite.set(\n \"setName\", // Queue name.\n null // Collection configuration.\n);", + "language": "java", + "name": "Set" + } + ] +} +[/block] + +[block:api-header] +{ + "type": "basic", + "title": "Collocated vs. Non-Collocated Mode" +} +[/block] +If you plan to create just a few queues or sets containing lots of data, then you would create them in non-collocated mode. This will make sure that about equal portion of each queue or set will be stored on each cluster node. On the other hand, if you plan to have many queues or sets, relatively small in size (compared to the whole cache), then you would most likely create them in collocated mode. In this mode all queue or set elements will be stored on the same cluster node, but about equal amount of queues/sets will be assigned to every node. +A collocated queue and set can be created by setting the `collocated` property of `CollectionConfiguration`, like so: +[block:code] +{ + "codes": [ + { + "code": "Ignite ignite = Ignition.ignite();\n\nCollectionConfiguration colCfg = new CollectionConfiguration();\n\ncolCfg.setCollocated(true); \n\n// Create collocated queue.\nIgniteQueue<String> queue = ignite.queue(\"queueName\", 0, colCfg);\n\n// Create collocated set.\nIgniteSet<String> set = ignite.set(\"setName\", colCfg);", + "language": "java", + "name": "Queue" + }, + { + "code": "Ignite ignite = Ignition.ignite();\n\nCollectionConfiguration colCfg = new CollectionConfiguration();\n\ncolCfg.setCollocated(true); \n\n// Create collocated set.\nIgniteSet<String> set = ignite.set(\"setName\", colCfg);", + "language": "text", + "name": "Set" + } + ] +} +[/block] + +[block:callout] +{ + "type": "info", + "title": "", + "body": "Non-collocated mode only makes sense for and is only supported for `PARTITIONED` caches." +} +[/block] + +[block:api-header] +{ + "type": "basic", + "title": "Bounded Queues" +} +[/block] +Bounded queues allow users to have many queues with maximum size which gives a better control over the overall cache capacity. They can be either *collocated* or *non-collocated*. When bounded queues are relatively small and used in collocated mode, all queue operations become extremely fast. Moreover, when used in combination with compute grid, users can collocate their compute jobs with cluster nodes on which queues are located to make sure that all operations are local and there is none (or minimal) data distribution. + +Here is an example of how a job could be send directly to the node on which a queue resides: +[block:code] +{ + "codes": [ + { + "code": "Ignite ignite = Ignition.ignite();\n\nCollectionConfiguration colCfg = new CollectionConfiguration();\n\ncolCfg.setCollocated(true); \n\ncolCfg.setCacheName(\"cacheName\");\n\nfinal IgniteQueue<String> queue = ignite.queue(\"queueName\", 20, colCfg);\n \n// Add queue elements (queue is cached on some node).\nfor (int i = 0; i < 20; i++)\n queue.add(\"Value \" + Integer.toString(i));\n \nIgniteRunnable queuePoller = new IgniteRunnable() {\n @Override public void run() throws IgniteException {\n // Poll is local operation due to collocation.\n for (int i = 0; i < 20; i++)\n System.out.println(\"Polled element: \" + queue.poll());\n }\n};\n\n// Drain queue on the node where the queue is cached.\nignite.compute().affinityRun(\"cacheName\", \"queueName\", queuePoller);", + "language": "java", + "name": "Queue" + } + ] +} +[/block] + +[block:callout] +{ + "type": "success", + "body": "Refer to [Collocate Compute and Data](doc:collocate-compute-and-data) section for more information on collocating computations with data." +} +[/block] + +[block:api-header] +{ + "type": "basic", + "title": "Cache Queues and Load Balancing" +} +[/block] +Given that elements will remain in the queue until someone takes them, and that no two nodes should ever receive the same element from the queue, cache queues can be used as an alternate work distribution and load balancing approach within Ignite. + +For example, you could simply add computations, such as instances of `IgniteRunnable` to a queue, and have threads on remote nodes call `IgniteQueue.take()` method which will block if queue is empty. Once the `take()` method will return a job, a thread will process it and call `take()` again to get the next job. Given this approach, threads on remote nodes will only start working on the next job when they have completed the previous one, hence creating ideally balanced system where every node only takes the number of jobs it can process, and not more. +[block:api-header] +{ + "type": "basic", + "title": "Collection Configuration" +} +[/block] +Ignite collections can be in configured in API via `CollectionConfiguration` (see above examples). The following configuration parameters can be used: +[block:parameters] +{ + "data": { + "h-0": "Setter Method", + "0-0": "`setCollocated(boolean)`", + "1-0": "`setCacheName(String)`", + "h-1": "Description", + "h-2": "Default", + "0-2": "false", + "0-1": "Sets collocation mode.", + "1-1": "Set name of the cache to store this collection.", + "1-2": "null" + }, + "cols": 3, + "rows": 2 +} +[/block] \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/af603c00/docs/wiki/distributed-events/automatic-batching.md ---------------------------------------------------------------------- diff --git a/docs/wiki/distributed-events/automatic-batching.md b/docs/wiki/distributed-events/automatic-batching.md new file mode 100755 index 0000000..54f9383 --- /dev/null +++ b/docs/wiki/distributed-events/automatic-batching.md @@ -0,0 +1,16 @@ +Ignite automatically groups or batches event notifications that are generated as a result of cache events occurring within the cluster. + +Each activity in cache can result in an event notification being generated and sent. For systems where cache activity is high, getting notified for every event could be network intensive, possibly leading to a decreased performance of cache operations in the grid. + +In Ignite, event notifications can be grouped together and sent in batches or timely intervals. Here is an example of how this can be done: + +[block:code] +{ + "codes": [ + { + "code": "Ignite ignite = Ignition.ignite();\n \n// Get an instance of named cache.\nfinal IgniteCache<Integer, String> cache = ignite.jcache(\"cacheName\");\n \n// Sample remote filter which only accepts events for keys\n// that are greater than or equal to 10.\nIgnitePredicate<CacheEvent> rmtLsnr = new IgnitePredicate<CacheEvent>() {\n @Override public boolean apply(CacheEvent evt) {\n System.out.println(\"Cache event: \" + evt);\n \n int key = evt.key();\n \n return key >= 10;\n }\n};\n \n// Subscribe to cache events occuring on all nodes \n// that have the specified cache running. \n// Send notifications in batches of 10.\nignite.events(ignite.cluster().forCacheNodes(\"cacheName\")).remoteListen(\n\t\t10 /*batch size*/, 0 /*time intervals*/, false, null, rmtLsnr, EVTS_CACHE);\n \n// Generate cache events.\nfor (int i = 0; i < 20; i++)\n cache.put(i, Integer.toString(i));", + "language": "java" + } + ] +} +[/block] \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/af603c00/docs/wiki/distributed-events/events.md ---------------------------------------------------------------------- diff --git a/docs/wiki/distributed-events/events.md b/docs/wiki/distributed-events/events.md new file mode 100755 index 0000000..7b613b8 --- /dev/null +++ b/docs/wiki/distributed-events/events.md @@ -0,0 +1,101 @@ +Ignite distributed events functionality allows applications to receive notifications when a variety of events occur in the distributed grid environment. You can automatically get notified for task executions, read, write or query operations occurring on local or remote nodes within the cluster. + +Distributed events functionality is provided via `IgniteEvents` interface. You can get an instance of `IgniteEvents` from Ignite as follows: +[block:code] +{ + "codes": [ + { + "code": "Ignite ignite = Ignition.ignite();\n\nIgniteEvents evts = ignite.events();", + "language": "java" + } + ] +} +[/block] + +[block:api-header] +{ + "type": "basic", + "title": "Subscribe for Events" +} +[/block] +Listen methods can be used to receive notification for specified events happening in the cluster. These methods register a listener on local or remotes nodes for the specified events. Whenever the event occurs on the node, the listener is notified. +##Local Events +`localListen(...)` method registers event listeners with specified events on local node only. +##Remote Events +`remoteListen(...)` method registers event listeners with specified events on all nodes within the cluster or cluster group. Following is an example of each method: +[block:code] +{ + "codes": [ + { + "code": "Ignite ignite = Ignition.ignite();\n\n// Local listener that listenes to local events.\nIgnitePredicate<CacheEvent> locLsnr = evt -> {\n System.out.println(\"Received event [evt=\" + evt.name() + \", key=\" + evt.key() + \n \", oldVal=\" + evt.oldValue() + \", newVal=\" + evt.newValue());\n\n return true; // Continue listening.\n};\n\n// Subscribe to specified cache events occuring on local node.\nignite.events().localListen(locLsnr,\n EventType.EVT_CACHE_OBJECT_PUT,\n EventType.EVT_CACHE_OBJECT_READ,\n EventType.EVT_CACHE_OBJECT_REMOVED);\n\n// Get an instance of named cache.\nfinal IgniteCache<Integer, String> cache = ignite.jcache(\"cacheName\");\n\n// Generate cache events.\nfor (int i = 0; i < 20; i++)\n cache.put(i, Integer.toString(i));\n", + "language": "java", + "name": "local listen" + }, + { + "code": "Ignite ignite = Ignition.ignite();\n\n// Get an instance of named cache.\nfinal IgniteCache<Integer, String> cache = ignite.jcache(\"cacheName\");\n\n// Sample remote filter which only accepts events for keys\n// that are greater than or equal to 10.\nIgnitePredicate<CacheEvent> rmtLsnr = evt -> evt.<Integer>key() >= 10;\n\n// Subscribe to specified cache events on all nodes that have cache running.\nignite.events(ignite.cluster().forCacheNodes(\"cacheName\")).remoteListen(null, rmtLsnr, EventType.EVT_CACHE_OBJECT_PUT,\n EventType.EVT_CACHE_OBJECT_READ,\n EventType.EVT_CACHE_OBJECT_REMOVED);\n\n// Generate cache events.\nfor (int i = 0; i < 20; i++)\n cache.put(i, Integer.toString(i));\n", + "language": "java", + "name": "remote listen" + }, + { + "code": "Ignite ignite = Ignition.ignite();\n \n// Get an instance of named cache.\nfinal IgniteCache<Integer, String> cache = ignite.jcache(\"cacheName\");\n \n// Sample remote filter which only accepts events for keys\n// that are greater than or equal to 10.\nIgnitePredicate<CacheEvent> rmtLsnr = new IgnitePredicate<CacheEvent>() {\n @Override public boolean apply(CacheEvent evt) {\n System.out.println(\"Cache event: \" + evt);\n \n int key = evt.key();\n \n return key >= 10;\n }\n};\n \n// Subscribe to specified cache events occuring on \n// all nodes that have the specified cache running.\nignite.events(ignite.cluster().forCacheNodes(\"cacheName\")).remoteListen(null, rmtLsnr, EVT_CACHE_OBJECT_PUT, \t\t \t\t EVT_CACHE_OBJECT_READ, EVT_CACHE_OBJECT_REMOVED);\n \n// Generate cache events.\nfo r (int i = 0; i < 20; i++)\n cache.put(i, Integer.toString(i));", + "language": "java", + "name": "java7 listen" + } + ] +} +[/block] +In the above example `EVT_CACHE_OBJECT_PUT`,`EVT_CACHE_OBJECT_READ`, and `EVT_CACHE_OBJECT_REMOVED` are pre-defined event type constants defined in `EventType` interface. +[block:callout] +{ + "type": "info", + "body": "`EventType` interface defines various event type constants that can be used with listen methods. Refer to [javadoc](https://ignite.incubator.apache.org/releases/1.0.0/javadoc/) for complete list of these event types." +} +[/block] + +[block:callout] +{ + "type": "warning", + "body": "Event types passed in as parameter in `localListen(...)` and `remoteListen(...)` methods must also be configured in `IgniteConfiguration`. See [configuration](#configuration) example below." +} +[/block] + +[block:api-header] +{ + "type": "basic", + "title": "Query for Events" +} +[/block] +All events generated in the system are kept locally on the local node. `IgniteEvents` API provides methods to query for these events. +##Local Events +`localQuery(...)` method queries for events on the local node using the passed in predicate filter. If all predicates are satisfied, a collection of events happening on the local node is returned. +##Remote Events +`remoteQuery(...)` method asynchronously queries for events on remote nodes in this projection using the passed in predicate filter. This operation is distributed and hence can fail on communication layer and generally can take much longer than local event notifications. Note that this method will not block and will return immediately with future. + +[block:api-header] +{ + "type": "basic", + "title": "Configuration" +} +[/block] +To get notified of any tasks or cache events occurring within the cluster, `includeEventTypes` property of `IgniteConfiguration` must be enabled. +[block:code] +{ + "codes": [ + { + "code": "<bean class=\"org.apache.ignite.configuration.IgniteConfiguration\">\n \t\t... \n <!-- Enable cache events. -->\n <property name=\"includeEventTypes\">\n <util:constant static-field=\"org.apache.ignite.events.EventType.EVTS_CACHE\"/>\n </property>\n \t...\n</bean>", + "language": "xml" + }, + { + "code": "IgniteConfiguration cfg = new IgniteConfiguration();\n\n// Enable cache events.\ncfg.setIncludeEventTypes(EVTS_CACHE);\n\n// Start Ignite node.\nIgnition.start(cfg);", + "language": "java" + } + ] +} +[/block] +By default, event notifications are turned off for performance reasons. +[block:callout] +{ + "type": "success", + "body": "Since thousands of events per second are generated, it creates an additional load on the system. This can lead to significant performance degradation. Therefore, it is highly recommended to enable only those events that your application logic requires." +} +[/block] \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/af603c00/docs/wiki/distributed-file-system/igfs.md ---------------------------------------------------------------------- diff --git a/docs/wiki/distributed-file-system/igfs.md b/docs/wiki/distributed-file-system/igfs.md new file mode 100755 index 0000000..23768d7 --- /dev/null +++ b/docs/wiki/distributed-file-system/igfs.md @@ -0,0 +1 @@ +We are currently adding documentation for the Ignite File System. In the mean time you can refer to the [javadoc](https://ignite.incubator.apache.org/releases/1.0.0/javadoc/org/apache/ignite/IgniteFs.html). \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/af603c00/docs/wiki/distributed-messaging/messaging.md ---------------------------------------------------------------------- diff --git a/docs/wiki/distributed-messaging/messaging.md b/docs/wiki/distributed-messaging/messaging.md new file mode 100755 index 0000000..9b16b2f --- /dev/null +++ b/docs/wiki/distributed-messaging/messaging.md @@ -0,0 +1,73 @@ +Ignite distributed messaging allows for topic based cluster-wide communication between all nodes. Messages with a specified message topic can be distributed to all or sub-group of nodes that have subscribed to that topic. + +Ignite messaging is based on publish-subscribe paradigm where publishers and subscribers are connected together by a common topic. When one of the nodes sends a message A for topic T, it is published on all nodes that have subscribed to T. +[block:callout] +{ + "type": "info", + "body": "Any new node joining the cluster automatically gets subscribed to all the topics that other nodes in the cluster (or [cluster group](/docs/cluster-groups)) are subscribed to." +} +[/block] +Distributed Messaging functionality in Ignite is provided via `IgniteMessaging` interface. You can get an instance of `IgniteMessaging`, like so: +[block:code] +{ + "codes": [ + { + "code": "Ignite ignite = Ignition.ignite();\n\n// Messaging instance over this cluster.\nIgniteMessaging msg = ignite.message();\n\n// Messaging instance over given cluster group (in this case, remote nodes).\nIgniteMessaging rmtMsg = ignite.message(ignite.cluster().forRemotes());", + "language": "java" + } + ] +} +[/block] + +[block:api-header] +{ + "type": "basic", + "title": "Publish Messages" +} +[/block] +Send methods help sending/publishing messages with a specified message topic to all nodes. Messages can be sent in *ordered* or *unordered* manner. +##Ordered Messages +`sendOrdered(...)` method can be used if you want to receive messages in the order they were sent. A timeout parameter is passed to specify how long a message will stay in the queue to wait for messages that are supposed to be sent before this message. If the timeout expires, then all the messages that have not yet arrived for a given topic on that node will be ignored. +##Unordered Messages +`send(...)` methods do not guarantee message ordering. This means that, when you sequentially send message A and message B, you are not guaranteed that the target node first receives A and then B. +[block:api-header] +{ + "type": "basic", + "title": "Subscribe for Messages" +} +[/block] +Listen methods help to listen/subscribe for messages. When these methods are called, a listener with specified message topic is registered on all (or sub-group of ) nodes to listen for new messages. With listen methods, a predicate is passed that returns a boolean value which tells the listener to continue or stop listening for new messages. +##Local Listen +`localListen(...)` method registers a message listener with specified topic only on the local node and listens for messages from any node in *this* cluster group. +##Remote Listen +`remoteListen(...)` method registers message listeners with specified topic on all nodes in *this* cluster group and listens for messages from any node in *this* cluster group . + + +[block:api-header] +{ + "type": "basic", + "title": "Example" +} +[/block] +Following example shows message exchange between remote nodes. +[block:code] +{ + "codes": [ + { + "code": "Ignite ignite = Ignition.ignite();\n \nIgniteMessaging rmtMsg = ignite.message(ignite.cluster().forRemotes());\n \n// Add listener for unordered messages on all remote nodes.\nrmtMsg.remoteListen(\"MyOrderedTopic\", (nodeId, msg) -> {\n System.out.println(\"Received ordered message [msg=\" + msg + \", from=\" + nodeId + ']');\n \n return true; // Return true to continue listening.\n});\n \n// Send ordered messages to remote nodes.\nfor (int i = 0; i < 10; i++)\n rmtMsg.sendOrdered(\"MyOrderedTopic\", Integer.toString(i));", + "language": "java", + "name": "Ordered Messaging" + }, + { + "code": " Ignite ignite = Ignition.ignite();\n \nIgniteMessaging rmtMsg = ignite.message(ignite.cluster().forRemotes());\n \n// Add listener for unordered messages on all remote nodes.\nrmtMsg.remoteListen(\"MyUnOrderedTopic\", (nodeId, msg) -> {\n System.out.println(\"Received unordered message [msg=\" + msg + \", from=\" + nodeId + ']');\n \n return true; // Return true to continue listening.\n});\n \n// Send unordered messages to remote nodes.\nfor (int i = 0; i < 10; i++)\n rmtMsg.send(\"MyUnOrderedTopic\", Integer.toString(i));", + "language": "java", + "name": "Unordered Messaging" + }, + { + "code": "Ignite ignite = Ignition.ignite();\n\n// Get cluster group of remote nodes.\nClusterGroup rmtPrj = ignite.cluster().forRemotes();\n\n// Get messaging instance over remote nodes.\nIgniteMessaging msg = ignite.message(rmtPrj);\n\n// Add message listener for specified topic on all remote nodes.\nmsg.remoteListen(\"myOrderedTopic\", new IgniteBiPredicate<UUID, String>() {\n @Override public boolean apply(UUID nodeId, String msg) {\n System.out.println(\"Received ordered message [msg=\" + msg + \", from=\" + nodeId + ']');\n\n return true; // Return true to continue listening.\n }\n});\n\n// Send ordered messages to all remote nodes.\nfor (int i = 0; i < 10; i++)\n msg.sendOrdered(\"myOrderedTopic\", Integer.toString(i), 0);", + "language": "java", + "name": "java7 ordered" + } + ] +} +[/block] \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/af603c00/docs/wiki/http/configuration.md ---------------------------------------------------------------------- diff --git a/docs/wiki/http/configuration.md b/docs/wiki/http/configuration.md new file mode 100755 index 0000000..e23366b --- /dev/null +++ b/docs/wiki/http/configuration.md @@ -0,0 +1,58 @@ +[block:api-header] +{ + "type": "basic", + "title": "General Configuration" +} +[/block] + +[block:parameters] +{ + "data": { + "h-0": "Parameter name", + "h-3": "Default value", + "h-2": "Optional", + "h-1": "Description", + "0-0": "**setRestSecretKey(String)**", + "0-1": "Defines secret key used for client authentication. When provided, client request must contain HTTP header **X-Signature** with Base64 encoded SHA1 hash of the string \"[1];[2]\", where [1] is timestamp in milliseconds and [2] is the secret key.", + "0-3": "**null**", + "0-2": "Yes", + "1-0": "**setRestPortRange(int)**", + "1-1": "Port range for Jetty server. In case port provided in Jetty configuration or **IGNITE_JETTY_PORT** system property is already in use, Ignite will iteratively increment port by 1 and try binding once again until provided port range is exceeded.", + "1-3": "**100**", + "1-2": "Yes", + "3-0": "**setRestEnabled(Boolean)**", + "3-1": "Whether REST client is enabled or not.", + "3-3": "**true**", + "3-2": "Yes", + "4-0": "**setRestAccessibleFolders(String...)**", + "4-1": "Array of folders that are accessible for log reading commands. When remote client requests a log file, file path is checked against this list. If requested file is not located in any sub-folder of these folders, request is not processed. By default array consists of a single **IGNITE_HOME** folder. If **IGNITE_HOME** could not be detected and property is not specified, no restrictions applied.", + "4-2": "Yes", + "4-3": "**IGNITE_HOME**", + "2-0": "**setRestJettyPath(String)**", + "2-1": "Path to Jetty configuration file. Should be either absolute or relative to **IGNITE_HOME**. If not provided then GridGain will start Jetty server with simple HTTP connector. This connector will use **IGNITE_JETTY_HOST** and **IGNITE_JETTY_PORT** system properties as host and port respectively. In case **IGNITE_JETTY_HOST** is not provided, localhost will be used as default. In case **IGNITE_JETTY_PORT** is not provided, port 8080 will be used as default.", + "2-3": "**null**", + "2-2": "Yes" + }, + "cols": 4, + "rows": 5 +} +[/block] + +[block:api-header] +{ + "type": "basic", + "title": "Sample Jetty XML configuration" +} +[/block] + +[block:code] +{ + "codes": [ + { + "code": "<?xml version=\"1.0\"?>\n<!DOCTYPE Configure PUBLIC \"-//Jetty//Configure//EN\" \"http://www.eclipse.org/jetty/configure.dtd\">\n<Configure id=\"Server\" class=\"org.eclipse.jetty.server.Server\">\n <Arg name=\"threadPool\">\n <!-- Default queued blocking thread pool -->\n <New class=\"org.eclipse.jetty.util.thread.QueuedThreadPool\">\n <Set name=\"minThreads\">20</Set>\n <Set name=\"maxThreads\">200</Set>\n </New>\n </Arg>\n <New id=\"httpCfg\" class=\"org.eclipse.jetty.server.HttpConfiguration\">\n <Set name=\"secureScheme\">https</Set>\n <Set name=\"securePort\">8443</Set>\n <Set name=\"sendServerVersion\">true</Set>\n <Set name=\"sendDateHeader\">true</Set>\n </New>\n <Call name=\"addConnector\">\n <Arg>\n <New class=\"org.eclipse.jetty.server.ServerConnector\">\n <Arg name=\"server\"><Ref refid=\"Server\"/></Arg>\n <Arg name=\"fact ories\">\n <Array type=\"org.eclipse.jetty.server.ConnectionFactory\">\n <Item>\n <New class=\"org.eclipse.jetty.server.HttpConnectionFactory\">\n <Ref refid=\"httpCfg\"/>\n </New>\n </Item>\n </Array>\n </Arg>\n <Set name=\"host\">\n <SystemProperty name=\"IGNITE_JETTY_HOST\" default=\"localhost\"/>\n \t</Set>\n <Set name=\"port\">\n <SystemProperty name=\"IGNITE_JETTY_PORT\" default=\"8080\"/>\n \t</Set>\n <Set name=\"idleTimeout\">30000</Set>\n <Set name=\"reuseAddress\">true</Set>\n </New>\n </Arg>\n </Call>\n <Set name=\"handler\">\n <New id=\"Handlers\" class=\"org.eclipse.jetty.server.handler.HandlerCollection\">\n <Set name=\"handlers\ ">\n <Array type=\"org.eclipse.jetty.server.Handler\">\n <Item>\n <New id=\"Contexts\" class=\"org.eclipse.jetty.server.handler.ContextHandlerCollection\"/>\n </Item>\n </Array>\n </Set>\n </New>\n </Set>\n <Set name=\"stopAtShutdown\">false</Set>\n</Configure>", + "language": "xml", + "name": "" + } + ] +} +[/block] \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/af603c00/docs/wiki/http/rest-api.md ---------------------------------------------------------------------- diff --git a/docs/wiki/http/rest-api.md b/docs/wiki/http/rest-api.md new file mode 100755 index 0000000..5a728cd --- /dev/null +++ b/docs/wiki/http/rest-api.md @@ -0,0 +1,1646 @@ +Ignite provides HTTP REST client that gives you the ability to communicate with the grid over HTTP and HTTPS protocols using REST approach. REST APIs can be used to perform various operations like read/write from/to cache, execute tasks, get cache and node metrics and more. + +* [Returned value](#returned-value) +* [Log](#log) +* [Version](#version) +* [Decrement](#decrement) +* [Increment](#increment) +* [Cache metrics](#cache-metrics) +* [Compare-And-Swap](#compare-and-swap) +* [Prepend](#prepend) +* [Append](#append) +* [Replace](#replace) +* [Remove all](#remove-all) +* [Remove](#remove) +* [Add](#add) +* [Put all](#put-all) +* [Put](#put) +* [Get all](#get-all) +* [Get](#get) +* [Node](#node) +* [Topology](#topology) +* [Execute](#execute) +* [Result](#result) + +[block:api-header] +{ + "type": "basic", + "title": "Returned value" +} +[/block] +HTTP REST request returns JSON object which has similar structure for each command. This object has the following structure: +[block:parameters] +{ + "data": { + "h-0": "name", + "h-1": "type", + "h-2": "description", + "h-3": "example", + "0-0": "affinityNodeId", + "0-1": "string", + "0-2": "Affinity node ID.", + "0-3": "2bd7b049-3fa0-4c44-9a6d-b5c7a597ce37", + "1-0": "error", + "1-1": "string", + "1-2": "The field contains description of error if server could not handle the request", + "1-3": "specifically for each command", + "2-0": "response", + "2-1": "jsonObject", + "2-2": "The field contains result of command.", + "2-3": "specifically for each command", + "3-0": "successStatus", + "3-1": "integer", + "3-2": "Exit status code. It might have the following values:\n * success = 0\n * failed = 1 \n * authorization failed = 2\n * security check failed = 3", + "3-3": "0" + }, + "cols": 4, + "rows": 4 +} +[/block] + +[block:api-header] +{ + "type": "basic", + "title": "Log" +} +[/block] +**Log** command shows server logs. +[block:code] +{ + "codes": [ + { + "code": "http://host:port/ignite?cmd=log&from=10&to=100&path=/var/log/ignite.log", + "language": "curl" + } + ] +} +[/block] +##Request Parameters +[block:parameters] +{ + "data": { + "h-0": "name", + "h-1": "type", + "h-2": "optional", + "h-3": "decription", + "h-4": "example", + "0-0": "cmd", + "0-3": "Should be **log** lowercase.", + "0-4": "", + "0-1": "string", + "0-2": "No", + "1-0": "from", + "1-1": "integer", + "1-2": "Yes", + "1-3": "Number of line to start from. Parameter is mandatory if **to** is passed.", + "1-4": "0", + "2-0": "path", + "2-1": "string", + "2-2": "Yes", + "2-3": "The path to log file. If not provided, will be used the following value **work/log/ignite.log**", + "2-4": "log/cache_server.log", + "3-0": "to", + "3-1": "integer", + "3-2": "Yes", + "3-3": "Number to line to finish on. Parameter is mandatory if **from** is passed.", + "3-4": "1000" + }, + "cols": 5, + "rows": 4 +} +[/block] +##Response example: +[block:code] +{ + "codes": [ + { + "code": "{\n \"error\": \"\",\n \"response\": [\"[14:01:56,626][INFO ][test-runner][GridDiscoveryManager] Topology snapshot [ver=1, nodes=1, CPUs=8, heap=1.8GB]\"],\n \"successStatus\": 0\n}", + "language": "json" + } + ] +} +[/block] + +[block:parameters] +{ + "data": { + "h-0": "name", + "h-1": "type", + "h-2": "description", + "h-3": "example", + "0-0": "response", + "0-3": "[\"[14:01:56,626][INFO ][test-runner][GridDiscoveryManager] Topology snapshot [ver=1, nodes=1, CPUs=8, heap=1.8GB]\"]", + "0-1": "string", + "0-2": "logs" + }, + "cols": 4, + "rows": 1 +} +[/block] + +[block:api-header] +{ + "type": "basic", + "title": "Version" +} +[/block] +**Version** command shows current Ignite version. +[block:code] +{ + "codes": [ + { + "code": "http://host:port/ignite?cmd=version", + "language": "curl" + } + ] +} +[/block] +##Request Parameters +[block:parameters] +{ + "data": { + "h-0": "name", + "h-1": "type", + "h-2": "optional", + "h-3": "description", + "h-4": "example", + "0-0": "cmd", + "0-4": "", + "0-1": "string", + "0-3": "Should be **version** lowercase." + }, + "cols": 5, + "rows": 1 +} +[/block] +##Response example +[block:code] +{ + "codes": [ + { + "code": "{\n \"error\": \"\",\n \"response\": \"1.0.0\",\n \"successStatus\": 0\n}", + "language": "json" + } + ] +} +[/block] + +[block:parameters] +{ + "data": { + "h-0": "name", + "h-1": "type", + "h-2": "description", + "h-3": "example", + "0-0": "response", + "0-3": "1.0.0", + "0-1": "string", + "0-2": "Ignite version" + }, + "cols": 4, + "rows": 1 +} +[/block] + +[block:api-header] +{ + "type": "basic", + "title": "Decrement" +} +[/block] +**Decrement** command subtracts and gets current value of given atomic long. +[block:code] +{ + "codes": [ + { + "code": "http://host:port/ignite?cmd=decr&cacheName=partionedCache&key=decrKey&init=15&delta=10", + "language": "curl" + } + ] +} +[/block] +##Request parameters +[block:parameters] +{ + "data": { + "h-0": "name", + "h-1": "type", + "h-2": "optional", + "h-3": "decription", + "h-4": "example", + "0-0": "cmd", + "0-4": "", + "0-1": "string", + "0-3": "Should be **decr** lowercase.", + "1-0": "cacheName", + "1-1": "string", + "1-2": "Yes", + "1-3": "Cache name. If not provided, default cache will be used.", + "1-4": "partionedCache", + "2-0": "key", + "2-1": "string", + "2-3": "The name of atomic long.", + "2-4": "counter", + "3-0": "init", + "3-1": "long", + "3-2": "Yes", + "3-3": "Initial value.", + "3-4": "15", + "4-4": "42", + "4-3": "Number to be subtracted.", + "4-0": "delta", + "4-1": "long" + }, + "cols": 5, + "rows": 5 +} +[/block] +##Response example +[block:code] +{ + "codes": [ + { + "code": "{\n \"affinityNodeId\": \"e05839d5-6648-43e7-a23b-78d7db9390d5\",\n \"error\": \"\",\n \"response\": -42,\n \"successStatus\": 0\n}", + "language": "json" + } + ] +} +[/block] + +[block:parameters] +{ + "data": { + "h-0": "name", + "h-1": "type", + "h-2": "description", + "h-3": "example", + "0-0": "response", + "0-1": "long", + "0-2": "Value after operation.", + "0-3": "-42" + }, + "cols": 4, + "rows": 1 +} +[/block] + +[block:api-header] +{ + "type": "basic", + "title": "Increment" +} +[/block] +**Increment** command adds and gets current value of given atomic long. +[block:code] +{ + "codes": [ + { + "code": "http://host:port/ignite?cmd=incr&cacheName=partionedCache&key=decrKey&init=15&delta=10", + "language": "curl" + } + ] +} +[/block] +##Request parameters +[block:parameters] +{ + "data": { + "h-0": "name", + "h-1": "type", + "h-2": "optional", + "h-3": "decription", + "h-4": "example", + "0-0": "cmd", + "0-4": "", + "0-1": "string", + "0-3": "Should be ** incr** lowercase.", + "1-0": "cacheName", + "1-1": "string", + "1-2": "Yes", + "1-3": "Cache name. If not provided, default cache will be used.", + "1-4": "partionedCache", + "2-0": "key", + "2-1": "string", + "2-3": "The name of atomic long.", + "2-4": "counter", + "3-0": "init", + "3-1": "long", + "3-2": "Yes", + "3-3": "Initial value.", + "3-4": "15", + "4-4": "42", + "4-3": "Number to be added.", + "4-0": "delta", + "4-1": "long" + }, + "cols": 5, + "rows": 5 +} +[/block] +##Response example +[block:code] +{ + "codes": [ + { + "code": "{\n \"affinityNodeId\": \"e05839d5-6648-43e7-a23b-78d7db9390d5\",\n \"error\": \"\",\n \"response\": 42,\n \"successStatus\": 0\n}", + "language": "json" + } + ] +} +[/block] + +[block:parameters] +{ + "data": { + "h-0": "name", + "h-1": "type", + "h-2": "description", + "h-3": "example", + "0-0": "response", + "0-1": "long", + "0-2": "Value after operation.", + "0-3": "42" + }, + "cols": 4, + "rows": 1 +} +[/block] + +[block:api-header] +{ + "type": "basic", + "title": "Cache metrics" +} +[/block] +**Cache metrics** command shows metrics for Ignite cache. +[block:code] +{ + "codes": [ + { + "code": "http://host:port/ignite?cmd=cache&cacheName=partionedCache&destId=8daab5ea-af83-4d91-99b6-77ed2ca06647", + "language": "curl" + } + ] +} +[/block] +##Request parameters +[block:parameters] +{ + "data": { + "h-0": "name", + "h-1": "type", + "h-2": "optional", + "h-3": "decription", + "h-4": "example", + "0-0": "cmd", + "0-4": "", + "0-1": "string", + "0-3": "Should be **cache** lowercase.", + "1-0": "cacheName", + "1-1": "string", + "1-2": "Yes", + "1-3": "Cache name. If not provided, default cache will be used.", + "1-4": "partionedCache", + "2-0": "destId", + "2-1": "string", + "2-3": "Node ID for which the metrics are to be returned.", + "2-4": "8daab5ea-af83-4d91-99b6-77ed2ca06647", + "2-2": "Yes" + }, + "cols": 5, + "rows": 3 +} +[/block] +##Response example +[block:code] +{ + "codes": [ + { + "code": "{\n \"affinityNodeId\": \"\",\n \"error\": \"\",\n \"response\": {\n \"createTime\": 1415179251551,\n \"hits\": 0,\n \"misses\": 0,\n \"readTime\": 1415179251551,\n \"reads\": 0,\n \"writeTime\": 1415179252198,\n \"writes\": 2\n },\n \"successStatus\": 0\n}", + "language": "json" + } + ] +} +[/block] + +[block:parameters] +{ + "data": { + "h-0": "name", + "h-1": "type", + "h-2": "description", + "h-3": "example", + "0-0": "response", + "0-1": "jsonObject", + "0-2": "The JSON object contains cache metrics such as create time, count reads and etc.", + "0-3": "{\n\"createTime\": 1415179251551, \"hits\": 0, \"misses\": 0, \"readTime\":1415179251551, \"reads\": 0,\"writeTime\": 1415179252198, \"writes\": 2\n}" + }, + "cols": 4, + "rows": 1 +} +[/block] + +[block:api-header] +{ + "type": "basic", + "title": "Compare-And-Swap" +} +[/block] +**CAS** command stores given key-value pair in cache only if the previous value is equal to the expected value passed in. +[block:code] +{ + "codes": [ + { + "code": "http://host:port/ignite?cmd=cas&key=casKey&val2=casOldVal&val1=casNewVal&cacheName=partionedCache&destId=8daab5ea-af83-4d91-99b6-77ed2ca06647", + "language": "curl" + } + ] +} +[/block] +##Request parameters +[block:parameters] +{ + "data": { + "h-0": "name", + "h-1": "type", + "h-2": "optional", + "h-3": "decription", + "h-4": "example", + "0-0": "cmd", + "0-4": "", + "0-1": "string", + "0-3": "Should be **cas** lowercase.", + "1-0": "cacheName", + "1-1": "string", + "1-2": "Yes", + "1-3": "Cache name. If not provided, default cache will be used.", + "1-4": "partionedCache", + "5-0": "destId", + "5-1": "string", + "5-3": "Node ID for which the metrics are to be returned.", + "5-4": "8daab5ea-af83-4d91-99b6-77ed2ca06647", + "5-2": "Yes", + "2-0": "key", + "3-0": "val", + "4-0": "val2", + "2-1": "string", + "3-1": "string", + "4-1": "string", + "2-2": "Key to store in cache.", + "3-2": "Value associated with the given key.", + "4-2": "Expected value.", + "2-3": "name", + "3-3": "Jack", + "4-3": "Bob" + }, + "cols": 5, + "rows": 6 +} +[/block] +##Response example +[block:code] +{ + "codes": [ + { + "code": "{\n \"affinityNodeId\": \"1bcbac4b-3517-43ee-98d0-874b103ecf30\",\n \"error\": \"\",\n \"response\": true,\n \"successStatus\": 0\n}", + "language": "json" + } + ] +} +[/block] + +[block:parameters] +{ + "data": { + "h-0": "name", + "h-1": "type", + "h-2": "description", + "h-3": "example", + "0-0": "response", + "0-1": "boolean", + "0-2": "True if replace happened, false otherwise.", + "0-3": "true" + }, + "cols": 4, + "rows": 1 +} +[/block] + +[block:api-header] +{ + "type": "basic", + "title": "Prepend" +} +[/block] +**Prepend** command prepends a line for value which is associated with key. +[block:code] +{ + "codes": [ + { + "code": "http://host:port/ignite?cmd=prepend&key=prependKey&val=prefix_&cacheName=partionedCache&destId=8daab5ea-af83-4d91-99b6-77ed2ca06647", + "language": "curl" + } + ] +} +[/block] +##Request parameters +[block:parameters] +{ + "data": { + "h-0": "name", + "h-1": "type", + "h-2": "optional", + "h-3": "decription", + "h-4": "example", + "0-0": "cmd", + "0-4": "", + "0-1": "string", + "0-3": "Should be **prepend** lowercase.", + "1-0": "cacheName", + "1-1": "string", + "1-2": "Yes", + "1-3": "Cache name. If not provided, default cache will be used.", + "1-4": "partionedCache", + "4-0": "destId", + "4-1": "string", + "4-3": "Node ID for which the metrics are to be returned.", + "4-4": "8daab5ea-af83-4d91-99b6-77ed2ca06647", + "4-2": "Yes", + "2-0": "key", + "3-0": "val", + "2-1": "string", + "3-1": "string", + "2-2": "Key to store in cache.", + "3-2": "Value to be prepended to the current value.", + "2-3": "name", + "3-3": "Name_" + }, + "cols": 5, + "rows": 5 +} +[/block] +##Response example +[block:code] +{ + "codes": [ + { + "code": "{\n \"affinityNodeId\": \"1bcbac4b-3517-43ee-98d0-874b103ecf30\",\n \"error\": \"\",\n \"response\": true,\n \"successStatus\": 0\n}", + "language": "json" + } + ] +} +[/block] + +[block:parameters] +{ + "data": { + "h-0": "name", + "h-1": "type", + "h-2": "description", + "h-3": "example", + "0-0": "response", + "0-1": "boolean", + "0-2": "True if replace happened, false otherwise.", + "0-3": "true" + }, + "cols": 4, + "rows": 1 +} +[/block] + +[block:api-header] +{ + "type": "basic", + "title": "Append" +} +[/block] +**Append** command appends a line for value which is associated with key. +[block:code] +{ + "codes": [ + { + "code": "http://host:port/ignite?cmd=append&key=appendKey&val=_suffix&cacheName=partionedCache&destId=8daab5ea-af83-4d91-99b6-77ed2ca06647", + "language": "curl" + } + ] +} +[/block] +##Request parameters +[block:parameters] +{ + "data": { + "h-0": "name", + "h-1": "type", + "h-2": "optional", + "h-3": "decription", + "h-4": "example", + "0-0": "cmd", + "0-4": "", + "0-1": "string", + "0-3": "Should be **append** lowercase.", + "1-0": "cacheName", + "1-1": "string", + "1-2": "Yes", + "1-3": "Cache name. If not provided, default cache will be used.", + "1-4": "partionedCache", + "4-0": "destId", + "4-1": "string", + "4-3": "Node ID for which the metrics are to be returned.", + "4-4": "8daab5ea-af83-4d91-99b6-77ed2ca06647", + "4-2": "Yes", + "2-0": "key", + "3-0": "val", + "2-1": "string", + "3-1": "string", + "2-2": "Key to store in cache.", + "3-2": "Value to be appended to the current value.", + "2-3": "name", + "3-3": "Jack" + }, + "cols": 5, + "rows": 5 +} +[/block] +##Response example +[block:code] +{ + "codes": [ + { + "code": "{\n \"affinityNodeId\": \"1bcbac4b-3517-43ee-98d0-874b103ecf30\",\n \"error\": \"\",\n \"response\": true,\n \"successStatus\": 0\n}", + "language": "json" + } + ] +} +[/block] + +[block:parameters] +{ + "data": { + "h-0": "name", + "h-1": "type", + "h-2": "description", + "h-3": "example", + "0-0": "response", + "0-1": "boolean", + "0-2": "True if replace happened, false otherwise.", + "0-3": "true" + }, + "cols": 4, + "rows": 1 +} +[/block] + +[block:api-header] +{ + "type": "basic", + "title": "Replace" +} +[/block] +**Replace** command stores a given key-value pair in cache only if there is a previous mapping for it. +[block:code] +{ + "codes": [ + { + "code": "http://host:port/ignite?cmd=rep&key=repKey&val=newValue&cacheName=partionedCache&destId=8daab5ea-af83-4d91-99b6-77ed2ca06647", + "language": "curl" + } + ] +} +[/block] +##Request parameters +[block:parameters] +{ + "data": { + "h-0": "name", + "h-1": "type", + "h-2": "optional", + "h-3": "decription", + "h-4": "example", + "0-0": "cmd", + "0-4": "", + "0-1": "string", + "0-3": "Should be **rmvall** lowercase.", + "1-0": "cacheName", + "1-1": "string", + "1-2": "Yes", + "1-3": "Cache name. If not provided, default cache will be used.", + "1-4": "partionedCache", + "4-0": "destId", + "4-1": "string", + "4-3": "Node ID for which the metrics are to be returned.", + "4-4": "8daab5ea-af83-4d91-99b6-77ed2ca06647", + "4-2": "Yes", + "2-0": "key", + "3-0": "val", + "2-1": "string", + "3-1": "string", + "2-2": "Key to store in cache.", + "3-2": "Value associated with the given key.", + "2-3": "name", + "3-3": "Jack" + }, + "cols": 5, + "rows": 5 +} +[/block] +##Response example +[block:code] +{ + "codes": [ + { + "code": "{\n \"affinityNodeId\": \"1bcbac4b-3517-43ee-98d0-874b103ecf30\",\n \"error\": \"\",\n \"response\": true,\n \"successStatus\": 0\n}", + "language": "json" + } + ] +} +[/block] + +[block:parameters] +{ + "data": { + "h-0": "name", + "h-1": "type", + "h-2": "description", + "h-3": "example", + "0-0": "response", + "0-1": "boolean", + "0-2": "True if replace happened, false otherwise.", + "0-3": "true" + }, + "cols": 4, + "rows": 1 +} +[/block] + +[block:api-header] +{ + "type": "basic", + "title": "Remove all" +} +[/block] +**Remove all** command removes given key mappings from cache. +[block:code] +{ + "codes": [ + { + "code": "http://host:port/ignite?cmd=rmvall&k1=rmKey1&k2=rmKey2&k3=rmKey3&cacheName=partionedCache&destId=8daab5ea-af83-4d91-99b6-77ed2ca06647", + "language": "curl" + } + ] +} +[/block] +##Request parameters +[block:parameters] +{ + "data": { + "h-0": "name", + "h-1": "type", + "h-2": "optional", + "h-3": "decription", + "h-4": "example", + "0-0": "cmd", + "0-4": "", + "0-1": "string", + "0-3": "Should be **rmvall** lowercase.", + "1-0": "cacheName", + "1-1": "string", + "1-2": "Yes", + "1-3": "Cache name. If not provided, default cache will be used.", + "1-4": "partionedCache", + "3-0": "destId", + "3-1": "string", + "3-3": "Node ID for which the metrics are to be returned.", + "3-4": "8daab5ea-af83-4d91-99b6-77ed2ca06647", + "3-2": "Yes", + "2-0": "k1...kN", + "2-1": "string", + "2-2": "Keys whose mappings are to be removed from cache.", + "2-3": "name" + }, + "cols": 5, + "rows": 4 +} +[/block] +##Response example +[block:code] +{ + "codes": [ + { + "code": "{\n \"affinityNodeId\": \"1bcbac4b-3517-43ee-98d0-874b103ecf30\",\n \"error\": \"\",\n \"response\": true,\n \"successStatus\": 0\n}", + "language": "json" + } + ] +} +[/block] + +[block:parameters] +{ + "data": { + "h-0": "name", + "h-1": "type", + "h-2": "description", + "h-3": "example", + "0-0": "response", + "0-1": "boolean", + "0-2": "True if replace happened, false otherwise.", + "0-3": "true" + }, + "cols": 4, + "rows": 1 +} +[/block] + +[block:api-header] +{ + "type": "basic", + "title": "Remove" +} +[/block] +**Remove** command removes the given key mapping from cache. +[block:code] +{ + "codes": [ + { + "code": "http://host:port/ignite?cmd=rmv&key=rmvKey&cacheName=partionedCache&destId=8daab5ea-af83-4d91-99b6-77ed2ca06647", + "language": "curl" + } + ] +} +[/block] +##Request parameters +[block:parameters] +{ + "data": { + "h-0": "name", + "h-1": "type", + "h-2": "optional", + "h-3": "decription", + "h-4": "example", + "0-0": "cmd", + "0-4": "", + "0-1": "string", + "0-3": "Should be **rmv** lowercase.", + "1-0": "cacheName", + "1-1": "string", + "1-2": "Yes", + "1-3": "Cache name. If not provided, default cache will be used.", + "1-4": "partionedCache", + "3-0": "destId", + "3-1": "string", + "3-3": "Node ID for which the metrics are to be returned.", + "3-4": "8daab5ea-af83-4d91-99b6-77ed2ca06647", + "3-2": "Yes", + "2-0": "key", + "2-1": "string", + "2-2": "Key - for which the mapping is to be removed from cache.", + "2-3": "name" + }, + "cols": 5, + "rows": 4 +} +[/block] +##Response example +[block:code] +{ + "codes": [ + { + "code": "{\n \"affinityNodeId\": \"1bcbac4b-3517-43ee-98d0-874b103ecf30\",\n \"error\": \"\",\n \"response\": true,\n \"successStatus\": 0\n}", + "language": "json" + } + ] +} +[/block] + +[block:parameters] +{ + "data": { + "h-0": "name", + "h-1": "type", + "h-2": "description", + "h-3": "example", + "0-0": "response", + "0-1": "boolean", + "0-2": "True if replace happened, false otherwise.", + "0-3": "true" + }, + "cols": 4, + "rows": 1 +} +[/block] + +[block:api-header] +{ + "type": "basic", + "title": "Add" +} +[/block] +**Add** command stores a given key-value pair in cache only if there isn't a previous mapping for it. +[block:code] +{ + "codes": [ + { + "code": "http://host:port/ignite?cmd=add&key=newKey&val=newValue&cacheName=partionedCache&destId=8daab5ea-af83-4d91-99b6-77ed2ca06647", + "language": "curl" + } + ] +} +[/block] +##Request parameters +[block:parameters] +{ + "data": { + "h-0": "name", + "h-1": "type", + "h-2": "optional", + "h-3": "decription", + "h-4": "example", + "0-0": "cmd", + "0-4": "", + "0-1": "string", + "0-3": "Should be **add** lowercase.", + "1-0": "cacheName", + "1-1": "string", + "1-2": "Yes", + "1-3": "Cache name. If not provided, default cache will be used.", + "1-4": "partionedCache", + "4-0": "destId", + "4-1": "string", + "4-3": "Node ID for which the metrics are to be returned.", + "4-4": "8daab5ea-af83-4d91-99b6-77ed2ca06647", + "4-2": "Yes", + "2-0": "key", + "2-1": "string", + "2-3": "Key to be associated with the value.", + "2-4": "name", + "3-0": "val", + "3-1": "string", + "3-3": "Value to be associated with the key.", + "3-4": "Jack" + }, + "cols": 5, + "rows": 5 +} +[/block] +##Response example +[block:code] +{ + "codes": [ + { + "code": "{\n \"affinityNodeId\": \"1bcbac4b-3517-43ee-98d0-874b103ecf30\",\n \"error\": \"\",\n \"response\": true,\n \"successStatus\": 0\n}", + "language": "json" + } + ] +} +[/block] + +[block:parameters] +{ + "data": { + "h-0": "name", + "h-1": "type", + "h-2": "description", + "h-3": "example", + "0-0": "response", + "0-1": "boolean", + "0-2": "True if value was stored in cache, false otherwise.", + "0-3": "true" + }, + "cols": 4, + "rows": 1 +} +[/block] + +[block:api-header] +{ + "type": "basic", + "title": "Put all" +} +[/block] +**Put all** command stores the given key-value pairs in cache. +[block:code] +{ + "codes": [ + { + "code": "http://host:port/ignite?cmd=putall&k1=putKey1&k2=putKey2&k3=putKey3&v1=value1&v2=value2&v3=value3&cacheName=partionedCache&destId=8daab5ea-af83-4d91-99b6-77ed2ca06647", + "language": "curl" + } + ] +} +[/block] +##Request parameters +[block:parameters] +{ + "data": { + "h-0": "name", + "h-1": "type", + "h-2": "optional", + "h-3": "decription", + "h-4": "example", + "0-0": "cmd", + "0-4": "", + "0-1": "string", + "0-3": "Should be **putall** lowercase.", + "1-0": "cacheName", + "1-1": "string", + "1-2": "Yes", + "1-3": "Cache name. If not provided, default cache will be used.", + "1-4": "partionedCache", + "4-0": "destId", + "4-1": "string", + "4-3": "Node ID for which the metrics are to be returned.", + "4-4": "8daab5ea-af83-4d91-99b6-77ed2ca06647", + "4-2": "Yes", + "2-0": "k1...kN", + "2-1": "string", + "2-3": "Keys to be associated with values.", + "2-4": "name", + "3-0": "v1...vN", + "3-1": "string", + "3-3": "Values to be associated with keys.", + "3-4": "Jack" + }, + "cols": 5, + "rows": 5 +} +[/block] +##Response example +[block:code] +{ + "codes": [ + { + "code": "{\n \"affinityNodeId\": \"1bcbac4b-3517-43ee-98d0-874b103ecf30\",\n \"error\": \"\",\n \"response\": true,\n \"successStatus\": 0\n}", + "language": "json" + } + ] +} +[/block] + +[block:parameters] +{ + "data": { + "h-0": "name", + "h-1": "type", + "h-2": "description", + "h-3": "example", + "0-0": "response", + "0-1": "boolean", + "0-2": "True if values was stored in cache, false otherwise.", + "0-3": "true" + }, + "cols": 4, + "rows": 1 +} +[/block] + +[block:api-header] +{ + "type": "basic", + "title": "Put" +} +[/block] +**Put** command stores the given key-value pair in cache. +[block:code] +{ + "codes": [ + { + "code": "http://host:port/ignite?cmd=put&key=newKey&val=newValue&cacheName=partionedCache&destId=8daab5ea-af83-4d91-99b6-77ed2ca06647", + "language": "curl" + } + ] +} +[/block] +##Request parameters +[block:parameters] +{ + "data": { + "h-0": "name", + "h-1": "type", + "h-2": "optional", + "h-3": "decription", + "h-4": "example", + "0-0": "cmd", + "0-4": "", + "0-1": "string", + "0-3": "Should be **put** lowercase.", + "1-0": "cacheName", + "1-1": "string", + "1-2": "Yes", + "1-3": "Cache name. If not provided, default cache will be used.", + "1-4": "partionedCache", + "4-0": "destId", + "4-1": "string", + "4-3": "Node ID for which the metrics are to be returned.", + "4-4": "8daab5ea-af83-4d91-99b6-77ed2ca06647", + "4-2": "Yes", + "2-0": "key", + "2-1": "string", + "2-3": "Key to be associated with values.", + "2-4": "name", + "3-0": "val", + "3-1": "string", + "3-3": "Value to be associated with keys.", + "3-4": "Jack" + }, + "cols": 5, + "rows": 5 +} +[/block] +##Response example +[block:code] +{ + "codes": [ + { + "code": "{\n \"affinityNodeId\": \"1bcbac4b-3517-43ee-98d0-874b103ecf30\",\n \"error\": \"\",\n \"response\": true,\n \"successStatus\": 0\n}", + "language": "json" + } + ] +} +[/block] + +[block:parameters] +{ + "data": { + "h-0": "name", + "h-1": "type", + "h-2": "description", + "h-3": "example", + "0-0": "response", + "0-1": "boolean", + "0-2": "True if value was stored in cache, false otherwise.", + "0-3": "true" + }, + "cols": 4, + "rows": 1 +} +[/block] + +[block:api-header] +{ + "type": "basic", + "title": "Get all" +} +[/block] +**Get all** command retrieves values mapped to the specified keys from cache. +[block:code] +{ + "codes": [ + { + "code": "http://host:port/ignite?cmd=getall&k1=getKey1&k2=getKey2&k3=getKey3&cacheName=partionedCache&destId=8daab5ea-af83-4d91-99b6-77ed2ca06647", + "language": "curl" + } + ] +} +[/block] +##Request parameters +[block:parameters] +{ + "data": { + "h-0": "name", + "h-1": "type", + "h-2": "optional", + "h-3": "decription", + "h-4": "example", + "0-0": "cmd", + "0-4": "", + "0-1": "string", + "0-3": "Should be **getall** lowercase.", + "1-0": "cacheName", + "1-1": "string", + "1-2": "Yes", + "1-3": "Cache name. If not provided, default cache will be used.", + "1-4": "partionedCache", + "3-0": "destId", + "3-1": "string", + "3-3": "Node ID for which the metrics are to be returned.", + "3-4": "8daab5ea-af83-4d91-99b6-77ed2ca06647", + "3-2": "Yes", + "2-0": "k1...kN", + "2-1": "string", + "2-3": "Keys whose associated values are to be returned.", + "2-4": "key1, key2, ..., keyN" + }, + "cols": 5, + "rows": 4 +} +[/block] +##Response example +[block:code] +{ + "codes": [ + { + "code": "{\n \"affinityNodeId\": \"\",\n \"error\": \"\",\n \"response\": {\n \"key1\": \"value1\",\n \"key2\": \"value2\"\n },\n \"successStatus\": 0\n}", + "language": "json" + } + ] +} +[/block] + +[block:parameters] +{ + "data": { + "h-0": "name", + "h-1": "type", + "h-2": "description", + "h-3": "example", + "0-0": "response", + "0-1": "jsonObject", + "0-2": "The map of key-value pairs.", + "0-3": "{\"key1\": \"value1\",\"key2\": \"value2\"}" + }, + "cols": 4, + "rows": 1 +} +[/block] + +[block:api-header] +{ + "type": "basic", + "title": "Get" +} +[/block] +**Get** command retrieves value mapped to the specified key from cache. +[block:code] +{ + "codes": [ + { + "code": "http://host:port/ignite?cmd=get&key=getKey&cacheName=partionedCache&destId=8daab5ea-af83-4d91-99b6-77ed2ca06647", + "language": "curl" + } + ] +} +[/block] +##Request parameters +[block:parameters] +{ + "data": { + "h-0": "name", + "h-1": "type", + "h-2": "optional", + "h-3": "decription", + "h-4": "example", + "0-0": "cmd", + "0-4": "", + "0-1": "string", + "0-3": "Should be **get** lowercase.", + "1-0": "cacheName", + "1-1": "string", + "1-2": "Yes", + "1-3": "Cache name. If not provided, default cache will be used.", + "1-4": "partionedCache", + "3-0": "destId", + "3-1": "string", + "3-3": "Node ID for which the metrics are to be returned.", + "3-4": "8daab5ea-af83-4d91-99b6-77ed2ca06647", + "3-2": "Yes", + "2-0": "key", + "2-1": "string", + "2-3": "Key whose associated value is to be returned", + "2-4": "testKey" + }, + "cols": 5, + "rows": 4 +} +[/block] +##Response example +[block:code] +{ + "codes": [ + { + "code": "{\n \"affinityNodeId\": \"2bd7b049-3fa0-4c44-9a6d-b5c7a597ce37\",\n \"error\": \"\",\n \"response\": \"value\",\n \"successStatus\": 0\n}", + "language": "json" + } + ] +} +[/block] + +[block:parameters] +{ + "data": { + "h-0": "name", + "h-1": "type", + "h-2": "description", + "h-3": "example", + "0-0": "response", + "0-1": "jsonObject", + "0-2": "Value for the given key.", + "0-3": "{\"name\": \"bob\"}" + }, + "cols": 4, + "rows": 1 +} +[/block] + +[block:api-header] +{ + "type": "basic", + "title": "Node" +} +[/block] +**Node** command gets information about a node. +[block:code] +{ + "codes": [ + { + "code": "http://host:port/ignite?cmd=node&attr=true&mtr=true&id=c981d2a1-878b-4c67-96f6-70f93a4cd241", + "language": "curl" + } + ] +} +[/block] +##Request parameters +[block:parameters] +{ + "data": { + "h-0": "name", + "h-1": "type", + "h-2": "optional", + "h-3": "decription", + "h-4": "example", + "0-0": "cmd", + "0-4": "", + "0-1": "string", + "0-3": "Should be **node** lowercase.", + "1-0": "mtr", + "1-1": "boolean", + "1-2": "Yes", + "1-3": "Response will include metrics, if this parameter has value true.", + "1-4": "true", + "4-0": "id", + "4-1": "string", + "4-3": "This parameter is optional, if ip parameter is passed. Response will be returned for node which has the node ID.", + "4-4": "8daab5ea-af83-4d91-99b6-77ed2ca06647", + "4-2": "", + "2-0": "attr", + "2-1": "boolean", + "2-3": "Response will include attributes, if this parameter has value true.", + "2-4": "true", + "3-0": "ip", + "3-1": "string", + "3-3": "This parameter is optional, if id parameter is passed. Response will be returned for node which has the IP.", + "3-4": "192.168.0.1", + "2-2": "Yes" + }, + "cols": 5, + "rows": 5 +} +[/block] +##Response example +[block:code] +{ + "codes": [ + { + "code": "{\n \"error\": \"\",\n \"response\": {\n \"attributes\": null,\n \"caches\": {},\n \"consistentId\": \"127.0.0.1:47500\",\n \"defaultCacheMode\": \"REPLICATED\",\n \"metrics\": null,\n \"nodeId\": \"2d0d6510-6fed-4fa3-b813-20f83ac4a1a9\",\n \"replicaCount\": 128,\n \"tcpAddresses\": [\"127.0.0.1\"],\n \"tcpHostNames\": [\"\"],\n \"tcpPort\": 11211\n },\n \"successStatus\": 0\n}", + "language": "json" + } + ] +} +[/block] + +[block:parameters] +{ + "data": { + "h-0": "name", + "h-1": "type", + "h-2": "description", + "h-3": "example", + "0-0": "response", + "0-1": "jsonObject", + "0-2": "Information about only one node.", + "0-3": "{\n\"attributes\": null,\n\"caches\": {},\n\"consistentId\": \"127.0.0.1:47500\",\n\"defaultCacheMode\": \"REPLICATED\",\n\"metrics\": null,\n\"nodeId\": \"2d0d6510-6fed-4fa3-b813-20f83ac4a1a9\",\n\"replicaCount\": 128,\n\"tcpAddresses\": [\"127.0.0.1\"],\n\"tcpHostNames\": [\"\"],\n\"tcpPort\": 11211\n}" + }, + "cols": 4, + "rows": 1 +} +[/block] + +[block:api-header] +{ + "type": "basic", + "title": "Topology" +} +[/block] +**Topology** command gets information about grid topology. +[block:code] +{ + "codes": [ + { + "code": "http://host:port/ignite?cmd=top&attr=true&mtr=true&id=c981d2a1-878b-4c67-96f6-70f93a4cd241", + "language": "curl" + } + ] +} +[/block] +##Request parameters +[block:parameters] +{ + "data": { + "h-0": "name", + "h-1": "type", + "h-2": "optional", + "h-3": "decription", + "h-4": "example", + "0-0": "cmd", + "0-4": "", + "0-1": "string", + "0-3": "Should be **top** lowercase.", + "1-0": "mtr", + "1-1": "boolean", + "1-2": "Yes", + "1-3": "Response will include metrics, if this parameter has value true.", + "1-4": "true", + "4-0": "id", + "4-1": "string", + "4-3": "This parameter is optional, if ip parameter is passed. Response will be returned for node which has the node ID.", + "4-4": "8daab5ea-af83-4d91-99b6-77ed2ca06647", + "4-2": "Yes", + "2-0": "attr", + "2-1": "boolean", + "2-3": "Response will include attributes, if this parameter has value true.", + "2-4": "true", + "3-0": "ip", + "3-1": "string", + "3-3": "This parameter is optional, if id parameter is passed. Response will be returned for node which has the IP.", + "3-4": "192.168.0.1", + "2-2": "Yes", + "3-2": "Yes" + }, + "cols": 5, + "rows": 5 +} +[/block] +##Response example +[block:code] +{ + "codes": [ + { + "code": "{\n \"error\": \"\",\n \"response\": [\n {\n \"attributes\": {\n ...\n },\n \"caches\": {},\n \"consistentId\": \"127.0.0.1:47500\",\n \"defaultCacheMode\": \"REPLICATED\",\n \"metrics\": {\n ...\n },\n \"nodeId\": \"96baebd6-dedc-4a68-84fd-f804ee1ed995\",\n \"replicaCount\": 128,\n \"tcpAddresses\": [\"127.0.0.1\"],\n \"tcpHostNames\": [\"\"],\n \"tcpPort\": 11211\n },\n {\n \"attributes\": {\n ...\n },\n \"caches\": {},\n \"consistentId\": \"127.0.0.1:47501\",\n \"defaultCacheMode\": \"REPLICATED\",\n \"metrics\": {\n ...\n },\n \"nodeId\": \"2bd7b049-3fa0-4c44-9a6d-b5c7a597ce37\",\n \"replicaCount\": 128,\n \"tcpAddresses\": [\"127.0.0.1\"],\n \"tcpHostNames\": [\"\"],\n \"tcpPort\": 11212\n }\n ],\n \"successStatus\": 0\n}", + "language": "json" + } + ] +} +[/block] + +[block:parameters] +{ + "data": { + "h-0": "name", + "h-1": "type", + "h-2": "description", + "h-3": "example", + "0-0": "response", + "0-1": "jsonObject", + "0-2": "Information about grid topology.", + "0-3": "[\n{\n\"attributes\": {\n...\n},\n\"caches\": {},\n\"consistentId\": \"127.0.0.1:47500\",\n\"defaultCacheMode\": \"REPLICATED\",\n\"metrics\": {\n...\n},\n\"nodeId\": \"96baebd6-dedc-4a68-84fd-f804ee1ed995\",\n...\n\"tcpPort\": 11211\n},\n{\n\"attributes\": {\n...\n},\n\"caches\": {},\n\"consistentId\": \"127.0.0.1:47501\",\n\"defaultCacheMode\": \"REPLICATED\",\n\"metrics\": {\n...\n},\n\"nodeId\": \"2bd7b049-3fa0-4c44-9a6d-b5c7a597ce37\",\n...\n\"tcpPort\": 11212\n}\n]" + }, + "cols": 4, + "rows": 1 +} +[/block] + +[block:api-header] +{ + "type": "basic", + "title": "Execute" +} +[/block] +**Execute** command executes given task on grid. +[block:code] +{ + "codes": [ + { + "code": "http://host:port/ignite?cmd=exe&name=taskName&p1=param1&p2=param2&async=true", + "language": "curl" + } + ] +} +[/block] +##Request parameters +[block:parameters] +{ + "data": { + "h-0": "name", + "h-1": "type", + "h-2": "optional", + "h-3": "decription", + "h-4": "example", + "0-0": "cmd", + "0-4": "", + "0-1": "string", + "0-3": "Should be **exe** lowercase.", + "1-0": "name", + "1-1": "string", + "1-2": "", + "1-3": "Name of the task to execute.", + "1-4": "summ", + "2-0": "p1...pN", + "2-1": "string", + "2-3": "Argument of task execution.", + "2-4": "arg1...argN", + "3-0": "async", + "3-1": "boolean", + "3-3": "The flag determines whether the task is performed asynchronously.", + "3-4": "true", + "2-2": "Yes", + "3-2": "Yes" + }, + "cols": 5, + "rows": 4 +} +[/block] +##Response example +[block:code] +{ + "codes": [ + { + "code": "{\n \"error\": \"\",\n \"response\": {\n \"error\": \"\",\n \"finished\": true,\n \"id\": \"~ee2d1688-2605-4613-8a57-6615a8cbcd1b\",\n \"result\": 4\n },\n \"successStatus\": 0\n}", + "language": "json" + } + ] +} +[/block] + +[block:parameters] +{ + "data": { + "h-0": "name", + "h-1": "type", + "h-2": "description", + "h-3": "example", + "0-0": "response", + "0-1": "jsonObject", + "0-2": "JSON object contains message about error, unique identifier of task, result of computation and status of computation.", + "0-3": "{\n\"error\": \"\",\n\"finished\": true,\n\"id\": \"~ee2d1688-2605-4613-8a57-6615a8cbcd1b\",\n\"result\": 4\n}" + }, + "cols": 4, + "rows": 1 +} +[/block] + +[block:api-header] +{ + "type": "basic", + "title": "Result" +} +[/block] +**Result** command returns computation result for the given task. +[block:code] +{ + "codes": [ + { + "code": "http://host:port/ignite?cmd=res&id=8daab5ea-af83-4d91-99b6-77ed2ca06647", + "language": "curl" + } + ] +} +[/block] +##Request parameters +[block:parameters] +{ + "data": { + "h-0": "name", + "h-1": "type", + "h-2": "optional", + "h-3": "decription", + "h-4": "example", + "0-0": "cmd", + "0-4": "", + "0-1": "string", + "0-3": "Should be **res** lowercase.", + "1-0": "id", + "1-1": "string", + "1-2": "", + "1-3": "ID of the task whose result is to be returned.", + "1-4": "69ad0c48941-4689aae0-6b0e-4d52-8758-ce8fe26f497d~4689aae0-6b0e-4d52-8758-ce8fe26f497d" + }, + "cols": 5, + "rows": 2 +} +[/block] +##Response example +[block:code] +{ + "codes": [ + { + "code": "{\n \"error\": \"\",\n \"response\": {\n \"error\": \"\",\n \"finished\": true,\n \"id\": \"69ad0c48941-4689aae0-6b0e-4d52-8758-ce8fe26f497d~4689aae0-6b0e-4d52-8758-ce8fe26f497d\",\n \"result\": 4\n },\n \"successStatus\": 0\n}", + "language": "json" + } + ] +} +[/block] + +[block:parameters] +{ + "data": { + "h-0": "name", + "h-1": "type", + "h-2": "description", + "h-3": "example", + "0-0": "response", + "0-1": "jsonObject", + "0-2": "JSON object contains message about error, ID of task, result of computation and status of computation.", + "0-3": "{\n \"error\": \"\",\n \"finished\": true,\n \"id\": \"~ee2d1688-2605-4613-8a57-6615a8cbcd1b\",\n \"result\": 4\n}" + }, + "cols": 4, + "rows": 1 +} +[/block] \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/af603c00/docs/wiki/release-notes/release-notes.md ---------------------------------------------------------------------- diff --git a/docs/wiki/release-notes/release-notes.md b/docs/wiki/release-notes/release-notes.md new file mode 100755 index 0000000..5ef3021 --- /dev/null +++ b/docs/wiki/release-notes/release-notes.md @@ -0,0 +1,13 @@ +##Apache Ignite In-Memory Data Fabric 1.0 +This is the first release of Apache Ignite project. The source code is based on the 7 year old GridGain In-Memory Data Fabric, open source edition, v. 6.6.2, which was donated to Apache Software Foundation in September 2014. + +The main feature set of Ignite In-Memory Data Fabric includes: +* Advanced Clustering +* Compute Grid +* Data Grid +* Service Grid +* IGFS - Ignite File System +* Distributed Data Structures +* Distributed Messaging +* Distributed Events +* Streaming & CEP \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/af603c00/docs/wiki/service-grid/cluster-singletons.md ---------------------------------------------------------------------- diff --git a/docs/wiki/service-grid/cluster-singletons.md b/docs/wiki/service-grid/cluster-singletons.md new file mode 100755 index 0000000..f72ca41 --- /dev/null +++ b/docs/wiki/service-grid/cluster-singletons.md @@ -0,0 +1,94 @@ +`IgniteServices` facade allows to deploy any number of services on any of the grid nodes. However, the most commonly used feature is to deploy singleton services on the cluster. Ignite will manage the singleton contract regardless of topology changes and node crashes. +[block:callout] +{ + "type": "info", + "body": "Note that in case of topology changes, due to network delays, there may be a temporary situation when a singleton service instance will be active on more than one node (e.g. crash detection delay)." +} +[/block] + +[block:api-header] +{ + "type": "basic", + "title": "Cluster Singleton" +} +[/block] +You can deploy a cluster-wide singleton service. Ignite will guarantee that there is always one instance of the service in the cluster. In case the cluster node on which the service was deployed crashes or stops, Ignite will automatically redeploy it on another node. However, if the node on which the service is deployed remains in topology, then the service will always be deployed on that node only, regardless of topology changes. +[block:code] +{ + "codes": [ + { + "code": "IgniteServices svcs = ignite.services();\n\nsvcs.deployClusterSingleton(\"myClusterSingleton\", new MyService());", + "language": "java" + } + ] +} +[/block] +The above method is analogous to calling +[block:code] +{ + "codes": [ + { + "code": "svcs.deployMultiple(\"myClusterSingleton\", new MyService(), 1, 1)", + "language": "java" + } + ] +} +[/block] + +[block:api-header] +{ + "type": "basic", + "title": "Node Singleton" +} +[/block] +You can deploy a per-node singleton service. Ignite will guarantee that there is always one instance of the service running on each node. Whenever new nodes are started within the cluster group, Ignite will automatically deploy one instance of the service on every new node. +[block:code] +{ + "codes": [ + { + "code": "IgniteServices svcs = ignite.services();\n\nsvcs.deployNodeSingleton(\"myNodeSingleton\", new MyService());", + "language": "java" + } + ] +} +[/block] +The above method is analogous to calling +[block:code] +{ + "codes": [ + { + "code": "svcs.deployMultiple(\"myNodeSingleton\", new MyService(), 0, 1);", + "language": "java" + } + ] +} +[/block] + +[block:api-header] +{ + "type": "basic", + "title": "Cache Key Affinity Singleton" +} +[/block] +You can deploy one instance of this service on the primary node for a given affinity key. Whenever topology changes and primary key node assignment changes, Ignite will always make sure that the service is undeployed on the previous primary node and is deployed on the new primary node. +[block:code] +{ + "codes": [ + { + "code": "IgniteServices svcs = ignite.services();\n\nsvcs.deployKeyAffinitySingleton(\"myKeySingleton\", new MyService(), \"myCache\", new MyCacheKey());", + "language": "java" + } + ] +} +[/block] +The above method is analogous to calling +[block:code] +{ + "codes": [ + { + "code": "IgniteServices svcs = ignite.services();\n\nServiceConfiguration cfg = new ServiceConfiguration();\n \ncfg.setName(\"myKeySingleton\");\ncfg.setService(new MyService());\ncfg.setCacheName(\"myCache\");\ncfg.setAffinityKey(new MyCacheKey());\ncfg.setTotalCount(1);\ncfg.setMaxPerNodeCount(1);\n \nsvcs.deploy(cfg);", + "language": "java" + } + ] +} +[/block] \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/af603c00/docs/wiki/service-grid/service-configuration.md ---------------------------------------------------------------------- diff --git a/docs/wiki/service-grid/service-configuration.md b/docs/wiki/service-grid/service-configuration.md new file mode 100755 index 0000000..78ff357 --- /dev/null +++ b/docs/wiki/service-grid/service-configuration.md @@ -0,0 +1,33 @@ +In addition to deploying managed services by calling any of the provided `IgniteServices.deploy(...)` methods, you can also automatically deploy services on startup by setting `serviceConfiguration` property of IgniteConfiguration: +[block:code] +{ + "codes": [ + { + "code": "<bean class=\"org.apache.ignite.IgniteConfiguration\">\n ... \n <!-- Distributed Service configuration. -->\n <property name=\"serviceConfiguration\">\n <list>\n <bean class=\"org.apache.ignite.services.ServiceConfiguration\">\n <property name=\"name\" value=\"MyClusterSingletonSvc\"/>\n <property name=\"maxPerNodeCount\" value=\"1\"/>\n <property name=\"totalCount\" value=\"1\"/>\n <property name=\"service\">\n <ref bean=\"myServiceImpl\"/>\n </property>\n </bean>\n </list>\n </property>\n</bean>\n \n<bean id=\"myServiceImpl\" class=\"foo.bar.MyServiceImpl\">\n ...\n</bean>", + "language": "xml" + }, + { + "code": "ServiceConfiguration svcCfg1 = new ServiceConfiguration();\n \n// Cluster-wide singleton configuration.\nsvcCfg1.setName(\"MyClusterSingletonSvc\");\nsvcCfg1.setMaxPerNodeCount(1);\nsvcCfg1.setTotalCount(1);\nsvcCfg1.setService(new MyClusterSingletonImpl());\n \nServiceConfiguration svcCfg2 = new ServiceConfiguration();\n \n// Per-node singleton configuration.\nsvcCfg2.setName(\"MyNodeSingletonSvc\");\nsvcCfg2.setMaxPerNodeCount(1);\nsvcCfg2.setService(new MyNodeSingletonImpl());\n\nIgniteConfiguration igniteCfg = new IgniteConfiguration();\n \nigniteCfg.setServiceConfiguration(svcCfg1, svcCfg2);\n...\n\n// Start Ignite node.\nIgnition.start(gridCfg);", + "language": "java" + } + ] +} +[/block] + +[block:api-header] +{ + "type": "basic", + "title": "Deploying After Startup" +} +[/block] +You can configure and deploy services after the startup of Ignite nodes. Besides multiple convenience methods that allow deployment of various [cluster singletons](doc:cluster-singletons), you can also create and deploy service with custom configuration. +[block:code] +{ + "codes": [ + { + "code": "ServiceConfiguration cfg = new ServiceConfiguration();\n \ncfg.setName(\"myService\");\ncfg.setService(new MyService());\n\n// Maximum of 4 service instances within cluster.\ncfg.setTotalCount(4);\n\n// Maximum of 2 service instances per each Ignite node.\ncfg.setMaxPerNodeCount(2);\n \nignite.services().deploy(cfg);", + "language": "java" + } + ] +} +[/block] \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/af603c00/docs/wiki/service-grid/service-example.md ---------------------------------------------------------------------- diff --git a/docs/wiki/service-grid/service-example.md b/docs/wiki/service-grid/service-example.md new file mode 100755 index 0000000..ecc8cda --- /dev/null +++ b/docs/wiki/service-grid/service-example.md @@ -0,0 +1,94 @@ +[block:api-header] +{ + "type": "basic", + "title": "Define Your Service Interface" +} +[/block] +As an example, let's define a simple counter service as a `MyCounterService` interface. Note that this is a simple Java interface without any special annotations or methods. +[block:code] +{ + "codes": [ + { + "code": "public class MyCounterService {\n /**\n * Increment counter value and return the new value.\n */\n int increment() throws CacheException;\n \n /**\n * Get current counter value.\n */\n int get() throws CacheException;\n}", + "language": "java" + } + ] +} +[/block] + +[block:api-header] +{ + "type": "basic", + "title": "Service Implementation" +} +[/block] +An implementation of a distributed service has to implement both, `Service` and `MyCounterService` interfaces. + +We implement our counter service by storing the counter value in cache. The key for this counter value is the name of the service. This allows us to reuse the same cache for multiple instances of the counter service. +[block:code] +{ + "codes": [ + { + "code": "public class MyCounterServiceImpl implements Service, MyCounterService {\n /** Auto-injected instance of Ignite. */\n @IgniteInstanceResource\n private Ignite ignite;\n\n /** Distributed cache used to store counters. */\n private IgniteCache<String, Integer> cache;\n\n /** Service name. */\n private String svcName;\n\n /**\n * Service initialization.\n */\n @Override public void init(ServiceContext ctx) {\n // Pre-configured cache to store counters.\n cache = ignite.cache(\"myCounterCache\");\n\n svcName = ctx.name();\n\n System.out.println(\"Service was initialized: \" + svcName);\n }\n\n /**\n * Cancel this service.\n */\n @Override public void cancel(ServiceContext ctx) {\n // Remove counter from cache.\n cache.remove(svcName);\n \n System.out.println(\"Service was cancelled: \" + svcName);\n }\n\n /**\n * Start service execution.\n */\n @Override public void execute(ServiceContext ctx) {\n // Since our service is simply represented by a counter\n // value stored in cache, there is nothing we need\n // to do in order to start it up.\n System.out.println(\"Executing distributed service: \" + svcName);\n }\n\n @Override public int get() throws CacheException {\n Integer i = cache.get(svcName);\n\n return i == null ? 0 : i;\n }\n\n @Override public int increment() throws CacheException {\n return cache.invoke(svcName, new CounterEntryProcessor());\n }\n\n /**\n * Entry processor which atomically increments value currently stored in cache.\n */\n private static class CounterEntryProcessor implements EntryProcessor<String, Integer, Integer> {\n @Override public Integer process(MutableEntry<String, Integer> e, Object... args) {\n int newVal = e.exists() ? e.getValue() + 1 : 1;\n \n // Update cache.\n e.setValue(newVal);\n\n return newVal;\n } \n }\n}", + "language": "java" + } + ] +} +[/block] + +[block:api-header] +{ + "type": "basic", + "title": "Service Deployment" +} +[/block] +We should deploy our counter service as per-node-singleton within the cluster group that has our cache "myCounterCache" deployed. +[block:code] +{ + "codes": [ + { + "code": "// Cluster group which includes all caching nodes.\nClusterGroup cacheGrp = ignite.cluster().forCache(\"myCounterService\");\n\n// Get an instance of IgniteServices for the cluster group.\nIgniteServices svcs = ignite.services(cacheGrp);\n \n// Deploy per-node singleton. An instance of the service\n// will be deployed on every node within the cluster group.\nsvcs.deployNodeSingleton(\"myCounterService\", new MyCounterServiceImpl());", + "language": "java" + } + ] +} +[/block] + +[block:api-header] +{ + "type": "basic", + "title": "Service Proxy" +} +[/block] +You can access an instance of the deployed service from any node within the cluster. If the service is deployed on that node, then the locally deployed instance will be returned. Otherwise, if service is not locally available, a remote proxy for the service will be created automatically. + +# Sticky vs Not-Sticky Proxies +Proxies can be either *sticky* or not. If proxy is sticky, then Ignite will always go back to the same cluster node to contact a remotely deployed service. If proxy is *not-sticky*, then Ignite will load balance remote service proxy invocations among all cluster nodes on which the service is deployed. +[block:code] +{ + "codes": [ + { + "code": "// Get service proxy for the deployed service.\nMyCounterService cntrSvc = ignite.services().\n serviceProxy(\"myCounterService\", MyCounterService.class, /*not-sticky*/false);\n\n// Ivoke a method on 'MyCounterService' interface.\ncntrSvc.increment();\n\n// Print latest counter value from our counter service.\nSystem.out.println(\"Incremented value : \" + cntrSvc.get());", + "language": "java" + } + ] +} +[/block] + +[block:api-header] +{ + "type": "basic", + "title": "Access Service from Computations" +} +[/block] +For convenience, you can inject an instance of service proxy into your computation using `@ServiceResource` annotation. +[block:code] +{ + "codes": [ + { + "code": "IgniteCompute compute = igntie.compute();\n\ncompute.run(new IgniteRunnable() {\n @ServiceResource(serviceName = \"myCounterService\");\n private MyCounterService counterSvc;\n \n public void run() {\n\t\t// Ivoke a method on 'MyCounterService' interface.\n\t\tint newValue = cntrSvc.increment();\n\n\t\t// Print latest counter value from our counter service.\n\t\tSystem.out.println(\"Incremented value : \" + newValue);\n }\n});", + "language": "java" + } + ] +} +[/block] \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/af603c00/docs/wiki/service-grid/service-grid.md ---------------------------------------------------------------------- diff --git a/docs/wiki/service-grid/service-grid.md b/docs/wiki/service-grid/service-grid.md new file mode 100755 index 0000000..22ac521 --- /dev/null +++ b/docs/wiki/service-grid/service-grid.md @@ -0,0 +1,62 @@ +Service Grid allows for deployments of arbitrary user-defined services on the cluster. You can implement and deploy any service, such as custom counters, ID generators, hierarchical maps, etc. + +Ignite allows you to control how many instances of your service should be deployed on each cluster node and will automatically ensure proper deployment and fault tolerance of all the services . + +##Features + * **Continuous availability** of deployed services regardless of topology changes or crashes. + * Automatically deploy any number of distributed service instances in the cluster. + * Automatically deploy [singletons](doc:cluster-singletons), including cluster-singleton, node-singleton, or key-affinity-singleton. + * Automatically deploy distributed services on node start-up by specifying them in the configuration. + * Undeploy any of the deployed services. + * Get information about service deployment topology within the cluster. + * Create service proxy for accessing remotely deployed distributed services. +[block:callout] +{ + "type": "success", + "body": "Please refer to [Service Example](doc:service-example) for information on service deployment and accessing service API." +} +[/block] + +[block:api-header] +{ + "type": "basic", + "title": "IgniteServices" +} +[/block] +All service grid functionality is available via `IgniteServices` interface. +[block:code] +{ + "codes": [ + { + "code": "Ignite ignite = Ignition.ignite();\n\n// Get services instance spanning all nodes in the cluster.\nIgniteServices svcs = ignite.services();", + "language": "java" + } + ] +} +[/block] +You can also limit the scope of service deployment to a Cluster Group. In this case, services will only span the nodes within the cluster group. +[block:code] +{ + "codes": [ + { + "code": "Ignite ignite = Ignitition.ignite();\n\nClusterGroup remoteGroup = ignite.cluster().forRemotes();\n\n// Limit service deployment only to remote nodes (exclude the local node).\nIgniteServices svcs = ignite.services(remoteGroup);", + "language": "java" + } + ] +} +[/block] + +[block:api-header] +{ + "type": "basic", + "title": "Load Balancing" +} +[/block] +In all cases, other than singleton service deployment, Ignite will automatically make sure that about an equal number of services are deployed on each node within the cluster. Whenever cluster topology changes, Ignite will re-evaluate service deployments and may re-deploy an already deployed service on another node for better load balancing. +[block:api-header] +{ + "type": "basic", + "title": "Fault Tolerance" +} +[/block] +Ignite always guarantees that services are continuously available, and are deployed according to the specified configuration, regardless of any topology changes or node crashes. \ No newline at end of file