You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by vo...@apache.org on 2017/03/02 11:31:14 UTC

[37/50] [abbrv] ignite git commit: IGNITE-4711 Propagate platform cache plugin configuration to Java

IGNITE-4711 Propagate platform cache plugin configuration to Java

This closes #1552


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

Branch: refs/heads/ignite-4565-ddl
Commit: ab1b68507cae85eb21fd2e0479a8c9f3148fabc2
Parents: 1c9b024
Author: Pavel Tupitsyn <pt...@apache.org>
Authored: Fri Feb 17 17:18:36 2017 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Fri Feb 17 17:18:36 2017 +0300

----------------------------------------------------------------------
 .../utils/PlatformConfigurationUtils.java       |  64 ++++++++++-
 ...PlatformCachePluginConfigurationClosure.java |  31 +++++
 ...mCachePluginConfigurationClosureFactory.java |  37 ++++++
 ...atformCachePluginConfigurationClosureFactory |   1 +
 .../cache/PlatformGetCachePluginsTask.java      |  85 ++++++++++++++
 .../PlatformTestCachePluginConfiguration.java   |  60 ++++++++++
 ...formTestCachePluginConfigurationClosure.java |  48 ++++++++
 ...tCachePluginConfigurationClosureFactory.java |  37 ++++++
 .../cache/PlatformTestCachePluginProvider.java  |  73 ++++++++++++
 .../Apache.Ignite.Core.Tests.csproj             |   2 +
 .../Cache/CacheJavaPluginConfiguration.cs       |  45 ++++++++
 .../Plugin/Cache/CacheJavaPluginTest.cs         | 113 +++++++++++++++++++
 .../Plugin/Cache/CachePluginConfiguration.cs    |  24 ++++
 .../Plugin/Cache/CachePluginTest.cs             |   7 +-
 .../Cache/Configuration/CacheConfiguration.cs   |  22 +++-
 .../Plugin/Cache/ICachePluginConfiguration.cs   |  18 ++-
 16 files changed, 655 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/ab1b6850/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformConfigurationUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformConfigurationUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformConfigurationUtils.java
index f295ff5..bce3735 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformConfigurationUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformConfigurationUtils.java
@@ -56,6 +56,8 @@ import org.apache.ignite.platform.dotnet.PlatformDotNetBinaryTypeConfiguration;
 import org.apache.ignite.platform.dotnet.PlatformDotNetCacheStoreFactoryNative;
 import org.apache.ignite.platform.dotnet.PlatformDotNetConfiguration;
 import org.apache.ignite.plugin.CachePluginConfiguration;
+import org.apache.ignite.plugin.platform.PlatformCachePluginConfigurationClosure;
+import org.apache.ignite.plugin.platform.PlatformCachePluginConfigurationClosureFactory;
 import org.apache.ignite.plugin.platform.PlatformPluginConfigurationClosure;
 import org.apache.ignite.plugin.platform.PlatformPluginConfigurationClosureFactory;
 import org.apache.ignite.spi.communication.CommunicationSpi;
@@ -80,6 +82,7 @@ import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedHashMap;
@@ -214,12 +217,23 @@ public class PlatformConfigurationUtils {
         int pluginCnt = in.readInt();
 
         if (pluginCnt > 0) {
-            CachePluginConfiguration[] plugins = new CachePluginConfiguration[pluginCnt];
+            ArrayList<CachePluginConfiguration> plugins = new ArrayList<>();
+
+            for (int i = 0; i < pluginCnt; i++) {
+                if (in.readBoolean()) {
+                    // Java cache plugin.
+                    readCachePluginConfiguration(ccfg, in);
+                } else {
+                    // Platform cache plugin.
+                    plugins.add(new PlatformCachePluginConfiguration(in.readObjectDetached()));
+                }
+            }
 
-            for (int i = 0; i < pluginCnt; i++)
-                plugins[i] = new PlatformCachePluginConfiguration(in.readObjectDetached());
+            if (ccfg.getPluginConfigurations() != null) {
+                Collections.addAll(plugins, ccfg.getPluginConfigurations());
+            }
 
-            ccfg.setPluginConfigurations(plugins);
+            ccfg.setPluginConfigurations(plugins.toArray(new CachePluginConfiguration[plugins.size()]));
         }
 
         return ccfg;
@@ -1325,6 +1339,48 @@ public class PlatformConfigurationUtils {
     }
 
     /**
+     * Reads the plugin configuration.
+     *
+     * @param cfg Ignite configuration to update.
+     * @param in Reader.
+     */
+    private static void readCachePluginConfiguration(CacheConfiguration cfg, BinaryRawReader in) {
+        int plugCfgFactoryId = in.readInt();
+
+        PlatformCachePluginConfigurationClosure plugCfg = cachePluginConfiguration(plugCfgFactoryId);
+
+        plugCfg.apply(cfg, in);
+    }
+
+    /**
+     * Create PlatformCachePluginConfigurationClosure for the given factory ID.
+     *
+     * @param factoryId Factory ID.
+     * @return PlatformCachePluginConfigurationClosure.
+     */
+    private static PlatformCachePluginConfigurationClosure cachePluginConfiguration(final int factoryId) {
+        PlatformCachePluginConfigurationClosureFactory factory = AccessController.doPrivileged(
+                new PrivilegedAction<PlatformCachePluginConfigurationClosureFactory>() {
+                    @Override public PlatformCachePluginConfigurationClosureFactory run() {
+                        for (PlatformCachePluginConfigurationClosureFactory factory :
+                                ServiceLoader.load(PlatformCachePluginConfigurationClosureFactory.class)) {
+                            if (factory.id() == factoryId)
+                                return factory;
+                        }
+
+                        return null;
+                    }
+                });
+
+        if (factory == null) {
+            throw new IgniteException("PlatformPluginConfigurationClosureFactory is not found " +
+                    "(did you put into the classpath?): " + factoryId);
+        }
+
+        return factory.create();
+    }
+
+    /**
      * Private constructor.
      */
     private PlatformConfigurationUtils() {

http://git-wip-us.apache.org/repos/asf/ignite/blob/ab1b6850/modules/core/src/main/java/org/apache/ignite/plugin/platform/PlatformCachePluginConfigurationClosure.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/plugin/platform/PlatformCachePluginConfigurationClosure.java b/modules/core/src/main/java/org/apache/ignite/plugin/platform/PlatformCachePluginConfigurationClosure.java
new file mode 100644
index 0000000..b03d84b
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/plugin/platform/PlatformCachePluginConfigurationClosure.java
@@ -0,0 +1,31 @@
+/*
+ * 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.plugin.platform;
+
+import org.apache.ignite.binary.BinaryRawReader;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.lang.IgniteBiInClosure;
+
+/**
+ * Platform cache configuration handler:
+ * updates plugin configuration using data sent from platform code.
+ */
+public interface PlatformCachePluginConfigurationClosure
+        extends IgniteBiInClosure<CacheConfiguration, BinaryRawReader> {
+    // No-op.
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/ab1b6850/modules/core/src/main/java/org/apache/ignite/plugin/platform/PlatformCachePluginConfigurationClosureFactory.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/plugin/platform/PlatformCachePluginConfigurationClosureFactory.java b/modules/core/src/main/java/org/apache/ignite/plugin/platform/PlatformCachePluginConfigurationClosureFactory.java
new file mode 100644
index 0000000..d6398ea
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/plugin/platform/PlatformCachePluginConfigurationClosureFactory.java
@@ -0,0 +1,37 @@
+/*
+ * 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.plugin.platform;
+
+/**
+ * Factory for @{@link PlatformCachePluginConfigurationClosure} with a unique id.
+ */
+public interface PlatformCachePluginConfigurationClosureFactory {
+    /**
+     * Gets the factory id.
+     *
+     * @return Factory id.
+     */
+    int id();
+
+    /**
+     * Creates configuration closure instance.
+     *
+     * @return Configuration closure instance.
+     */
+    PlatformCachePluginConfigurationClosure create();
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/ab1b6850/modules/core/src/test/java/META-INF/services/org.apache.ignite.plugin.platform.PlatformCachePluginConfigurationClosureFactory
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/META-INF/services/org.apache.ignite.plugin.platform.PlatformCachePluginConfigurationClosureFactory b/modules/core/src/test/java/META-INF/services/org.apache.ignite.plugin.platform.PlatformCachePluginConfigurationClosureFactory
new file mode 100644
index 0000000..a99b3b9
--- /dev/null
+++ b/modules/core/src/test/java/META-INF/services/org.apache.ignite.plugin.platform.PlatformCachePluginConfigurationClosureFactory
@@ -0,0 +1 @@
+org.apache.ignite.platform.plugin.cache.PlatformTestCachePluginConfigurationClosureFactory
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/ab1b6850/modules/core/src/test/java/org/apache/ignite/platform/plugin/cache/PlatformGetCachePluginsTask.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/platform/plugin/cache/PlatformGetCachePluginsTask.java b/modules/core/src/test/java/org/apache/ignite/platform/plugin/cache/PlatformGetCachePluginsTask.java
new file mode 100644
index 0000000..cfcf0d5
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/platform/plugin/cache/PlatformGetCachePluginsTask.java
@@ -0,0 +1,85 @@
+/*
+ * 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.platform.plugin.cache;
+
+import org.apache.ignite.Ignite;
+import org.apache.ignite.cluster.ClusterNode;
+import org.apache.ignite.compute.ComputeJob;
+import org.apache.ignite.compute.ComputeJobAdapter;
+import org.apache.ignite.compute.ComputeJobResult;
+import org.apache.ignite.compute.ComputeTaskAdapter;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.plugin.CachePluginConfiguration;
+import org.apache.ignite.resources.IgniteInstanceResource;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Task to get a list of cache plugins.
+ */
+public class PlatformGetCachePluginsTask extends ComputeTaskAdapter<String, String[]> {
+    /** {@inheritDoc} */
+    @Nullable @Override public Map<? extends ComputeJob, ClusterNode> map(List<ClusterNode> subgrid,
+        @Nullable String arg) {
+        return Collections.singletonMap(new GetCachePluginsJob(arg), F.first(subgrid));
+    }
+
+    /** {@inheritDoc} */
+    @Nullable @Override public String[] reduce(List<ComputeJobResult> results) {
+        return results.get(0).getData();
+    }
+
+    /**
+     * Job.
+     */
+    @SuppressWarnings("unchecked")
+    private static class GetCachePluginsJob extends ComputeJobAdapter {
+        /** */
+        private final String cacheName;
+
+        /** */
+        @IgniteInstanceResource
+        private final Ignite ignite;
+
+        /** */
+        GetCachePluginsJob(String cacheName) {
+            this.cacheName = cacheName;
+            ignite = null;
+        }
+
+        /** {@inheritDoc} */
+        @Nullable @Override public String[] execute() {
+            CachePluginConfiguration[] cfg =
+                    ignite.cache(cacheName).getConfiguration(CacheConfiguration.class).getPluginConfigurations();
+
+            if (cfg == null)
+                return null;
+
+            String[] res = new String[cfg.length];
+
+            for (int i = 0; i < cfg.length; i++)
+                res[i] = cfg[i].getClass().getName();
+
+            return res;
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/ab1b6850/modules/core/src/test/java/org/apache/ignite/platform/plugin/cache/PlatformTestCachePluginConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/platform/plugin/cache/PlatformTestCachePluginConfiguration.java b/modules/core/src/test/java/org/apache/ignite/platform/plugin/cache/PlatformTestCachePluginConfiguration.java
new file mode 100644
index 0000000..88a021a
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/platform/plugin/cache/PlatformTestCachePluginConfiguration.java
@@ -0,0 +1,60 @@
+/*
+ * 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.platform.plugin.cache;
+
+import org.apache.ignite.plugin.CachePluginConfiguration;
+import org.apache.ignite.plugin.CachePluginContext;
+import org.apache.ignite.plugin.CachePluginProvider;
+
+/**
+ * Test plugin configuration.
+ */
+public class PlatformTestCachePluginConfiguration implements CachePluginConfiguration {
+    /** */
+    private String pluginProperty;
+
+    /**
+     * Initializes a new instance of PlatformTestPluginConfiguration.
+     */
+    PlatformTestCachePluginConfiguration() {
+        // No-op.
+    }
+
+    /**
+     * Gets the plugin property.
+     *
+     * @return Plugin property.
+     */
+    public String pluginProperty() {
+        return pluginProperty;
+    }
+
+    /**
+     * Sets the plugin property.
+     *
+     * @param pluginProperty Value.
+     */
+    void setPluginProperty(String pluginProperty) {
+        this.pluginProperty = pluginProperty;
+    }
+
+    /** {@inheritDoc} */
+    @Override public CachePluginProvider createProvider(CachePluginContext ctx) {
+        return new PlatformTestCachePluginProvider();
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/ab1b6850/modules/core/src/test/java/org/apache/ignite/platform/plugin/cache/PlatformTestCachePluginConfigurationClosure.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/platform/plugin/cache/PlatformTestCachePluginConfigurationClosure.java b/modules/core/src/test/java/org/apache/ignite/platform/plugin/cache/PlatformTestCachePluginConfigurationClosure.java
new file mode 100644
index 0000000..2763c4f
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/platform/plugin/cache/PlatformTestCachePluginConfigurationClosure.java
@@ -0,0 +1,48 @@
+/*
+ * 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.platform.plugin.cache;
+
+import org.apache.ignite.binary.BinaryRawReader;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.plugin.CachePluginConfiguration;
+import org.apache.ignite.plugin.platform.PlatformCachePluginConfigurationClosure;
+
+import java.util.ArrayList;
+import java.util.Collections;
+
+/**
+ * Test config closure.
+ */
+public class PlatformTestCachePluginConfigurationClosure implements PlatformCachePluginConfigurationClosure {
+    /** {@inheritDoc} */
+    @Override public void apply(CacheConfiguration cacheConfiguration, BinaryRawReader reader) {
+        ArrayList<CachePluginConfiguration> cfgs = new ArrayList<>();
+
+        if (cacheConfiguration.getPluginConfigurations() != null) {
+            Collections.addAll(cfgs, cacheConfiguration.getPluginConfigurations());
+        }
+
+        PlatformTestCachePluginConfiguration plugCfg = new PlatformTestCachePluginConfiguration();
+
+        plugCfg.setPluginProperty(reader.readString());
+
+        cfgs.add(plugCfg);
+
+        cacheConfiguration.setPluginConfigurations(cfgs.toArray(new CachePluginConfiguration[cfgs.size()]));
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/ab1b6850/modules/core/src/test/java/org/apache/ignite/platform/plugin/cache/PlatformTestCachePluginConfigurationClosureFactory.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/platform/plugin/cache/PlatformTestCachePluginConfigurationClosureFactory.java b/modules/core/src/test/java/org/apache/ignite/platform/plugin/cache/PlatformTestCachePluginConfigurationClosureFactory.java
new file mode 100644
index 0000000..85fa8e4
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/platform/plugin/cache/PlatformTestCachePluginConfigurationClosureFactory.java
@@ -0,0 +1,37 @@
+/*
+ * 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.platform.plugin.cache;
+
+import org.apache.ignite.plugin.platform.PlatformCachePluginConfigurationClosure;
+import org.apache.ignite.plugin.platform.PlatformCachePluginConfigurationClosureFactory;
+
+/**
+ * Test closure factory.
+ */
+public class PlatformTestCachePluginConfigurationClosureFactory
+        implements PlatformCachePluginConfigurationClosureFactory {
+    /** {@inheritDoc} */
+    @Override public int id() {
+        return 0;
+    }
+
+    /** {@inheritDoc} */
+    @Override public PlatformCachePluginConfigurationClosure create() {
+        return new PlatformTestCachePluginConfigurationClosure();
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/ab1b6850/modules/core/src/test/java/org/apache/ignite/platform/plugin/cache/PlatformTestCachePluginProvider.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/platform/plugin/cache/PlatformTestCachePluginProvider.java b/modules/core/src/test/java/org/apache/ignite/platform/plugin/cache/PlatformTestCachePluginProvider.java
new file mode 100644
index 0000000..1dcd81f
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/platform/plugin/cache/PlatformTestCachePluginProvider.java
@@ -0,0 +1,73 @@
+/*
+ * 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.platform.plugin.cache;
+
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.cluster.ClusterNode;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.plugin.CachePluginConfiguration;
+import org.apache.ignite.plugin.CachePluginProvider;
+import org.jetbrains.annotations.Nullable;
+
+import javax.cache.Cache;
+
+/**
+ * Test cache plugin provider.
+ */
+public class PlatformTestCachePluginProvider implements CachePluginProvider {
+    /** {@inheritDoc} */
+    @Override public void start() throws IgniteCheckedException {
+        // No-op.
+    }
+
+    /** {@inheritDoc} */
+    @Override public void stop(boolean cancel) {
+        // No-op.
+    }
+
+    /** {@inheritDoc} */
+    @Override public void onIgniteStart() throws IgniteCheckedException {
+        // No-op.
+    }
+
+    /** {@inheritDoc} */
+    @Override public void onIgniteStop(boolean cancel) {
+        // No-op.
+    }
+
+    /** {@inheritDoc} */
+    @Override public void validate() throws IgniteCheckedException {
+        // No-op.
+    }
+
+    /** {@inheritDoc} */
+    @Override public void validateRemote(CacheConfiguration locCfg, CachePluginConfiguration locPluginCcfg,
+                                         CacheConfiguration rmtCfg, ClusterNode rmtNode) throws IgniteCheckedException {
+        // No-op.
+    }
+
+    /** {@inheritDoc} */
+    @Nullable @Override public Object unwrapCacheEntry(Cache.Entry entry, Class cls) {
+        return null;
+    }
+
+    /** {@inheritDoc} */
+    @Nullable @Override public Object createComponent(Class cls) {
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/ab1b6850/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
index 71b0593..0eb3e39 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
@@ -91,6 +91,8 @@
     <Compile Include="Log\DefaultLoggerTest.cs" />
     <Compile Include="Log\Log4NetLoggerTest.cs" />
     <Compile Include="Log\NLogLoggerTest.cs" />
+    <Compile Include="Plugin\Cache\CacheJavaPluginConfiguration.cs" />
+    <Compile Include="Plugin\Cache\CacheJavaPluginTest.cs" />
     <Compile Include="Plugin\PluginTest.cs" />
     <Compile Include="Plugin\TestIgnitePlugin.cs" />
     <Compile Include="Plugin\TestIgnitePluginConfiguration.cs" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/ab1b6850/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Plugin/Cache/CacheJavaPluginConfiguration.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Plugin/Cache/CacheJavaPluginConfiguration.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Plugin/Cache/CacheJavaPluginConfiguration.cs
new file mode 100644
index 0000000..2db875d
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Plugin/Cache/CacheJavaPluginConfiguration.cs
@@ -0,0 +1,45 @@
+\ufeff/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.Tests.Plugin.Cache
+{
+    using Apache.Ignite.Core.Binary;
+    using Apache.Ignite.Core.Plugin.Cache;
+
+    /// <summary>
+    /// Configuration with a plugin with Java part.
+    /// </summary>
+    public class CacheJavaPluginConfiguration : ICachePluginConfiguration
+    {
+        /// <summary>
+        /// Gets or sets the custom property.
+        /// </summary>
+        public string Foo { get; set; }
+
+        /** <inheritdoc /> */
+        public int? CachePluginConfigurationClosureFactoryId
+        {
+            get { return 0; }
+        }
+
+        /** <inheritdoc /> */
+        public void WriteBinary(IBinaryRawWriter writer)
+        {
+            writer.WriteString(Foo);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/ab1b6850/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Plugin/Cache/CacheJavaPluginTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Plugin/Cache/CacheJavaPluginTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Plugin/Cache/CacheJavaPluginTest.cs
new file mode 100644
index 0000000..56d2b90
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Plugin/Cache/CacheJavaPluginTest.cs
@@ -0,0 +1,113 @@
+\ufeff/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.Tests.Plugin.Cache
+{
+    using Apache.Ignite.Core.Cache;
+    using Apache.Ignite.Core.Cache.Configuration;
+    using NUnit.Framework;
+
+    /// <summary>
+    /// Tests the plugin with Java part.
+    /// </summary>
+    public class CacheJavaPluginTest
+    {
+        /** */
+        private const string CacheName = "staticCache";
+
+        /** */
+        private const string DynCacheName = "dynamicCache";
+
+        /** */
+        private const string GetPluginsTask = "org.apache.ignite.platform.plugin.cache.PlatformGetCachePluginsTask";
+
+        /** */
+        private const string PluginConfigurationClass = 
+            "org.apache.ignite.platform.plugin.cache.PlatformTestCachePluginConfiguration";
+
+        /** */
+        private IIgnite _grid;
+
+        /// <summary>
+        /// Fixture set up.
+        /// </summary>
+        [TestFixtureSetUp]
+        public void FixtureSetUp()
+        {
+            var cfg = new IgniteConfiguration(TestUtils.GetTestConfiguration())
+            {
+                CacheConfiguration = new[]
+                {
+                    new CacheConfiguration(CacheName)
+                    {
+                        PluginConfigurations = new[] {new CacheJavaPluginConfiguration()}
+                    }
+                }
+            };
+
+            _grid = Ignition.Start(cfg);
+        }
+
+        /// <summary>
+        /// Fixture tear down.
+        /// </summary>
+        [TestFixtureTearDown]
+        public void FixtureTearDown()
+        {
+            Ignition.StopAll(true);
+        }
+
+        /// <summary>
+        /// Tests that cache plugin works with static cache.
+        /// </summary>
+        [Test]
+        public void TestStaticCache()
+        {
+            var cache = _grid.GetCache<int, int>(CacheName);
+
+            VerifyCachePlugin(cache);
+        }
+
+        /// <summary>
+        /// Tests that cache plugin works with static cache.
+        /// </summary>
+        [Test]
+        public void TestDynamicCache()
+        {
+            var cache = _grid.CreateCache<int, int>(new CacheConfiguration(DynCacheName)
+            {
+                PluginConfigurations = new[] {new CacheJavaPluginConfiguration()}
+            });
+
+            VerifyCachePlugin(cache);
+        }
+
+        /// <summary>
+        /// Verifies the cache plugin.
+        /// </summary>
+        private void VerifyCachePlugin(ICache<int, int> cache)
+        {
+            Assert.IsNull(cache.GetConfiguration().PluginConfigurations); // Java cache plugins are not returned.
+
+            cache[1] = 1;
+            Assert.AreEqual(1, cache[1]);
+
+            var plugins = _grid.GetCompute().ExecuteJavaTask<string[]>(GetPluginsTask, cache.Name);
+            Assert.AreEqual(new[] {PluginConfigurationClass}, plugins);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/ab1b6850/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Plugin/Cache/CachePluginConfiguration.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Plugin/Cache/CachePluginConfiguration.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Plugin/Cache/CachePluginConfiguration.cs
index 4627aa0..72220ff 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Plugin/Cache/CachePluginConfiguration.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Plugin/Cache/CachePluginConfiguration.cs
@@ -18,7 +18,9 @@
 namespace Apache.Ignite.Core.Tests.Plugin.Cache
 {
     using System;
+    using Apache.Ignite.Core.Binary;
     using Apache.Ignite.Core.Plugin.Cache;
+    using NUnit.Framework;
 
     /// <summary>
     /// Cache plugin config.
@@ -35,6 +37,28 @@ namespace Apache.Ignite.Core.Tests.Plugin.Cache
         /// <summary>
         /// Gets or sets a value indicating whether the plugin should throw an error.
         /// </summary>
+        // ReSharper disable once UnusedAutoPropertyAccessor.Global
         public bool ThrowError { get; set; }
+
+        /// <summary>
+        /// Gets the id to locate PlatformCachePluginConfigurationClosureFactory on Java side
+        /// and read the data written by
+        /// <see cref="WriteBinary(IBinaryRawWriter)" /> method.
+        /// </summary>
+        public int? CachePluginConfigurationClosureFactoryId
+        {
+            get { return null; }
+        }
+
+        /// <summary>
+        /// Writes this instance to a raw writer.
+        /// This method will be called when <see cref="CachePluginConfigurationClosureFactoryId" />
+        /// is not null to propagate configuration to the Java side.
+        /// </summary>
+        /// <param name="writer">The writer.</param>
+        public void WriteBinary(IBinaryRawWriter writer)
+        {
+            Assert.Fail("Should not be called");
+        }
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/ab1b6850/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Plugin/Cache/CachePluginTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Plugin/Cache/CachePluginTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Plugin/Cache/CachePluginTest.cs
index 583d314..0fc8877 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Plugin/Cache/CachePluginTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Plugin/Cache/CachePluginTest.cs
@@ -20,6 +20,7 @@ namespace Apache.Ignite.Core.Tests.Plugin.Cache
     using System;
     using System.Collections.Generic;
     using System.Linq;
+    using Apache.Ignite.Core.Binary;
     using Apache.Ignite.Core.Cache;
     using Apache.Ignite.Core.Cache.Configuration;
     using Apache.Ignite.Core.Plugin.Cache;
@@ -202,14 +203,16 @@ namespace Apache.Ignite.Core.Tests.Plugin.Cache
         [CachePluginProviderType(typeof(CachePlugin))]
         private class NonSerializableCachePluginConfig : ICachePluginConfiguration
         {
-            // No-op.
+            public int? CachePluginConfigurationClosureFactoryId { get { return null; } }
+            public void WriteBinary(IBinaryRawWriter writer) { /* No-op. */ }
         }
 
         [Serializable]
         [CachePluginProviderType(typeof(string))]
         private class ThrowCachePluginConfig : ICachePluginConfiguration
         {
-            // No-op.
+            public int? CachePluginConfigurationClosureFactoryId { get { return null; } }
+            public void WriteBinary(IBinaryRawWriter writer) { /* No-op. */ }
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/ab1b6850/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheConfiguration.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheConfiguration.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheConfiguration.cs
index 0e270dc..ebf412d 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheConfiguration.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheConfiguration.cs
@@ -375,11 +375,23 @@ namespace Apache.Ignite.Core.Cache.Configuration
                         throw new InvalidOperationException("Invalid cache configuration: " +
                                                             "ICachePluginConfiguration can't be null.");
 
-                    if (!cachePlugin.GetType().IsSerializable)
-                        throw new InvalidOperationException("Invalid cache configuration: " +
-                                                            "ICachePluginConfiguration should be Serializable.");
-
-                    writer.WriteObject(cachePlugin);
+                    if (cachePlugin.CachePluginConfigurationClosureFactoryId != null)
+                    {
+                        writer.WriteBoolean(true);
+                        writer.WriteInt(cachePlugin.CachePluginConfigurationClosureFactoryId.Value);
+                        cachePlugin.WriteBinary(writer);
+                    }
+                    else
+                    {
+                        if (!cachePlugin.GetType().IsSerializable)
+                        {
+                            throw new InvalidOperationException("Invalid cache configuration: " +
+                                                                "ICachePluginConfiguration should be Serializable.");
+                        }
+
+                        writer.WriteBoolean(false);
+                        writer.WriteObject(cachePlugin);
+                    }
                 }
             }
             else

http://git-wip-us.apache.org/repos/asf/ignite/blob/ab1b6850/modules/platforms/dotnet/Apache.Ignite.Core/Plugin/Cache/ICachePluginConfiguration.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Plugin/Cache/ICachePluginConfiguration.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Plugin/Cache/ICachePluginConfiguration.cs
index 5ea3b51..1790357 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Plugin/Cache/ICachePluginConfiguration.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Plugin/Cache/ICachePluginConfiguration.cs
@@ -18,6 +18,7 @@
 namespace Apache.Ignite.Core.Plugin.Cache
 {
     using System.Diagnostics.CodeAnalysis;
+    using Apache.Ignite.Core.Binary;
     using Apache.Ignite.Core.Cache.Configuration;
 
     /// <summary>
@@ -45,6 +46,21 @@ namespace Apache.Ignite.Core.Plugin.Cache
     [SuppressMessage("Microsoft.Design", "CA1040:AvoidEmptyInterfaces")]
     public interface ICachePluginConfiguration
     {
-        // No-op.
+        /// <summary>
+        /// Gets the id to locate PlatformCachePluginConfigurationClosureFactory on Java side
+        /// and read the data written by <see cref="WriteBinary"/> method.
+        /// <para />
+        /// When this property is not null, all cache plugin functionality is delegated to Java part.
+        /// <see cref="ICachePluginProvider{TConfig}"/> won't be invoked.
+        /// </summary>
+        int? CachePluginConfigurationClosureFactoryId { get; }
+
+        /// <summary>
+        /// Writes this instance to a raw writer.
+        /// This method will be called when <see cref="CachePluginConfigurationClosureFactoryId"/> 
+        /// is not null to propagate configuration to the Java side.
+        /// </summary>
+        /// <param name="writer">The writer.</param>
+        void WriteBinary(IBinaryRawWriter writer);
     }
 }