ignite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sboi...@apache.org
Subject [22/50] [abbrv] incubator-ignite git commit: # ignite-63
Date Fri, 23 Jan 2015 09:02:30 GMT
# ignite-63


Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/d0e6cace
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/d0e6cace
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/d0e6cace

Branch: refs/heads/ignite-63
Commit: d0e6cacef068ac12bc85bdc51925d81b1933ce22
Parents: 4b25edc
Author: sboikov <sboikov@gridgain.com>
Authored: Fri Jan 23 10:54:09 2015 +0300
Committer: sboikov <sboikov@gridgain.com>
Committed: Fri Jan 23 10:54:09 2015 +0300

----------------------------------------------------------------------
 .../examples/misc/springbean/spring-bean.xml    |   2 +-
 ...idHadoopDefaultMapReducePlannerSelfTest.java |   1 -
 .../schedule/GridScheduleSelfTest.java          | 401 ++++++++++
 .../bamboo/GridSchedulerTestSuite.java          |   2 +-
 .../grid/kernal/GridScheduleSelfTest.java       | 401 ----------
 .../ignite/logger/slf4j/GridSlf4jLogger.java    | 141 ++++
 .../org/apache/ignite/logger/slf4j/package.html |  23 +
 .../grid/logger/slf4j/GridSlf4jLogger.java      | 141 ----
 .../org/gridgain/grid/logger/slf4j/package.html |  23 -
 .../java/org/apache/ignite/GridGainSpring.java  | 117 +++
 .../java/org/apache/ignite/GridSpringBean.java  | 342 ++++++++
 .../ignite/cache/spring/GridSpringCache.java    | 185 +++++
 .../cache/spring/GridSpringCacheManager.java    | 241 ++++++
 .../spring/GridSpringDynamicCacheManager.java   | 316 ++++++++
 .../org/apache/ignite/cache/spring/package.html |  23 +
 .../java/org/gridgain/grid/GridGainSpring.java  | 118 ---
 .../java/org/gridgain/grid/GridSpringBean.java  | 343 --------
 .../grid/cache/spring/GridSpringCache.java      | 185 -----
 .../cache/spring/GridSpringCacheManager.java    | 241 ------
 .../spring/GridSpringDynamicCacheManager.java   | 316 --------
 .../org/gridgain/grid/cache/spring/package.html |  23 -
 .../ignite/internal/GridFactorySelfTest.java    | 790 ++++++++++++++++++
 .../GridSpringBeanSerializationSelfTest.java    |  92 +++
 .../p2p/GridP2PUserVersionChangeSelfTest.java   | 357 +++++++++
 .../spring/GridSpringCacheManagerSelfTest.java  | 237 ++++++
 .../ignite/spring/GridSpringCacheTestKey.java   |  59 ++
 .../spring/GridSpringCacheTestKeyGenerator.java |  41 +
 .../spring/GridSpringCacheTestService.java      | 124 +++
 .../GridSpringDynamicCacheManagerSelfTest.java  | 219 +++++
 .../GridSpringDynamicCacheTestService.java      |  62 ++
 .../org/apache/ignite/spring/spring-caching.xml |  47 ++
 .../ignite/spring/spring-dynamic-caching.xml    |  43 +
 .../testsuites/bamboo/GridSpringTestSuite.java  |   5 +-
 .../spring/GridSpringCacheManagerSelfTest.java  | 237 ------
 .../cache/spring/GridSpringCacheTestKey.java    |  59 --
 .../spring/GridSpringCacheTestKeyGenerator.java |  41 -
 .../spring/GridSpringCacheTestService.java      | 124 ---
 .../GridSpringDynamicCacheManagerSelfTest.java  | 218 -----
 .../GridSpringDynamicCacheTestService.java      |  62 --
 .../grid/cache/spring/spring-caching.xml        |  47 --
 .../cache/spring/spring-dynamic-caching.xml     |  43 -
 .../grid/kernal/GridFactorySelfTest.java        | 791 -------------------
 .../GridSpringBeanSerializationSelfTest.java    |  92 ---
 .../p2p/GridP2PUserVersionChangeSelfTest.java   | 357 ---------
 44 files changed, 3865 insertions(+), 3867 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d0e6cace/examples/src/main/java/org/apache/ignite/examples/misc/springbean/spring-bean.xml
----------------------------------------------------------------------
diff --git a/examples/src/main/java/org/apache/ignite/examples/misc/springbean/spring-bean.xml b/examples/src/main/java/org/apache/ignite/examples/misc/springbean/spring-bean.xml
index 4eed607..8670632 100644
--- a/examples/src/main/java/org/apache/ignite/examples/misc/springbean/spring-bean.xml
+++ b/examples/src/main/java/org/apache/ignite/examples/misc/springbean/spring-bean.xml
@@ -29,7 +29,7 @@
     <description>Main Spring file for grid configuration.</description>
 
     <!-- Example of bean definition with given configuration. -->
-    <bean id="mySpringBean" class="org.gridgain.grid.GridSpringBean">
+    <bean id="mySpringBean" class="org.apache.ignite.GridSpringBean">
         <property name="configuration">
             <bean id="grid.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
                 <!-- Set to local host address just for examples. -->

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d0e6cace/modules/hadoop/src/test/java/org/apache/ignite/internal/processors/hadoop/GridHadoopDefaultMapReducePlannerSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/hadoop/src/test/java/org/apache/ignite/internal/processors/hadoop/GridHadoopDefaultMapReducePlannerSelfTest.java b/modules/hadoop/src/test/java/org/apache/ignite/internal/processors/hadoop/GridHadoopDefaultMapReducePlannerSelfTest.java
index 5c48b5a..9ef184d 100644
--- a/modules/hadoop/src/test/java/org/apache/ignite/internal/processors/hadoop/GridHadoopDefaultMapReducePlannerSelfTest.java
+++ b/modules/hadoop/src/test/java/org/apache/ignite/internal/processors/hadoop/GridHadoopDefaultMapReducePlannerSelfTest.java
@@ -26,7 +26,6 @@ import org.apache.ignite.internal.*;
 import org.apache.ignite.internal.processors.cache.*;
 import org.apache.ignite.internal.processors.fs.*;
 import org.apache.ignite.lang.*;
-import org.gridgain.grid.*;
 import org.apache.ignite.hadoop.*;
 import org.apache.ignite.internal.processors.hadoop.planner.*;
 import org.apache.ignite.internal.processors.interop.*;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d0e6cace/modules/schedule/src/test/java/org/apache/ignite/internal/processors/schedule/GridScheduleSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/schedule/src/test/java/org/apache/ignite/internal/processors/schedule/GridScheduleSelfTest.java b/modules/schedule/src/test/java/org/apache/ignite/internal/processors/schedule/GridScheduleSelfTest.java
new file mode 100644
index 0000000..a7121b2
--- /dev/null
+++ b/modules/schedule/src/test/java/org/apache/ignite/internal/processors/schedule/GridScheduleSelfTest.java
@@ -0,0 +1,401 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.schedule;
+
+import org.apache.ignite.*;
+import org.apache.ignite.lang.*;
+import org.apache.ignite.resources.*;
+import org.apache.ignite.scheduler.*;
+import org.apache.ignite.internal.util.typedef.*;
+import org.apache.ignite.internal.util.lang.*;
+import org.apache.ignite.testframework.junits.common.*;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.*;
+
+import static java.util.concurrent.TimeUnit.*;
+
+/**
+ * Test for task scheduler.
+ */
+@SuppressWarnings({"ProhibitedExceptionDeclared", "TooBroadScope"})
+public class GridScheduleSelfTest extends GridCommonAbstractTest {
+    /** */
+    private static final int NODES_CNT = 2;
+
+    /** */
+    private static AtomicInteger execCntr = new AtomicInteger(0);
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTestsStarted() throws Exception {
+        startGrids(NODES_CNT);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTestsStopped() throws Exception {
+        stopAllGrids();
+
+        super.afterTestsStopped();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTest() throws Exception {
+        execCntr.set(0);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testRunLocal() throws Exception {
+        for (int i = 0; i < NODES_CNT; i++) {
+            IgniteFuture<?> fut = grid(i).scheduler().runLocal(new TestRunnable());
+
+            assert fut.get() == null;
+
+            assertEquals(1, execCntr.getAndSet(0));
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testCallLocal() throws Exception {
+        for (int i = 0; i < NODES_CNT; i++) {
+            IgniteFuture<?> fut = grid(i).scheduler().callLocal(new TestCallable());
+
+            assertEquals(1, fut.get());
+
+            assertEquals(1, execCntr.getAndSet(0));
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testScheduleRunnable() throws Exception {
+        final CountDownLatch latch = new CountDownLatch(1);
+
+        SchedulerFuture<?> fut = null;
+
+        long freq = 60; // 1 minute frequency.
+        long delay = 2; // 2 seconds delay.
+
+        try {
+            // Execute 2 times after 2 seconds delay every minute.
+            fut = grid(0).scheduler().scheduleLocal(
+                new Runnable() {
+                    @Override public void run() {
+                        latch.countDown();
+
+                        info(">>> EXECUTING SCHEDULED RUNNABLE! <<<");
+                    }
+                },
+                "{2, 2} * * * * *");
+
+            assert !fut.isDone();
+            assert !fut.isCancelled();
+            assert fut.last() == null;
+
+            final AtomicInteger notifyCnt = new AtomicInteger();
+
+            fut.listenAsync(new CI1<IgniteFuture<?>>() {
+                @Override public void apply(IgniteFuture<?> e) {
+                    notifyCnt.incrementAndGet();
+                }
+            });
+
+            long timeTillRun = freq + delay;
+
+            info("Going to wait for the first run: " + timeTillRun);
+
+            latch.await(timeTillRun, SECONDS);
+
+            assertEquals(0, latch.getCount());
+
+            assert !fut.isDone();
+            assert !fut.isCancelled();
+            assert fut.last() == null;
+
+            info("Going to wait for 2nd run: " + timeTillRun);
+
+            // Wait until scheduling will be finished.
+            Thread.sleep(timeTillRun * 1000);
+
+            assert fut.isDone();
+            assert notifyCnt.get() == 2;
+            assert !fut.isCancelled();
+            assert fut.last() == null;
+
+        }
+        finally {
+            assert fut != null;
+
+            fut.cancel();
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testScheduleCallable() throws Exception {
+        SchedulerFuture<Integer> fut = null;
+
+        long freq = 60; // 1 minute frequency.
+        long delay = 2; // 2 seconds delay.
+
+        try {
+            fut = grid(0).scheduler().scheduleLocal(new Callable<Integer>() {
+                private int cnt;
+
+                @Override public Integer call() {
+                    info(">>> EXECUTING SCHEDULED CALLABLE! <<<");
+
+                    return ++cnt;
+                }
+            }, "{1, 2} * * * * *");
+
+            final AtomicInteger notifyCnt = new AtomicInteger();
+
+            fut.listenAsync(new CI1<IgniteFuture<?>>() {
+                @Override public void apply(IgniteFuture<?> e) {
+                    notifyCnt.incrementAndGet();
+                }
+            });
+
+            assert !fut.isDone();
+            assert !fut.isCancelled();
+            assert fut.last() == null;
+
+            long timeTillRun = freq + delay;
+
+            info("Going to wait for the 1st run: " + timeTillRun);
+
+            assertEquals((Integer)1, fut.get(timeTillRun, SECONDS));
+            assertEquals((Integer)1, fut.last());
+
+            assert !fut.isDone();
+            assert !fut.isCancelled();
+
+            info("Going to wait for the 2nd run: " + timeTillRun);
+
+            assertEquals((Integer)2, fut.get(timeTillRun, SECONDS));
+            assertEquals((Integer)2, fut.last());
+
+            assert fut.isDone();
+            assert !fut.isCancelled();
+        }
+        finally {
+            assert fut != null;
+
+            fut.cancel();
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testRunnableCancel() throws Exception {
+        SchedulerFuture fut = null;
+
+        final GridTuple<Integer> tpl = new GridTuple<>(0);
+
+        try {
+            fut = grid(0).scheduler().scheduleLocal(new Runnable() {
+                @Override public void run() {
+                    tpl.set(tpl.get() + 1);
+                }
+            }, "{1, *} * * * * *");
+
+            assertEquals(Integer.valueOf(0), tpl.get());
+
+            fut.cancel();
+
+            assert fut.isCancelled();
+            assert fut.isDone();
+
+            assertEquals(Integer.valueOf(0), tpl.get());
+
+            try {
+                fut.get();
+
+                fail("IgniteCheckedException must have been thrown");
+            }
+            catch (IgniteCheckedException e) {
+                info("Caught expected exception: " + e);
+            }
+
+            try {
+                fut.get(500, SECONDS);
+
+                fail("IgniteCheckedException must have been thrown");
+            }
+            catch (IgniteCheckedException e) {
+                info("Caught expected exception: " + e);
+            }
+        }
+        finally {
+            assert fut != null;
+
+            if (!fut.isCancelled())
+                fut.cancel();
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testInvalidPatterns() throws Exception {
+        Runnable run = new Runnable() {
+            @Override public void run() {
+                // No-op.
+            }
+        };
+
+        try {
+            // Invalid delay.
+            grid(0).scheduler().scheduleLocal(run, "{sdf, *} * * * * *").get();
+
+            fail("IgniteCheckedException must have been thrown");
+        }
+        catch (IgniteCheckedException e) {
+            info("Caught expected exception: " + e);
+        }
+
+        try {
+            // Invalid delay.
+            grid(0).scheduler().scheduleLocal(run, "{**, *} * * * * *").get();
+
+            fail("IgniteCheckedException must have been thrown");
+        }
+        catch (IgniteCheckedException e) {
+            info("Caught expected exception: " + e);
+        }
+
+        try {
+            // Invalid number of executions.
+            grid(0).scheduler().scheduleLocal(run, "{1, ghd} * * * * *").get();
+
+            fail("IgniteCheckedException must have been thrown");
+        }
+        catch (IgniteCheckedException e) {
+            info("Caught expected exception: " + e);
+        }
+
+        try {
+            // Number of executions in pattern must be greater than zero or equal to "*".
+            grid(0).scheduler().scheduleLocal(run, "{*, 0} * * * * *").get();
+
+            fail("IgniteCheckedException must have been thrown");
+        }
+        catch (IgniteCheckedException e) {
+            info("Caught expected exception: " + e);
+        }
+
+        try {
+            // Invalid cron expression.
+            grid(0).scheduler().scheduleLocal(run, "{2, 6} * * * * * * * * * *").get();
+
+            fail("IgniteCheckedException must have been thrown");
+        }
+        catch (IgniteCheckedException e) {
+            info("Caught expected exception: " + e);
+        }
+
+        try {
+            // Invalid both delay and number of calls.
+            grid(0).scheduler().scheduleLocal(run, "{-2, -6} * * * * *").get();
+
+            fail("IgniteCheckedException must have been thrown");
+        }
+        catch (IgniteCheckedException e) {
+            info("Caught expected exception: " + e);
+        }
+    }
+
+    /**
+     * Waits until method {@link org.apache.ignite.scheduler.SchedulerFuture#last()} returns not a null value. Tries to call specified number
+     * of attempts with 100ms interval between them.
+     *
+     * @param fut Schedule future to call method on.
+     * @param attempts Max number of attempts to try.
+     * @return {@code true} if wait is successful, {@code false} if attempts are exhausted.
+     * @throws Exception If failed.
+     */
+    @SuppressWarnings("BusyWait")
+    private boolean waitForLastResult(SchedulerFuture<Integer> fut, int attempts) throws Exception {
+        assert fut != null;
+        assert attempts > 0;
+
+        boolean success = false;
+
+        for (int i = 0; i < attempts; i++) {
+            if (fut.last() != null) {
+
+                success = true;
+
+                break;
+            }
+
+            Thread.sleep(100);
+        }
+
+        return success;
+    }
+
+    /**
+     * Test runnable job.
+     */
+    private static class TestRunnable implements IgniteRunnable {
+        /** */
+        @IgniteInstanceResource
+        private Ignite ignite;
+
+        /** */
+        @IgniteLoggerResource
+        private IgniteLogger log;
+
+        /** @{inheritDoc} */
+        @Override public void run() {
+            log.info("Runnable job executed on node: " + ignite.cluster().localNode().id());
+
+            assert ignite != null;
+
+            execCntr.incrementAndGet();
+        }
+    }
+    /**
+     * Test callable job.
+     */
+    private static class TestCallable implements IgniteCallable<Integer> {
+        /** */
+        @IgniteInstanceResource
+        private Ignite ignite;
+
+        /** */
+        @IgniteLoggerResource
+        private IgniteLogger log;
+
+        /** {@inheritDoc} */
+        @Override public Integer call() {
+            log.info("Callable job executed on node: " + ignite.cluster().localNode().id());
+
+            assert ignite != null;
+
+            return execCntr.incrementAndGet();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d0e6cace/modules/schedule/src/test/java/org/apache/ignite/testsuites/bamboo/GridSchedulerTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/schedule/src/test/java/org/apache/ignite/testsuites/bamboo/GridSchedulerTestSuite.java b/modules/schedule/src/test/java/org/apache/ignite/testsuites/bamboo/GridSchedulerTestSuite.java
index 8e8b9e2..7a0e0b6 100644
--- a/modules/schedule/src/test/java/org/apache/ignite/testsuites/bamboo/GridSchedulerTestSuite.java
+++ b/modules/schedule/src/test/java/org/apache/ignite/testsuites/bamboo/GridSchedulerTestSuite.java
@@ -18,7 +18,7 @@
 package org.apache.ignite.testsuites.bamboo;
 
 import junit.framework.*;
-import org.gridgain.grid.kernal.*;
+import org.apache.ignite.internal.processors.schedule.*;
 
 /**
  * Scheduler tests.

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d0e6cace/modules/schedule/src/test/java/org/gridgain/grid/kernal/GridScheduleSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/schedule/src/test/java/org/gridgain/grid/kernal/GridScheduleSelfTest.java b/modules/schedule/src/test/java/org/gridgain/grid/kernal/GridScheduleSelfTest.java
deleted file mode 100644
index 5a3ebb1..0000000
--- a/modules/schedule/src/test/java/org/gridgain/grid/kernal/GridScheduleSelfTest.java
+++ /dev/null
@@ -1,401 +0,0 @@
-/*
- * 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.gridgain.grid.kernal;
-
-import org.apache.ignite.*;
-import org.apache.ignite.lang.*;
-import org.apache.ignite.resources.*;
-import org.apache.ignite.scheduler.*;
-import org.apache.ignite.internal.util.typedef.*;
-import org.apache.ignite.internal.util.lang.*;
-import org.apache.ignite.testframework.junits.common.*;
-import java.util.concurrent.*;
-import java.util.concurrent.atomic.*;
-
-import static java.util.concurrent.TimeUnit.*;
-
-/**
- * Test for task scheduler.
- */
-@SuppressWarnings({"ProhibitedExceptionDeclared", "TooBroadScope"})
-public class GridScheduleSelfTest extends GridCommonAbstractTest {
-    /** */
-    private static final int NODES_CNT = 2;
-
-    /** */
-    private static AtomicInteger execCntr = new AtomicInteger(0);
-
-    /** {@inheritDoc} */
-    @Override protected void beforeTestsStarted() throws Exception {
-        startGrids(NODES_CNT);
-    }
-
-    /** {@inheritDoc} */
-    @Override protected void afterTestsStopped() throws Exception {
-        stopAllGrids();
-
-        super.afterTestsStopped();
-    }
-
-    /** {@inheritDoc} */
-    @Override protected void beforeTest() throws Exception {
-        execCntr.set(0);
-    }
-
-    /**
-     * @throws Exception If failed.
-     */
-    public void testRunLocal() throws Exception {
-        for (int i = 0; i < NODES_CNT; i++) {
-            IgniteFuture<?> fut = grid(i).scheduler().runLocal(new TestRunnable());
-
-            assert fut.get() == null;
-
-            assertEquals(1, execCntr.getAndSet(0));
-        }
-    }
-
-    /**
-     * @throws Exception If failed.
-     */
-    public void testCallLocal() throws Exception {
-        for (int i = 0; i < NODES_CNT; i++) {
-            IgniteFuture<?> fut = grid(i).scheduler().callLocal(new TestCallable());
-
-            assertEquals(1, fut.get());
-
-            assertEquals(1, execCntr.getAndSet(0));
-        }
-    }
-
-    /**
-     * @throws Exception If failed.
-     */
-    public void testScheduleRunnable() throws Exception {
-        final CountDownLatch latch = new CountDownLatch(1);
-
-        SchedulerFuture<?> fut = null;
-
-        long freq = 60; // 1 minute frequency.
-        long delay = 2; // 2 seconds delay.
-
-        try {
-            // Execute 2 times after 2 seconds delay every minute.
-            fut = grid(0).scheduler().scheduleLocal(
-                new Runnable() {
-                    @Override public void run() {
-                        latch.countDown();
-
-                        info(">>> EXECUTING SCHEDULED RUNNABLE! <<<");
-                    }
-                },
-                "{2, 2} * * * * *");
-
-            assert !fut.isDone();
-            assert !fut.isCancelled();
-            assert fut.last() == null;
-
-            final AtomicInteger notifyCnt = new AtomicInteger();
-
-            fut.listenAsync(new CI1<IgniteFuture<?>>() {
-                @Override public void apply(IgniteFuture<?> e) {
-                    notifyCnt.incrementAndGet();
-                }
-            });
-
-            long timeTillRun = freq + delay;
-
-            info("Going to wait for the first run: " + timeTillRun);
-
-            latch.await(timeTillRun, SECONDS);
-
-            assertEquals(0, latch.getCount());
-
-            assert !fut.isDone();
-            assert !fut.isCancelled();
-            assert fut.last() == null;
-
-            info("Going to wait for 2nd run: " + timeTillRun);
-
-            // Wait until scheduling will be finished.
-            Thread.sleep(timeTillRun * 1000);
-
-            assert fut.isDone();
-            assert notifyCnt.get() == 2;
-            assert !fut.isCancelled();
-            assert fut.last() == null;
-
-        }
-        finally {
-            assert fut != null;
-
-            fut.cancel();
-        }
-    }
-
-    /**
-     * @throws Exception If failed.
-     */
-    public void testScheduleCallable() throws Exception {
-        SchedulerFuture<Integer> fut = null;
-
-        long freq = 60; // 1 minute frequency.
-        long delay = 2; // 2 seconds delay.
-
-        try {
-            fut = grid(0).scheduler().scheduleLocal(new Callable<Integer>() {
-                private int cnt;
-
-                @Override public Integer call() {
-                    info(">>> EXECUTING SCHEDULED CALLABLE! <<<");
-
-                    return ++cnt;
-                }
-            }, "{1, 2} * * * * *");
-
-            final AtomicInteger notifyCnt = new AtomicInteger();
-
-            fut.listenAsync(new CI1<IgniteFuture<?>>() {
-                @Override public void apply(IgniteFuture<?> e) {
-                    notifyCnt.incrementAndGet();
-                }
-            });
-
-            assert !fut.isDone();
-            assert !fut.isCancelled();
-            assert fut.last() == null;
-
-            long timeTillRun = freq + delay;
-
-            info("Going to wait for the 1st run: " + timeTillRun);
-
-            assertEquals((Integer)1, fut.get(timeTillRun, SECONDS));
-            assertEquals((Integer)1, fut.last());
-
-            assert !fut.isDone();
-            assert !fut.isCancelled();
-
-            info("Going to wait for the 2nd run: " + timeTillRun);
-
-            assertEquals((Integer)2, fut.get(timeTillRun, SECONDS));
-            assertEquals((Integer)2, fut.last());
-
-            assert fut.isDone();
-            assert !fut.isCancelled();
-        }
-        finally {
-            assert fut != null;
-
-            fut.cancel();
-        }
-    }
-
-    /**
-     * @throws Exception If failed.
-     */
-    public void testRunnableCancel() throws Exception {
-        SchedulerFuture fut = null;
-
-        final GridTuple<Integer> tpl = new GridTuple<>(0);
-
-        try {
-            fut = grid(0).scheduler().scheduleLocal(new Runnable() {
-                @Override public void run() {
-                    tpl.set(tpl.get() + 1);
-                }
-            }, "{1, *} * * * * *");
-
-            assertEquals(Integer.valueOf(0), tpl.get());
-
-            fut.cancel();
-
-            assert fut.isCancelled();
-            assert fut.isDone();
-
-            assertEquals(Integer.valueOf(0), tpl.get());
-
-            try {
-                fut.get();
-
-                fail("IgniteCheckedException must have been thrown");
-            }
-            catch (IgniteCheckedException e) {
-                info("Caught expected exception: " + e);
-            }
-
-            try {
-                fut.get(500, SECONDS);
-
-                fail("IgniteCheckedException must have been thrown");
-            }
-            catch (IgniteCheckedException e) {
-                info("Caught expected exception: " + e);
-            }
-        }
-        finally {
-            assert fut != null;
-
-            if (!fut.isCancelled())
-                fut.cancel();
-        }
-    }
-
-    /**
-     * @throws Exception If failed.
-     */
-    public void testInvalidPatterns() throws Exception {
-        Runnable run = new Runnable() {
-            @Override public void run() {
-                // No-op.
-            }
-        };
-
-        try {
-            // Invalid delay.
-            grid(0).scheduler().scheduleLocal(run, "{sdf, *} * * * * *").get();
-
-            fail("IgniteCheckedException must have been thrown");
-        }
-        catch (IgniteCheckedException e) {
-            info("Caught expected exception: " + e);
-        }
-
-        try {
-            // Invalid delay.
-            grid(0).scheduler().scheduleLocal(run, "{**, *} * * * * *").get();
-
-            fail("IgniteCheckedException must have been thrown");
-        }
-        catch (IgniteCheckedException e) {
-            info("Caught expected exception: " + e);
-        }
-
-        try {
-            // Invalid number of executions.
-            grid(0).scheduler().scheduleLocal(run, "{1, ghd} * * * * *").get();
-
-            fail("IgniteCheckedException must have been thrown");
-        }
-        catch (IgniteCheckedException e) {
-            info("Caught expected exception: " + e);
-        }
-
-        try {
-            // Number of executions in pattern must be greater than zero or equal to "*".
-            grid(0).scheduler().scheduleLocal(run, "{*, 0} * * * * *").get();
-
-            fail("IgniteCheckedException must have been thrown");
-        }
-        catch (IgniteCheckedException e) {
-            info("Caught expected exception: " + e);
-        }
-
-        try {
-            // Invalid cron expression.
-            grid(0).scheduler().scheduleLocal(run, "{2, 6} * * * * * * * * * *").get();
-
-            fail("IgniteCheckedException must have been thrown");
-        }
-        catch (IgniteCheckedException e) {
-            info("Caught expected exception: " + e);
-        }
-
-        try {
-            // Invalid both delay and number of calls.
-            grid(0).scheduler().scheduleLocal(run, "{-2, -6} * * * * *").get();
-
-            fail("IgniteCheckedException must have been thrown");
-        }
-        catch (IgniteCheckedException e) {
-            info("Caught expected exception: " + e);
-        }
-    }
-
-    /**
-     * Waits until method {@link org.apache.ignite.scheduler.SchedulerFuture#last()} returns not a null value. Tries to call specified number
-     * of attempts with 100ms interval between them.
-     *
-     * @param fut Schedule future to call method on.
-     * @param attempts Max number of attempts to try.
-     * @return {@code true} if wait is successful, {@code false} if attempts are exhausted.
-     * @throws Exception If failed.
-     */
-    @SuppressWarnings("BusyWait")
-    private boolean waitForLastResult(SchedulerFuture<Integer> fut, int attempts) throws Exception {
-        assert fut != null;
-        assert attempts > 0;
-
-        boolean success = false;
-
-        for (int i = 0; i < attempts; i++) {
-            if (fut.last() != null) {
-
-                success = true;
-
-                break;
-            }
-
-            Thread.sleep(100);
-        }
-
-        return success;
-    }
-
-    /**
-     * Test runnable job.
-     */
-    private static class TestRunnable implements IgniteRunnable {
-        /** */
-        @IgniteInstanceResource
-        private Ignite ignite;
-
-        /** */
-        @IgniteLoggerResource
-        private IgniteLogger log;
-
-        /** @{inheritDoc} */
-        @Override public void run() {
-            log.info("Runnable job executed on node: " + ignite.cluster().localNode().id());
-
-            assert ignite != null;
-
-            execCntr.incrementAndGet();
-        }
-    }
-    /**
-     * Test callable job.
-     */
-    private static class TestCallable implements IgniteCallable<Integer> {
-        /** */
-        @IgniteInstanceResource
-        private Ignite ignite;
-
-        /** */
-        @IgniteLoggerResource
-        private IgniteLogger log;
-
-        /** {@inheritDoc} */
-        @Override public Integer call() {
-            log.info("Callable job executed on node: " + ignite.cluster().localNode().id());
-
-            assert ignite != null;
-
-            return execCntr.incrementAndGet();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d0e6cace/modules/slf4j/src/main/java/org/apache/ignite/logger/slf4j/GridSlf4jLogger.java
----------------------------------------------------------------------
diff --git a/modules/slf4j/src/main/java/org/apache/ignite/logger/slf4j/GridSlf4jLogger.java b/modules/slf4j/src/main/java/org/apache/ignite/logger/slf4j/GridSlf4jLogger.java
new file mode 100644
index 0000000..76d37d9
--- /dev/null
+++ b/modules/slf4j/src/main/java/org/apache/ignite/logger/slf4j/GridSlf4jLogger.java
@@ -0,0 +1,141 @@
+/*
+ * 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.logger.slf4j;
+
+import org.apache.ignite.*;
+import org.jetbrains.annotations.*;
+import org.slf4j.*;
+
+/**
+ * SLF4J-based implementation for logging. This logger should be used
+ * by loaders that have prefer slf4j-based logging.
+ * <p>
+ * Here is an example of configuring SLF4J logger in GridGain configuration Spring file:
+ * <pre name="code" class="xml">
+ *      &lt;property name="gridLogger"&gt;
+ *          &lt;bean class="org.apache.ignite.logger.slf4j.GridSlf4jLogger"/&gt;
+ *      &lt;/property&gt;
+ * </pre>
+ * <p>
+ * It's recommended to use GridGain's logger injection instead of using/instantiating
+ * logger in your task/job code. See {@link org.apache.ignite.resources.IgniteLoggerResource} annotation about logger
+ * injection.
+ */
+public class GridSlf4jLogger implements IgniteLogger {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** SLF4J implementation proxy. */
+    private final Logger impl;
+
+    /**
+     * Creates new logger.
+     */
+    public GridSlf4jLogger() {
+        impl = LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
+    }
+
+    /**
+     * Creates new logger with given implementation.
+     *
+     * @param impl SLF4J implementation to use.
+     */
+    public GridSlf4jLogger(Logger impl) {
+        assert impl != null;
+
+        this.impl = impl;
+    }
+
+    /** {@inheritDoc} */
+    @Override public GridSlf4jLogger getLogger(Object ctgr) {
+        Logger impl = ctgr == null ? LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME) :
+            ctgr instanceof Class ? LoggerFactory.getLogger(((Class<?>)ctgr).getName()) :
+                LoggerFactory.getLogger(ctgr.toString());
+
+        return new GridSlf4jLogger(impl);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void trace(String msg) {
+        if (!impl.isTraceEnabled())
+            warning("Logging at TRACE level without checking if TRACE level is enabled: " + msg);
+
+        impl.trace(msg);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void debug(String msg) {
+        if (!impl.isDebugEnabled())
+            warning("Logging at DEBUG level without checking if DEBUG level is enabled: " + msg);
+
+        impl.debug(msg);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void info(String msg) {
+        if (!impl.isInfoEnabled())
+            warning("Logging at INFO level without checking if INFO level is enabled: " + msg);
+
+        impl.info(msg);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void warning(String msg) {
+        impl.warn(msg);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void warning(String msg, @Nullable Throwable e) {
+        impl.warn(msg, e);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void error(String msg) {
+        impl.error(msg);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void error(String msg, @Nullable Throwable e) {
+        impl.error(msg, e);
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isTraceEnabled() {
+        return impl.isTraceEnabled();
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isInfoEnabled() {
+        return impl.isInfoEnabled();
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isDebugEnabled() {
+        return impl.isDebugEnabled();
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isQuiet() {
+        return !isInfoEnabled() && !isDebugEnabled();
+    }
+
+    /** {@inheritDoc} */
+    @Nullable @Override public String fileName() {
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d0e6cace/modules/slf4j/src/main/java/org/apache/ignite/logger/slf4j/package.html
----------------------------------------------------------------------
diff --git a/modules/slf4j/src/main/java/org/apache/ignite/logger/slf4j/package.html b/modules/slf4j/src/main/java/org/apache/ignite/logger/slf4j/package.html
new file mode 100644
index 0000000..b5a9b27
--- /dev/null
+++ b/modules/slf4j/src/main/java/org/apache/ignite/logger/slf4j/package.html
@@ -0,0 +1,23 @@
+<!--
+  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.
+  -->
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<body>
+    <!-- Package description. -->
+    Contains SLF4J implementation for logging.
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d0e6cace/modules/slf4j/src/main/java/org/gridgain/grid/logger/slf4j/GridSlf4jLogger.java
----------------------------------------------------------------------
diff --git a/modules/slf4j/src/main/java/org/gridgain/grid/logger/slf4j/GridSlf4jLogger.java b/modules/slf4j/src/main/java/org/gridgain/grid/logger/slf4j/GridSlf4jLogger.java
deleted file mode 100644
index 421da4c..0000000
--- a/modules/slf4j/src/main/java/org/gridgain/grid/logger/slf4j/GridSlf4jLogger.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * 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.gridgain.grid.logger.slf4j;
-
-import org.apache.ignite.*;
-import org.jetbrains.annotations.*;
-import org.slf4j.*;
-
-/**
- * SLF4J-based implementation for logging. This logger should be used
- * by loaders that have prefer slf4j-based logging.
- * <p>
- * Here is an example of configuring SLF4J logger in GridGain configuration Spring file:
- * <pre name="code" class="xml">
- *      &lt;property name="gridLogger"&gt;
- *          &lt;bean class="org.gridgain.grid.logger.slf4j.GridSlf4jLogger"/&gt;
- *      &lt;/property&gt;
- * </pre>
- * <p>
- * It's recommended to use GridGain's logger injection instead of using/instantiating
- * logger in your task/job code. See {@link org.apache.ignite.resources.IgniteLoggerResource} annotation about logger
- * injection.
- */
-public class GridSlf4jLogger implements IgniteLogger {
-    /** */
-    private static final long serialVersionUID = 0L;
-
-    /** SLF4J implementation proxy. */
-    private final Logger impl;
-
-    /**
-     * Creates new logger.
-     */
-    public GridSlf4jLogger() {
-        impl = LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
-    }
-
-    /**
-     * Creates new logger with given implementation.
-     *
-     * @param impl SLF4J implementation to use.
-     */
-    public GridSlf4jLogger(Logger impl) {
-        assert impl != null;
-
-        this.impl = impl;
-    }
-
-    /** {@inheritDoc} */
-    @Override public GridSlf4jLogger getLogger(Object ctgr) {
-        Logger impl = ctgr == null ? LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME) :
-            ctgr instanceof Class ? LoggerFactory.getLogger(((Class<?>)ctgr).getName()) :
-                LoggerFactory.getLogger(ctgr.toString());
-
-        return new GridSlf4jLogger(impl);
-    }
-
-    /** {@inheritDoc} */
-    @Override public void trace(String msg) {
-        if (!impl.isTraceEnabled())
-            warning("Logging at TRACE level without checking if TRACE level is enabled: " + msg);
-
-        impl.trace(msg);
-    }
-
-    /** {@inheritDoc} */
-    @Override public void debug(String msg) {
-        if (!impl.isDebugEnabled())
-            warning("Logging at DEBUG level without checking if DEBUG level is enabled: " + msg);
-
-        impl.debug(msg);
-    }
-
-    /** {@inheritDoc} */
-    @Override public void info(String msg) {
-        if (!impl.isInfoEnabled())
-            warning("Logging at INFO level without checking if INFO level is enabled: " + msg);
-
-        impl.info(msg);
-    }
-
-    /** {@inheritDoc} */
-    @Override public void warning(String msg) {
-        impl.warn(msg);
-    }
-
-    /** {@inheritDoc} */
-    @Override public void warning(String msg, @Nullable Throwable e) {
-        impl.warn(msg, e);
-    }
-
-    /** {@inheritDoc} */
-    @Override public void error(String msg) {
-        impl.error(msg);
-    }
-
-    /** {@inheritDoc} */
-    @Override public void error(String msg, @Nullable Throwable e) {
-        impl.error(msg, e);
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean isTraceEnabled() {
-        return impl.isTraceEnabled();
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean isInfoEnabled() {
-        return impl.isInfoEnabled();
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean isDebugEnabled() {
-        return impl.isDebugEnabled();
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean isQuiet() {
-        return !isInfoEnabled() && !isDebugEnabled();
-    }
-
-    /** {@inheritDoc} */
-    @Nullable @Override public String fileName() {
-        return null;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d0e6cace/modules/slf4j/src/main/java/org/gridgain/grid/logger/slf4j/package.html
----------------------------------------------------------------------
diff --git a/modules/slf4j/src/main/java/org/gridgain/grid/logger/slf4j/package.html b/modules/slf4j/src/main/java/org/gridgain/grid/logger/slf4j/package.html
deleted file mode 100644
index b5a9b27..0000000
--- a/modules/slf4j/src/main/java/org/gridgain/grid/logger/slf4j/package.html
+++ /dev/null
@@ -1,23 +0,0 @@
-<!--
-  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.
-  -->
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<html>
-<body>
-    <!-- Package description. -->
-    Contains SLF4J implementation for logging.
-</body>
-</html>

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d0e6cace/modules/spring/src/main/java/org/apache/ignite/GridGainSpring.java
----------------------------------------------------------------------
diff --git a/modules/spring/src/main/java/org/apache/ignite/GridGainSpring.java b/modules/spring/src/main/java/org/apache/ignite/GridGainSpring.java
new file mode 100644
index 0000000..9b72771
--- /dev/null
+++ b/modules/spring/src/main/java/org/apache/ignite/GridGainSpring.java
@@ -0,0 +1,117 @@
+/*
+ * 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 org.apache.ignite.configuration.*;
+import org.apache.ignite.internal.*;
+import org.apache.ignite.internal.processors.resource.*;
+import org.jetbrains.annotations.*;
+import org.springframework.context.*;
+
+import java.net.*;
+
+/**
+ * Factory methods to start GridGain with optional Spring application context, this context can be injected into
+ * grid tasks and grid jobs using {@link org.apache.ignite.resources.IgniteSpringApplicationContextResource @IgniteSpringApplicationContextResource}
+ * annotation.
+ * <p>
+ * You can also instantiate grid directly from Spring without using {@code GridGain}.
+ * For more information refer to {@link GridSpringBean} documentation.
+ */
+public class GridGainSpring {
+    /**
+     * Starts grid with default configuration. By default this method will
+     * use grid configuration defined in {@code GRIDGAIN_HOME/config/default-config.xml}
+     * configuration file. If such file is not found, then all system defaults will be used.
+     *
+     * @param springCtx Optional Spring application context, possibly {@code null}.
+     *      Spring bean definitions for bean injection are taken from this context.
+     *      If provided, this context can be injected into grid tasks and grid jobs using
+     *      {@link org.apache.ignite.resources.IgniteSpringApplicationContextResource @IgniteSpringApplicationContextResource} annotation.
+     * @return Started grid.
+     * @throws IgniteCheckedException If default grid could not be started. This exception will be thrown
+     *      also if default grid has already been started.
+     */
+    public static Ignite start(@Nullable ApplicationContext springCtx) throws IgniteCheckedException {
+        return GridGainEx.start(new GridSpringResourceContextImpl(springCtx));
+    }
+
+    /**
+     * Starts grid with given configuration.
+     *
+     * @param cfg Grid configuration. This cannot be {@code null}.
+     * @param springCtx Optional Spring application context, possibly {@code null}.
+     *      Spring bean definitions for bean injection are taken from this context.
+     *      If provided, this context can be injected into grid tasks and grid jobs using
+     *      {@link org.apache.ignite.resources.IgniteSpringApplicationContextResource @IgniteSpringApplicationContextResource} annotation.
+     * @return Started grid.
+     * @throws IgniteCheckedException If grid could not be started. This exception will be thrown
+     *      also if named grid has already been started.
+     */
+    public static Ignite start(IgniteConfiguration cfg, @Nullable ApplicationContext springCtx) throws IgniteCheckedException {
+        return GridGainEx.start(cfg, new GridSpringResourceContextImpl(springCtx));
+    }
+
+    /**
+     * Starts all grids specified within given Spring XML configuration file. If grid with given name
+     * is already started, then exception is thrown. In this case all instances that may
+     * have been started so far will be stopped too.
+     * <p>
+     * Usually Spring XML configuration file will contain only one Grid definition. Note that
+     * Grid configuration bean(s) is retrieved form configuration file by type, so the name of
+     * the Grid configuration bean is ignored.
+     *
+     * @param springCfgPath Spring XML configuration file path or URL. This cannot be {@code null}.
+     * @param springCtx Optional Spring application context, possibly {@code null}.
+     *      Spring bean definitions for bean injection are taken from this context.
+     *      If provided, this context can be injected into grid tasks and grid jobs using
+     *      {@link org.apache.ignite.resources.IgniteSpringApplicationContextResource @IgniteSpringApplicationContextResource} annotation.
+     * @return Started grid. If Spring configuration contains multiple grid instances,
+     *      then the 1st found instance is returned.
+     * @throws IgniteCheckedException If grid could not be started or configuration
+     *      read. This exception will be thrown also if grid with given name has already
+     *      been started or Spring XML configuration file is invalid.
+     */
+    public static Ignite start(String springCfgPath, @Nullable ApplicationContext springCtx) throws IgniteCheckedException {
+        return GridGainEx.start(springCfgPath, null, new GridSpringResourceContextImpl(springCtx));
+    }
+
+    /**
+     * Starts all grids specified within given Spring XML configuration file URL. If grid with given name
+     * is already started, then exception is thrown. In this case all instances that may
+     * have been started so far will be stopped too.
+     * <p>
+     * Usually Spring XML configuration file will contain only one Grid definition. Note that
+     * Grid configuration bean(s) is retrieved form configuration file by type, so the name of
+     * the Grid configuration bean is ignored.
+     *
+     * @param springCfgUrl Spring XML configuration file URL. This cannot be {@code null}.
+     * @param springCtx Optional Spring application context, possibly {@code null}.
+     *      Spring bean definitions for bean injection are taken from this context.
+     *      If provided, this context can be injected into grid tasks and grid jobs using
+     *      {@link org.apache.ignite.resources.IgniteSpringApplicationContextResource @GridSpringApplicationContextResource} annotation.
+     * @return Started grid. If Spring configuration contains multiple grid instances,
+     *      then the 1st found instance is returned.
+     * @throws IgniteCheckedException If grid could not be started or configuration
+     *      read. This exception will be thrown also if grid with given name has already
+     *      been started or Spring XML configuration file is invalid.
+     */
+    public static Ignite start(URL springCfgUrl, @Nullable ApplicationContext springCtx) throws IgniteCheckedException {
+        return GridGainEx.start(springCfgUrl, null, new GridSpringResourceContextImpl(springCtx));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d0e6cace/modules/spring/src/main/java/org/apache/ignite/GridSpringBean.java
----------------------------------------------------------------------
diff --git a/modules/spring/src/main/java/org/apache/ignite/GridSpringBean.java b/modules/spring/src/main/java/org/apache/ignite/GridSpringBean.java
new file mode 100644
index 0000000..65a7ab7
--- /dev/null
+++ b/modules/spring/src/main/java/org/apache/ignite/GridSpringBean.java
@@ -0,0 +1,342 @@
+/*
+ * 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 org.apache.ignite.cache.*;
+import org.apache.ignite.cluster.*;
+import org.apache.ignite.configuration.*;
+import org.apache.ignite.plugin.*;
+import org.apache.ignite.product.*;
+import org.apache.ignite.hadoop.*;
+import org.apache.ignite.plugin.security.*;
+import org.apache.ignite.internal.util.typedef.*;
+import org.apache.ignite.internal.util.typedef.internal.*;
+import org.jetbrains.annotations.*;
+import org.springframework.beans.*;
+import org.springframework.beans.factory.*;
+import org.springframework.context.*;
+
+import java.io.*;
+import java.util.*;
+import java.util.concurrent.*;
+
+/**
+ * Grid Spring bean allows to bypass {@link Ignition} methods.
+ * In other words, this bean class allows to inject new grid instance from
+ * Spring configuration file directly without invoking static
+ * {@link Ignition} methods. This class can be wired directly from
+ * Spring and can be referenced from within other Spring beans.
+ * By virtue of implementing {@link DisposableBean} and {@link InitializingBean}
+ * interfaces, {@code GridSpringBean} automatically starts and stops underlying
+ * grid instance.
+ * <p>
+ * <h1 class="header">Spring Configuration Example</h1>
+ * Here is a typical example of describing it in Spring file:
+ * <pre name="code" class="xml">
+ * &lt;bean id="mySpringBean" class="org.apache.ignite.GridSpringBean"&gt;
+ *     &lt;property name="configuration"&gt;
+ *         &lt;bean id="grid.cfg" class="org.gridgain.grid.GridConfiguration"&gt;
+ *             &lt;property name="gridName" value="mySpringGrid"/&gt;
+ *         &lt;/bean&gt;
+ *     &lt;/property&gt;
+ * &lt;/bean&gt;
+ * </pre>
+ * Or use default configuration:
+ * <pre name="code" class="xml">
+ * &lt;bean id="mySpringBean" class="org.apache.ignite.GridSpringBean"/&gt;
+ * </pre>
+ * <h1 class="header">Java Example</h1>
+ * Here is how you may access this bean from code:
+ * <pre name="code" class="java">
+ * AbstractApplicationContext ctx = new FileSystemXmlApplicationContext("/path/to/spring/file");
+ *
+ * // Register Spring hook to destroy bean automatically.
+ * ctx.registerShutdownHook();
+ *
+ * Grid grid = (Grid)ctx.getBean("mySpringBean");
+ * </pre>
+ * <p>
+ */
+public class GridSpringBean implements Ignite, DisposableBean, InitializingBean,
+    ApplicationContextAware, Externalizable {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** */
+    private Ignite g;
+
+    /** */
+    private IgniteConfiguration cfg;
+
+    /** */
+    private ApplicationContext appCtx;
+
+    /** {@inheritDoc} */
+    @Override public IgniteConfiguration configuration() {
+        return cfg;
+    }
+
+    /**
+     * Sets grid configuration.
+     *
+     * @param cfg Grid configuration.
+     */
+    public void setConfiguration(IgniteConfiguration cfg) {
+        this.cfg = cfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void setApplicationContext(ApplicationContext ctx) throws BeansException {
+        appCtx = ctx;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void destroy() throws Exception {
+        // If there were some errors when afterPropertiesSet() was called.
+        if (g != null) {
+            // Do not cancel started tasks, wait for them.
+            G.stop(g.name(), false);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public void afterPropertiesSet() throws Exception {
+        if (cfg == null)
+            cfg = new IgniteConfiguration();
+
+        g = GridGainSpring.start(cfg, appCtx);
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteLogger log() {
+        assert cfg != null;
+
+        return cfg.getGridLogger();
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteProduct product() {
+        assert g != null;
+
+        return g.product();
+    }
+
+    /** {@inheritDoc} */
+    @Override public Collection<GridCache<?, ?>> caches() {
+        assert g != null;
+
+        return g.caches();
+    }
+
+    /** {@inheritDoc} */
+    @Override public Collection<IgniteStreamer> streamers() {
+        assert g != null;
+
+        return g.streamers();
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteCompute compute() {
+        assert g != null;
+
+        return g.compute();
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteManaged managed() {
+        assert g != null;
+
+        return g.managed();
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteMessaging message() {
+        assert g != null;
+
+        return g.message();
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteEvents events() {
+        assert g != null;
+
+        return g.events();
+    }
+
+    /** {@inheritDoc} */
+    @Override public ExecutorService executorService() {
+        assert g != null;
+
+        return g.executorService();
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteCluster cluster() {
+        assert g != null;
+
+        return g.cluster();
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteCompute compute(ClusterGroup prj) {
+        assert g != null;
+
+        return g.compute(prj);
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteMessaging message(ClusterGroup prj) {
+        assert g != null;
+
+        return g.message(prj);
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteEvents events(ClusterGroup prj) {
+        assert g != null;
+
+        return g.events(prj);
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteManaged managed(ClusterGroup prj) {
+        assert g != null;
+
+        return g.managed(prj);
+    }
+
+    /** {@inheritDoc} */
+    @Override public ExecutorService executorService(ClusterGroup prj) {
+        assert g != null;
+
+        return g.executorService(prj);
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteScheduler scheduler() {
+        assert g != null;
+
+        return g.scheduler();
+    }
+
+    /** {@inheritDoc} */
+    @Override public GridSecurity security() {
+        assert g != null;
+
+        return g.security();
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgnitePortables portables() {
+        assert g != null;
+
+        return g.portables();
+    }
+
+    /** {@inheritDoc} */
+    @Override public String name() {
+        assert g != null;
+
+        return g.name();
+    }
+
+    /** {@inheritDoc} */
+    @Override public <K, V> GridCache<K, V> cache(String name) {
+        assert g != null;
+
+        return g.cache(name);
+    }
+
+    /** {@inheritDoc} */
+    @Override public <K, V> IgniteCache<K, V> jcache(@Nullable String name) {
+        assert g != null;
+
+        return g.jcache(name);
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteTransactions transactions() {
+        assert g != null;
+
+        return g.transactions();
+    }
+
+    /** {@inheritDoc} */
+    @Override public <K, V> IgniteDataLoader<K, V> dataLoader(@Nullable String cacheName) {
+        assert g != null;
+
+        return g.dataLoader(cacheName);
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteFs fileSystem(String name) {
+        assert g != null;
+
+        return g.fileSystem(name);
+    }
+
+    /** {@inheritDoc} */
+    @Override public Collection<IgniteFs> fileSystems() {
+        assert g != null;
+
+        return g.fileSystems();
+    }
+
+    /** {@inheritDoc} */
+    @Override public GridHadoop hadoop() {
+        assert g != null;
+
+        return g.hadoop();
+    }
+
+    /** {@inheritDoc} */
+    @Nullable @Override public IgniteStreamer streamer(@Nullable String name) {
+        assert g != null;
+
+        return g.streamer(name);
+    }
+
+    /** {@inheritDoc} */
+    @Override public <T extends IgnitePlugin> T plugin(String name) throws PluginNotFoundException {
+        assert g != null;
+
+        return g.plugin(name);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void close() throws IgniteCheckedException {
+        g.close();
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(GridSpringBean.class, this);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void writeExternal(ObjectOutput out) throws IOException {
+        out.writeObject(g);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+        g = (Ignite)in.readObject();
+
+        cfg = g.configuration();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d0e6cace/modules/spring/src/main/java/org/apache/ignite/cache/spring/GridSpringCache.java
----------------------------------------------------------------------
diff --git a/modules/spring/src/main/java/org/apache/ignite/cache/spring/GridSpringCache.java b/modules/spring/src/main/java/org/apache/ignite/cache/spring/GridSpringCache.java
new file mode 100644
index 0000000..749eefb
--- /dev/null
+++ b/modules/spring/src/main/java/org/apache/ignite/cache/spring/GridSpringCache.java
@@ -0,0 +1,185 @@
+/*
+ * 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.cache.spring;
+
+import org.apache.ignite.*;
+import org.apache.ignite.cache.*;
+import org.apache.ignite.lang.*;
+import org.apache.ignite.internal.util.typedef.*;
+import org.springframework.cache.*;
+import org.springframework.cache.support.*;
+
+import java.io.*;
+
+/**
+ * Spring cache implementation.
+ */
+class GridSpringCache implements Cache, Serializable {
+    /** */
+    private String name;
+
+    /** */
+    private Ignite ignite;
+
+    /** */
+    private GridCacheProjection<Object, Object> cache;
+
+    /** */
+    private IgniteClosure<Object, Object> keyFactory;
+
+    /**
+     * @param name Cache name.
+     * @param ignite Ignite instance.
+     * @param cache Cache.
+     * @param keyFactory Key factory.
+     */
+    GridSpringCache(String name, Ignite ignite, GridCacheProjection<?, ?> cache,
+        IgniteClosure<Object, Object> keyFactory) {
+        assert cache != null;
+
+        this.name = name;
+        this.ignite = ignite;
+        this.cache = (GridCacheProjection<Object, Object>)cache;
+        this.keyFactory = keyFactory != null ? keyFactory : F.identity();
+    }
+
+    /** {@inheritDoc} */
+    @Override public String getName() {
+        return name;
+    }
+
+    /** {@inheritDoc} */
+    @Override public Object getNativeCache() {
+        return cache;
+    }
+
+    /** {@inheritDoc} */
+    @Override public ValueWrapper get(Object key) {
+        try {
+            Object val = cache.get(keyFactory.apply(key));
+
+            return val != null ? new SimpleValueWrapper(val) : null;
+        }
+        catch (IgniteCheckedException e) {
+            throw new IgniteException("Failed to get value from cache [cacheName=" + cache.name() +
+                ", key=" + key + ']', e);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public <T> T get(Object key, Class<T> type) {
+        try {
+            Object val = cache.get(keyFactory.apply(key));
+
+            if (val != null && type != null && !type.isInstance(val))
+                throw new IllegalStateException("Cached value is not of required type [cacheName=" + cache.name() +
+                    ", key=" + key + ", val=" + val + ", requiredType=" + type + ']');
+
+            return (T)val;
+        }
+        catch (IgniteCheckedException e) {
+            throw new IgniteException("Failed to get value from cache [cacheName=" + cache.name() +
+                ", key=" + key + ']', e);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public void put(Object key, Object val) {
+        try {
+            cache.putx(keyFactory.apply(key), val);
+        }
+        catch (IgniteCheckedException e) {
+            throw new IgniteException("Failed to put value to cache [cacheName=" + cache.name() +
+                ", key=" + key + ", val=" + val + ']', e);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public ValueWrapper putIfAbsent(Object key, Object val) {
+        try {
+            Object old = cache.putIfAbsent(keyFactory.apply(key), val);
+
+            return old != null ? new SimpleValueWrapper(old) : null;
+        }
+        catch (IgniteCheckedException e) {
+            throw new IgniteException("Failed to put value to cache [cacheName=" + cache.name() +
+                ", key=" + key + ", val=" + val + ']', e);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public void evict(Object key) {
+        try {
+            cache.removex(keyFactory.apply(key));
+        }
+        catch (IgniteCheckedException e) {
+            throw new IgniteException("Failed to remove value from cache [cacheName=" + cache.name() +
+                ", key=" + key + ']', e);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public void clear() {
+        try {
+            ignite.compute(cache.gridProjection()).broadcast(new ClearClosure(cache));
+        }
+        catch (IgniteCheckedException e) {
+            throw new IgniteException("Failed to clear cache [cacheName=" + cache.name() + ']', e);
+        }
+    }
+
+    /**
+     * Closure that removes all entries from cache.
+     */
+    private static class ClearClosure extends CAX implements Externalizable {
+        /** */
+        private static final long serialVersionUID = 0L;
+
+        /** Cache projection. */
+        private GridCacheProjection<Object, Object> cache;
+
+        /**
+         * For {@link Externalizable}.
+         */
+        public ClearClosure() {
+            // No-op.
+        }
+
+        /**
+         * @param cache Cache projection.
+         */
+        private ClearClosure(GridCacheProjection<Object, Object> cache) {
+            this.cache = cache;
+        }
+
+        /** {@inheritDoc} */
+        @Override public void applyx() throws IgniteCheckedException {
+            cache.removeAll();
+        }
+
+        /** {@inheritDoc} */
+        @Override public void writeExternal(ObjectOutput out) throws IOException {
+            out.writeObject(cache);
+        }
+
+        /** {@inheritDoc} */
+        @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+            cache = (GridCacheProjection<Object, Object>)in.readObject();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d0e6cace/modules/spring/src/main/java/org/apache/ignite/cache/spring/GridSpringCacheManager.java
----------------------------------------------------------------------
diff --git a/modules/spring/src/main/java/org/apache/ignite/cache/spring/GridSpringCacheManager.java b/modules/spring/src/main/java/org/apache/ignite/cache/spring/GridSpringCacheManager.java
new file mode 100644
index 0000000..e1c2660
--- /dev/null
+++ b/modules/spring/src/main/java/org/apache/ignite/cache/spring/GridSpringCacheManager.java
@@ -0,0 +1,241 @@
+/*
+ * 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.cache.spring;
+
+import org.apache.ignite.*;
+import org.apache.ignite.cache.*;
+import org.apache.ignite.configuration.*;
+import org.apache.ignite.lang.*;
+import org.apache.ignite.internal.util.typedef.*;
+import org.springframework.beans.factory.*;
+import org.springframework.cache.*;
+
+import java.util.*;
+
+/**
+ * Implementation of Spring cache abstraction based on GridGain cache.
+ * <h1 class="header">Overview</h1>
+ * Spring cache abstraction allows to enable caching for Java methods
+ * so that the result of a method execution is stored in some storage. If
+ * later the same method is called with the same set of parameters,
+ * the result will be retrieved from that storage instead of actually
+ * executing the method. For more information, refer to
+ * <a href="http://docs.spring.io/spring/docs/current/spring-framework-reference/html/cache.html">
+ * Spring Cache Abstraction documentation</a>.
+ * <h1 class="header">How To Enable Caching</h1>
+ * To enable caching based on GridGain cache in your Spring application,
+ * you will need to do the following:
+ * <ul>
+ *     <li>
+ *         Start a GridGain node with configured cache in the same JVM
+ *         where you application is running.
+ *     </li>
+ *     <li>
+ *         Configure {@code GridSpringCacheManager} as a cache provider
+ *         in Spring application context.
+ *     </li>
+ * </ul>
+ * {@code GridSpringCacheManager} can start a node itself on its startup
+ * based on provided GridGain configuration. You can provide path to a
+ * Spring configuration XML file, like below (path can be absolute or
+ * relative to {@code GRIDGAIN_HOME}):
+ * <pre name="code" class="xml">
+ * &lt;beans xmlns="http://www.springframework.org/schema/beans"
+ *        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ *        xmlns:cache="http://www.springframework.org/schema/cache"
+ *        xsi:schemaLocation="
+ *         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ *         http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd"&gt;
+ *     &lt;-- Provide configuration file path. --&gt;
+ *     &lt;bean id="cacheManager" class="org.apache.ignite.cache.spring.GridSpringCacheManager"&gt;
+ *         &lt;property name="configurationPath" value="examples/config/spring-cache.xml"/&gt;
+ *     &lt;/bean>
+ *
+ *     &lt;-- Use annotation-driven caching configuration. --&gt;
+ *     &lt;cache:annotation-driven/&gt;
+ * &lt;/beans&gt;
+ * </pre>
+ * Or you can provide a {@link IgniteConfiguration} bean, like below:
+ * <pre name="code" class="xml">
+ * &lt;beans xmlns="http://www.springframework.org/schema/beans"
+ *        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ *        xmlns:cache="http://www.springframework.org/schema/cache"
+ *        xsi:schemaLocation="
+ *         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ *         http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd"&gt;
+ *     &lt;-- Provide configuration bean. --&gt;
+ *     &lt;bean id="cacheManager" class="org.apache.ignite.cache.spring.GridSpringCacheManager"&gt;
+ *         &lt;property name="configuration"&gt;
+ *             &lt;bean id="gridCfg" class="org.gridgain.grid.GridConfiguration"&gt;
+ *                 ...
+ *             &lt;/bean&gt;
+ *         &lt;/property&gt;
+ *     &lt;/bean&gt;
+ *
+ *     &lt;-- Use annotation-driven caching configuration. --&gt;
+ *     &lt;cache:annotation-driven/&gt;
+ * &lt;/beans&gt;
+ * </pre>
+ * Note that providing both configuration path and configuration bean is illegal
+ * and results in {@link IllegalArgumentException}.
+ * <p>
+ * If you already have GridGain node running within your application,
+ * simply provide correct Grid name, like below (if there is no Grid
+ * instance with such name, exception will be thrown):
+ * <pre name="code" class="xml">
+ * &lt;beans xmlns="http://www.springframework.org/schema/beans"
+ *        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ *        xmlns:cache="http://www.springframework.org/schema/cache"
+ *        xsi:schemaLocation="
+ *         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ *         http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd"&gt;
+ *     &lt;-- Provide Grid name. --&gt;
+ *     &lt;bean id="cacheManager" class="org.apache.ignite.cache.spring.GridSpringCacheManager"&gt;
+ *         &lt;property name="gridName" value="myGrid"/&gt;
+ *     &lt;/bean>
+ *
+ *     &lt;-- Use annotation-driven caching configuration. --&gt;
+ *     &lt;cache:annotation-driven/&gt;
+ * &lt;/beans&gt;
+ * </pre>
+ * This can be used, for example, when you are running your application
+ * in a J2EE Web container and use {@gglink org.gridgain.grid.startup.servlet.GridServletContextListenerStartup}
+ * for node startup.
+ * <p>
+ * If neither {@link #setConfigurationPath(String) configurationPath},
+ * {@link #setConfiguration(IgniteConfiguration) configuration}, nor
+ * {@link #setGridName(String) gridName} are provided, cache manager
+ * will try to use default Grid instance (the one with the {@code null}
+ * name). If it doesn't exist, exception will be thrown.
+ * <h1>Starting Remote Nodes</h1>
+ * Remember that the node started inside your application is an entry point
+ * to the whole topology it connects to. You can start as many remote standalone
+ * nodes as you need using {@code bin/ggstart.{sh|bat}} scripts provided in
+ * GridGain distribution, and all these nodes will participate
+ * in caching data.
+ */
+public class GridSpringCacheManager implements CacheManager, InitializingBean {
+    /** Grid configuration file path. */
+    private String cfgPath;
+
+    /** Ignite configuration. */
+    private IgniteConfiguration cfg;
+
+    /** Grid name. */
+    private String gridName;
+
+    /** Ignite instance. */
+    protected Ignite grid;
+
+    /**
+     * Gets configuration file path.
+     *
+     * @return Grid configuration file path.
+     */
+    public String getConfigurationPath() {
+        return cfgPath;
+    }
+
+    /**
+     * Sets configuration file path.
+     *
+     * @param cfgPath Grid configuration file path.
+     */
+    public void setConfigurationPath(String cfgPath) {
+        this.cfgPath = cfgPath;
+    }
+
+    /**
+     * Gets configuration bean.
+     *
+     * @return Grid configuration bean.
+     */
+    public IgniteConfiguration getConfiguration() {
+        return cfg;
+    }
+
+    /**
+     * Sets configuration bean.
+     *
+     * @param cfg Grid configuration bean.
+     */
+    public void setConfiguration(IgniteConfiguration cfg) {
+        this.cfg = cfg;
+    }
+
+    /**
+     * Gets grid name.
+     *
+     * @return Grid name.
+     */
+    public String getGridName() {
+        return gridName;
+    }
+
+    /**
+     * Sets grid name.
+     *
+     * @param gridName Grid name.
+     */
+    public void setGridName(String gridName) {
+        this.gridName = gridName;
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("IfMayBeConditional")
+    @Override public void afterPropertiesSet() throws Exception {
+        assert grid == null;
+
+        if (cfgPath != null && cfg != null) {
+            throw new IllegalArgumentException("Both 'configurationPath' and 'configuration' are " +
+                "provided. Set only one of these properties if you need to start a GridGain node inside of " +
+                "GridSpringCacheManager. If you already have a node running, omit both of them and set" +
+                "'gridName' property.");
+        }
+
+        if (cfgPath != null)
+            grid = Ignition.start(cfgPath);
+        else if (cfg != null)
+            grid = Ignition.start(cfg);
+        else
+            grid = Ignition.ignite(gridName);
+    }
+
+    /** {@inheritDoc} */
+    @Override public Cache getCache(String name) {
+        assert grid != null;
+
+        try {
+            return new GridSpringCache(name, grid, grid.cache(name), null);
+        }
+        catch (IllegalArgumentException ignored) {
+            return null;
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public Collection<String> getCacheNames() {
+        assert grid != null;
+
+        return F.viewReadOnly(grid.caches(), new IgniteClosure<GridCache<?,?>, String>() {
+            @Override public String apply(GridCache<?, ?> c) {
+                return c.name();
+            }
+        });
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/d0e6cace/modules/spring/src/main/java/org/apache/ignite/cache/spring/GridSpringDynamicCacheManager.java
----------------------------------------------------------------------
diff --git a/modules/spring/src/main/java/org/apache/ignite/cache/spring/GridSpringDynamicCacheManager.java b/modules/spring/src/main/java/org/apache/ignite/cache/spring/GridSpringDynamicCacheManager.java
new file mode 100644
index 0000000..fc12034
--- /dev/null
+++ b/modules/spring/src/main/java/org/apache/ignite/cache/spring/GridSpringDynamicCacheManager.java
@@ -0,0 +1,316 @@
+/*
+ * 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.cache.spring;
+
+import org.apache.ignite.*;
+import org.apache.ignite.cache.*;
+import org.apache.ignite.internal.*;
+import org.apache.ignite.internal.processors.cache.*;
+import org.apache.ignite.lang.*;
+import org.apache.ignite.internal.util.tostring.*;
+import org.apache.ignite.internal.util.typedef.*;
+import org.apache.ignite.internal.util.typedef.internal.*;
+import org.springframework.cache.*;
+import org.springframework.cache.annotation.*;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * Extension of {@link GridSpringCacheManager} that adds an option to
+ * emulate dynamic cache creation for you Spring-based applications.
+ * <p>
+ * All the data will be actually cached in one GridGain cache. It's
+ * name should be provided to this cache manager via
+ * {@link #setDataCacheName(String)} configuration property.
+ * <p>
+ * Under the hood, this cache manager will create a cache projection
+ * for each cache name provided in {@link Cacheable}, {@link CachePut},
+ * etc. annotations. Note that you're still able to use caches configured in
+ * GridGain configuration. Cache projection will be created only
+ * cache with provided name doesn't exist.
+ * <h1 class="header">Configuration</h1>
+ * {@link GridSpringDynamicCacheManager} inherits all configuration
+ * properties from {@link GridSpringCacheManager} (see it's JavaDoc
+ * for more information on how to enable GridGain-based caching in
+ * a Spring application).
+ * <p>
+ * Additionally you will need to set a GridGain cache name where the data for
+ * all dynamically created caches will be stored. By default its name
+ * is {@code null}, which refers to default cache. Here is the example
+ * of how to configure a named cache:
+ * <pre name="code" class="xml">
+ * &lt;beans xmlns="http://www.springframework.org/schema/beans"
+ *        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ *        xmlns:cache="http://www.springframework.org/schema/cache"
+ *        xsi:schemaLocation="
+ *         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ *         http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd"&gt;
+ *     &lt;-- Provide configuration file path --&gt;
+ *     &lt;bean id="cacheManager" class="org.apache.ignite.cache.spring.GridSpringCacheManager"&gt;
+ *         &lt;property name="dataCacheName" value="myDataCache"/&gt;
+ *     &lt;/bean>
+ *
+ *     ...
+ * &lt;/beans&gt;
+ * </pre>
+ *
+ * @see GridSpringCacheManager
+ */
+public class GridSpringDynamicCacheManager extends GridSpringCacheManager {
+    /** Data cache name. */
+    private String dataCacheName;
+
+    /** Meta cache. */
+    private GridCacheProjectionEx<MetaKey, Cache> metaCache;
+
+    /** Data cache. */
+    private GridCache<DataKey, Object> dataCache;
+
+    /**
+     * Sets data cache name.
+     *
+     * @return Data cache name.
+     */
+    public String getDataCacheName() {
+        return dataCacheName;
+    }
+
+    /**
+     * Gets data cache name.
+     *
+     * @param dataCacheName Data cache name.
+     */
+    public void setDataCacheName(String dataCacheName) {
+        this.dataCacheName = dataCacheName;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void afterPropertiesSet() throws Exception {
+        super.afterPropertiesSet();
+
+        metaCache = ((GridEx)grid).utilityCache(MetaKey.class, Cache.class);
+        dataCache = grid.cache(dataCacheName);
+    }
+
+    /** {@inheritDoc} */
+    @Override public Cache getCache(final String name) {
+        Cache cache = super.getCache(name);
+
+        if (cache != null)
+            return cache;
+
+        try {
+            MetaKey key = new MetaKey(name);
+
+            cache = metaCache.get(key);
+
+            if (cache == null) {
+                cache = new GridSpringCache(name, grid, dataCache.projection(new ProjectionFilter(name)),
+                    new IgniteClosure<Object, Object>() {
+                        @Override public Object apply(Object o) {
+                            return new DataKey(name, o);
+                        }
+                    });
+
+                Cache old = metaCache.putIfAbsent(key, cache);
+
+                if (old != null)
+                    cache = old;
+            }
+
+            return cache;
+        }
+        catch (IgniteCheckedException e) {
+            throw new IgniteException(e);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public Collection<String> getCacheNames() {
+        Collection<String> names = F.view(super.getCacheNames(), new IgnitePredicate<String>() {
+            @Override public boolean apply(String name) {
+                return !F.eq(name, dataCacheName);
+            }
+        });
+
+        return F.concat(false, names, F.transform(metaCache.entrySetx(),
+            new IgniteClosure<Map.Entry<MetaKey, Cache>, String>() {
+                @Override public String apply(Map.Entry<MetaKey, Cache> e) {
+                    return e.getKey().name;
+                }
+            }));
+    }
+
+    /**
+     * Meta key.
+     */
+    private static class MetaKey extends GridCacheUtilityKey<MetaKey> implements Externalizable {
+        /** Cache name. */
+        private String name;
+
+        /**
+         * For {@link Externalizable}.
+         */
+        public MetaKey() {
+            // No-op.
+        }
+
+        /**
+         * @param name Cache name.
+         */
+        private MetaKey(String name) {
+            this.name = name;
+        }
+
+        /** {@inheritDoc} */
+        @Override protected boolean equalsx(MetaKey key) {
+            return name != null ? name.equals(key.name) : key.name == null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public int hashCode() {
+            return name.hashCode();
+        }
+
+        /** {@inheritDoc} */
+        @Override public void writeExternal(ObjectOutput out) throws IOException {
+            U.writeString(out, name);
+        }
+
+        /** {@inheritDoc} */
+        @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+            name = U.readString(in);
+        }
+
+        /** {@inheritDoc} */
+        @Override public String toString() {
+            return S.toString(MetaKey.class, this);
+        }
+    }
+
+    /**
+     * Data key.
+     */
+    private static class DataKey implements Externalizable {
+        /** Cache name. */
+        private String name;
+
+        /** Key. */
+        @GridToStringInclude
+        private Object key;
+
+        /**
+         * @param name Cache name.
+         * @param key Key.
+         */
+        private DataKey(String name, Object key) {
+            this.name = name;
+            this.key = key;
+        }
+
+        /**
+         * For {@link Externalizable}.
+         */
+        public DataKey() {
+            // No-op.
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean equals(Object o) {
+            if (this == o)
+                return true;
+
+            if (o == null || getClass() != o.getClass())
+                return false;
+
+            DataKey key0 = (DataKey)o;
+
+            return name != null ? name.equals(key0.name) : key0.name == null &&
+                key != null ? key.equals(key0.key) : key0.key == null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public int hashCode() {
+            int res = name != null ? name.hashCode() : 0;
+
+            res = 31 * res + (key != null ? key.hashCode() : 0);
+
+            return res;
+        }
+
+        /** {@inheritDoc} */
+        @Override public void writeExternal(ObjectOutput out) throws IOException {
+            U.writeString(out, name);
+            out.writeObject(key);
+        }
+
+        /** {@inheritDoc} */
+        @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+            name = U.readString(in);
+            key = in.readObject();
+        }
+
+        /** {@inheritDoc} */
+        @Override public String toString() {
+            return S.toString(DataKey.class, this);
+        }
+    }
+
+    /**
+     * Projection filter.
+     */
+    private static class ProjectionFilter implements IgniteBiPredicate<DataKey, Object>, Externalizable {
+        /** Cache name. */
+        private String name;
+
+        /**
+         * For {@link Externalizable}.
+         */
+        public ProjectionFilter() {
+            // No-op.
+        }
+
+        /**
+         * @param name Cache name.
+         */
+        private ProjectionFilter(String name) {
+            this.name = name;
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean apply(DataKey key, Object val) {
+            return name != null ? name.equals(key.name) : key.name == null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public void writeExternal(ObjectOutput out) throws IOException {
+            U.writeString(out, name);
+        }
+
+        /** {@inheritDoc} */
+        @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+            name = U.readString(in);
+        }
+
+        /** {@inheritDoc} */
+        @Override public String toString() {
+            return S.toString(ProjectionFilter.class, this);
+        }
+    }
+}


Mime
View raw message