Repository: incubator-ignite Updated Branches: refs/heads/ignite-45 cf083b9f8 -> c1d532607
#ignite-556: Add method Ignite.createCache(@Nullable String springCfgPath) Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/e743e535 Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/e743e535 Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/e743e535 Branch: refs/heads/ignite-45 Commit: e743e535f969dc994adc06d6780000cd2639d60c Parents: 444ee28 Author: ivasilinets <[email protected]> Authored: Mon Mar 23 13:01:50 2015 +0300 Committer: ivasilinets <[email protected]> Committed: Mon Mar 23 13:01:50 2015 +0300 ---------------------------------------------------------------------- .../src/main/java/org/apache/ignite/Ignite.java | 11 ++ .../apache/ignite/internal/IgniteKernal.java | 25 +++++ .../org/apache/ignite/internal/IgnitionEx.java | 31 +----- .../spring/IgniteSpringProcessor.java | 15 +++ .../ignite/internal/util/IgniteUtils.java | 27 +++++ modules/core/src/test/config/cache.xml | 56 ++++++++++ .../ignite/testframework/junits/IgniteMock.java | 5 + .../org/apache/ignite/IgniteSpringBean.java | 7 ++ .../spring/IgniteSpringProcessorImpl.java | 104 +++++++++++-------- .../internal/IgniteDynamicCacheConfigTest.java | 51 +++++++++ 10 files changed, 260 insertions(+), 72 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e743e535/modules/core/src/main/java/org/apache/ignite/Ignite.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/Ignite.java b/modules/core/src/main/java/org/apache/ignite/Ignite.java index c2aa6bd..ff4eea6 100644 --- a/modules/core/src/main/java/org/apache/ignite/Ignite.java +++ b/modules/core/src/main/java/org/apache/ignite/Ignite.java @@ -197,6 +197,17 @@ public interface Ignite extends AutoCloseable { public <K, V> IgniteCache<K, V> createCache(CacheConfiguration<K, V> cacheCfg); /** + * Dynamically starts new cache with the given cache configuration. + * <p> + * If local node is an affinity node, this method will return the instance of started cache. + * Otherwise, it will create a client cache on local node. + * + * @param springCfgPath Spring XML configuration file path or URL. + * @return Instance of started cache. + */ + public <K, V> IgniteCache<K, V> createCache(@Nullable String springCfgPath) throws IgniteCheckedException; + + /** * Gets existing cache with the given name or creates new one with the given configuration. * * @param cacheCfg Cache configuration to use. http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e743e535/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java index 41cceac..d1f3f99 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java @@ -56,6 +56,7 @@ import org.apache.ignite.internal.processors.security.*; import org.apache.ignite.internal.processors.segmentation.*; import org.apache.ignite.internal.processors.service.*; import org.apache.ignite.internal.processors.session.*; +import org.apache.ignite.internal.processors.spring.*; import org.apache.ignite.internal.processors.task.*; import org.apache.ignite.internal.processors.timeout.*; import org.apache.ignite.internal.util.*; @@ -76,6 +77,7 @@ import javax.management.*; import java.io.*; import java.lang.management.*; import java.lang.reflect.*; +import java.net.*; import java.text.*; import java.util.*; import java.util.concurrent.*; @@ -2274,6 +2276,29 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable { } /** {@inheritDoc} */ + public <K, V> IgniteCache<K, V> createCache(@Nullable String springCfgPath) throws IgniteCheckedException { + if (springCfgPath == null) { + return createCache((CacheConfiguration) null); + } + else { + URL url = U.resolveSpringUrl(springCfgPath); + + IgniteSpringProcessor spring = SPRING.create(false); + + IgniteBiTuple<Collection<CacheConfiguration>, ? extends GridSpringResourceContext> cfgMap = + spring.loadCacheConfigurations(url); + + if (cfgMap.size() != 1) + throw new IgniteCheckedException("File " + url.toString() + " should have one cache configuration"); + + for (CacheConfiguration cfg : cfgMap.get1()) + return createCache(cfg); + } + + return null; + } + + /** {@inheritDoc} */ @Override public <K, V> IgniteCache<K, V> getOrCreateCache(CacheConfiguration<K, V> cacheCfg) { A.notNull(cacheCfg, "cacheCfg"); http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e743e535/modules/core/src/main/java/org/apache/ignite/internal/IgnitionEx.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgnitionEx.java b/modules/core/src/main/java/org/apache/ignite/internal/IgnitionEx.java index ea09523..0f72ac4 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/IgnitionEx.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/IgnitionEx.java @@ -542,7 +542,7 @@ public class IgnitionEx { */ public static Ignite startWithClosure(@Nullable String springCfgPath, @Nullable String gridName, IgniteClosure<IgniteConfiguration, IgniteConfiguration> cfgClo) throws IgniteCheckedException { - URL url = resolveSpringUrl(springCfgPath); + URL url = U.resolveSpringUrl(springCfgPath); return start(url, gridName, null, cfgClo); } @@ -665,7 +665,7 @@ public class IgnitionEx { */ public static Ignite start(String springCfgPath, @Nullable String gridName, @Nullable GridSpringResourceContext springCtx) throws IgniteCheckedException { - URL url = resolveSpringUrl(springCfgPath); + URL url = U.resolveSpringUrl(springCfgPath); return start(url, gridName, springCtx); } @@ -808,33 +808,6 @@ public class IgnitionEx { } /** - * Resolve Spring configuration URL. - * - * @param springCfgPath Spring XML configuration file path or URL. This cannot be {@code null}. - * @return URL. - * @throws IgniteCheckedException If failed. - */ - private static URL resolveSpringUrl(String springCfgPath) throws IgniteCheckedException { - A.notNull(springCfgPath, "springCfgPath"); - - URL url; - - try { - url = new URL(springCfgPath); - } - catch (MalformedURLException e) { - url = U.resolveIgniteUrl(springCfgPath); - - if (url == null) - throw new IgniteCheckedException("Spring XML configuration path is invalid: " + springCfgPath + - ". Note that this path should be either absolute or a relative local file system path, " + - "relative to META-INF in classpath or valid URL to IGNITE_HOME.", e); - } - - return url; - } - - /** * Starts grid with given configuration. * * @param startCtx Start context. http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e743e535/modules/core/src/main/java/org/apache/ignite/internal/processors/spring/IgniteSpringProcessor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/spring/IgniteSpringProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/spring/IgniteSpringProcessor.java index d0167fe..cd2e3d4 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/spring/IgniteSpringProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/spring/IgniteSpringProcessor.java @@ -48,6 +48,21 @@ public interface IgniteSpringProcessor { URL cfgUrl, String... excludedProps) throws IgniteCheckedException; /** + * Loads all cache configurations specified within given configuration file. + * <p> + * Usually Spring XML configuration file will contain only one Cache definition. Note that + * Cache configuration bean(s) is retrieved form configuration file by type, so the name of + * the Cache configuration bean is ignored. + * + * @param cfgUrl Configuration file path or URL. This cannot be {@code null}. + * @return Tuple containing all loaded configurations and Spring context used to load them. + * @throws IgniteCheckedException If configuration could not be + * read. + */ + public IgniteBiTuple<Collection<CacheConfiguration>, ? extends GridSpringResourceContext> loadCacheConfigurations( + URL cfgUrl) throws IgniteCheckedException; + + /** * Loads bean instances that match the given types from given configuration file. * * @param cfgUrl Configuration file path or URL. This cannot be {@code null}. http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e743e535/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java index c2cbabf..0cfccbd 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java @@ -3219,6 +3219,33 @@ public abstract class IgniteUtils { } /** + * Resolve Spring configuration URL. + * + * @param springCfgPath Spring XML configuration file path or URL. This cannot be {@code null}. + * @return URL. + * @throws IgniteCheckedException If failed. + */ + public static URL resolveSpringUrl(String springCfgPath) throws IgniteCheckedException { + A.notNull(springCfgPath, "springCfgPath"); + + URL url; + + try { + url = new URL(springCfgPath); + } + catch (MalformedURLException e) { + url = U.resolveIgniteUrl(springCfgPath); + + if (url == null) + throw new IgniteCheckedException("Spring XML configuration path is invalid: " + springCfgPath + + ". Note that this path should be either absolute or a relative local file system path, " + + "relative to META-INF in classpath or valid URL to IGNITE_HOME.", e); + } + + return url; + } + + /** * Gets URL representing the path passed in. First the check is made if path is absolute. * If not, then the check is made if path is relative to {@code META-INF} folder in classpath. * If not, then the check is made if path is relative to ${IGNITE_HOME}. http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e743e535/modules/core/src/test/config/cache.xml ---------------------------------------------------------------------- diff --git a/modules/core/src/test/config/cache.xml b/modules/core/src/test/config/cache.xml new file mode 100644 index 0000000..8c0e417 --- /dev/null +++ b/modules/core/src/test/config/cache.xml @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + 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. +--> + +<!-- + Ignite Spring configuration file to startup grid cache. + + When starting a standalone Ignite node, you need to execute the following command: + {IGNITE_HOME}/bin/ignite.{bat|sh} examples/config/example-cache.xml + + When starting Ignite from Java IDE, pass path to this file to Ignite: + Ignition.start("examples/config/example-cache.xml"); +--> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:util="http://www.springframework.org/schema/util" + xsi:schemaLocation=" + http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/util + http://www.springframework.org/schema/util/spring-util.xsd"> + <bean id="cache-configuration" class="org.apache.ignite.configuration.CacheConfiguration"> + <!-- Initial cache size. --> + <property name="startSize" value="3000000"/> + + <!-- Set synchronous rebalancing (default is asynchronous). --> + <property name="rebalanceMode" value="SYNC"/> + + <!-- Set to FULL_SYNC for examples, default is PRIMARY_SYNC. --> + <property name="writeSynchronizationMode" value="FULL_SYNC"/> + + <property name="name" value="TestDynamicCache"/> + + <property name="cacheMode" value="PARTITIONED"/> + + <property name="atomicityMode" value="ATOMIC"/> + + <property name="backups" value="1"/> + </bean> +</beans> + http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e743e535/modules/core/src/test/java/org/apache/ignite/testframework/junits/IgniteMock.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/junits/IgniteMock.java b/modules/core/src/test/java/org/apache/ignite/testframework/junits/IgniteMock.java index dfcf487..fa96112 100644 --- a/modules/core/src/test/java/org/apache/ignite/testframework/junits/IgniteMock.java +++ b/modules/core/src/test/java/org/apache/ignite/testframework/junits/IgniteMock.java @@ -171,6 +171,11 @@ public class IgniteMock implements Ignite { } /** {@inheritDoc} */ + @Override public <K, V> IgniteCache<K, V> createCache(@Nullable String springCfgPath) throws IgniteCheckedException { + return null; + } + + /** {@inheritDoc} */ @Override public <K, V> IgniteCache<K, V> getOrCreateCache(CacheConfiguration<K, V> cacheCfg) { return null; } http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e743e535/modules/spring/src/main/java/org/apache/ignite/IgniteSpringBean.java ---------------------------------------------------------------------- diff --git a/modules/spring/src/main/java/org/apache/ignite/IgniteSpringBean.java b/modules/spring/src/main/java/org/apache/ignite/IgniteSpringBean.java index c8db3bd..4c4b194 100644 --- a/modules/spring/src/main/java/org/apache/ignite/IgniteSpringBean.java +++ b/modules/spring/src/main/java/org/apache/ignite/IgniteSpringBean.java @@ -240,6 +240,13 @@ public class IgniteSpringBean implements Ignite, DisposableBean, InitializingBea } /** {@inheritDoc} */ + @Override public <K, V> IgniteCache<K, V> createCache(@Nullable String springCfgPath) throws IgniteCheckedException { + assert g != null; + + return g.createCache(springCfgPath); + } + + /** {@inheritDoc} */ @Override public <K, V> IgniteCache<K, V> getOrCreateCache(CacheConfiguration<K, V> cacheCfg) { assert g != null; http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e743e535/modules/spring/src/main/java/org/apache/ignite/internal/processors/spring/IgniteSpringProcessorImpl.java ---------------------------------------------------------------------- diff --git a/modules/spring/src/main/java/org/apache/ignite/internal/processors/spring/IgniteSpringProcessorImpl.java b/modules/spring/src/main/java/org/apache/ignite/internal/processors/spring/IgniteSpringProcessorImpl.java index 2049b05..b068851 100644 --- a/modules/spring/src/main/java/org/apache/ignite/internal/processors/spring/IgniteSpringProcessorImpl.java +++ b/modules/spring/src/main/java/org/apache/ignite/internal/processors/spring/IgniteSpringProcessorImpl.java @@ -78,20 +78,7 @@ public class IgniteSpringProcessorImpl implements IgniteSpringProcessor { /** {@inheritDoc} */ @Override public IgniteBiTuple<Collection<IgniteConfiguration>, ? extends GridSpringResourceContext> loadConfigurations( URL cfgUrl, String... excludedProps) throws IgniteCheckedException { - ApplicationContext springCtx; - - try { - springCtx = applicationContext(cfgUrl, excludedProps); - } - catch (BeansException e) { - if (X.hasCause(e, ClassNotFoundException.class)) - throw new IgniteCheckedException("Failed to instantiate Spring XML application context " + - "(make sure all classes used in Spring configuration are present at CLASSPATH) " + - "[springUrl=" + cfgUrl + ']', e); - else - throw new IgniteCheckedException("Failed to instantiate Spring XML application context [springUrl=" + - cfgUrl + ", err=" + e.getMessage() + ']', e); - } + ApplicationContext springCtx = applicationContext(cfgUrl, excludedProps); Map<String, IgniteConfiguration> cfgMap; @@ -110,6 +97,26 @@ public class IgniteSpringProcessorImpl implements IgniteSpringProcessor { } /** {@inheritDoc} */ + @Override public IgniteBiTuple<Collection<CacheConfiguration>, ? extends GridSpringResourceContext> loadCacheConfigurations ( + URL cfgUrl) throws IgniteCheckedException { + ApplicationContext springCtx = applicationContext(cfgUrl); + Map<String, CacheConfiguration> cfgMap; + + try { + cfgMap = springCtx.getBeansOfType(CacheConfiguration.class); + } + catch (BeansException e) { + throw new IgniteCheckedException("Failed to instantiate bean [type=" + CacheConfiguration.class + + ", err=" + e.getMessage() + ']', e); + } + + if (cfgMap == null || cfgMap.isEmpty()) + throw new IgniteCheckedException("Failed to find cache configuration in: " + cfgUrl); + + return F.t(cfgMap.values(), new GridSpringResourceContextImpl(springCtx)); + } + + /** {@inheritDoc} */ @Override public Map<Class<?>, Object> loadBeans(URL cfgUrl, Class<?>... beanClasses) throws IgniteCheckedException { assert beanClasses.length > 0; @@ -225,44 +232,55 @@ public class IgniteSpringProcessorImpl implements IgniteSpringProcessor { * @param excludedProps Properties to be excluded. * @return Spring application context. */ - public static ApplicationContext applicationContext(URL cfgUrl, final String... excludedProps) { - GenericApplicationContext springCtx = new GenericApplicationContext(); - - BeanFactoryPostProcessor postProc = new BeanFactoryPostProcessor() { - @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) - throws BeansException { - for (String beanName : beanFactory.getBeanDefinitionNames()) { - BeanDefinition def = beanFactory.getBeanDefinition(beanName); - - if (def.getBeanClassName() != null) { - try { - Class.forName(def.getBeanClassName()); - } - catch (ClassNotFoundException ignored) { - ((BeanDefinitionRegistry)beanFactory).removeBeanDefinition(beanName); - - continue; + public static ApplicationContext applicationContext(URL cfgUrl, final String... excludedProps) throws IgniteCheckedException { + try { + GenericApplicationContext springCtx = new GenericApplicationContext(); + + BeanFactoryPostProcessor postProc = new BeanFactoryPostProcessor() { + @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) + throws BeansException { + for (String beanName : beanFactory.getBeanDefinitionNames()) { + BeanDefinition def = beanFactory.getBeanDefinition(beanName); + + if (def.getBeanClassName() != null) { + try { + Class.forName(def.getBeanClassName()); + } + catch (ClassNotFoundException ignored) { + ((BeanDefinitionRegistry) beanFactory).removeBeanDefinition(beanName); + + continue; + } } - } - MutablePropertyValues vals = def.getPropertyValues(); + MutablePropertyValues vals = def.getPropertyValues(); - for (PropertyValue val : new ArrayList<>(vals.getPropertyValueList())) { - for (String excludedProp : excludedProps) { - if (val.getName().equals(excludedProp)) - vals.removePropertyValue(val); + for (PropertyValue val : new ArrayList<>(vals.getPropertyValueList())) { + for (String excludedProp : excludedProps) { + if (val.getName().equals(excludedProp)) + vals.removePropertyValue(val); + } } } } - } - }; + }; - springCtx.addBeanFactoryPostProcessor(postProc); + springCtx.addBeanFactoryPostProcessor(postProc); - new XmlBeanDefinitionReader(springCtx).loadBeanDefinitions(new UrlResource(cfgUrl)); + new XmlBeanDefinitionReader(springCtx).loadBeanDefinitions(new UrlResource(cfgUrl)); - springCtx.refresh(); + springCtx.refresh(); - return springCtx; + return springCtx; + } + catch (BeansException e) { + if (X.hasCause(e, ClassNotFoundException.class)) + throw new IgniteCheckedException("Failed to instantiate Spring XML application context " + + "(make sure all classes used in Spring configuration are present at CLASSPATH) " + + "[springUrl=" + cfgUrl + ']', e); + else + throw new IgniteCheckedException("Failed to instantiate Spring XML application context [springUrl=" + + cfgUrl + ", err=" + e.getMessage() + ']', e); + } } } http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e743e535/modules/spring/src/test/java/org/apache/ignite/internal/IgniteDynamicCacheConfigTest.java ---------------------------------------------------------------------- diff --git a/modules/spring/src/test/java/org/apache/ignite/internal/IgniteDynamicCacheConfigTest.java b/modules/spring/src/test/java/org/apache/ignite/internal/IgniteDynamicCacheConfigTest.java new file mode 100644 index 0000000..59c16de --- /dev/null +++ b/modules/spring/src/test/java/org/apache/ignite/internal/IgniteDynamicCacheConfigTest.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal; + + +import org.apache.ignite.*; +import org.apache.ignite.testframework.junits.common.*; + +/** + * Test for dynamic cache start from config file. + */ +public class IgniteDynamicCacheConfigTest extends GridCommonAbstractTest { + /** {@inheritDoc} */ + @Override protected void beforeTestsStarted() throws Exception { + super.beforeTestsStarted(); + + startGrids(1); + } + + /** {@inheritDoc} */ + @Override protected void afterTestsStopped() throws Exception { + super.afterTestsStopped(); + + stopAllGrids(); + } + + /** + * @throws Exception If failed. + */ + public void testDynamicCacheStartFromConfig() throws Exception { + IgniteCache cache = ignite(0).createCache("modules/core/src/test/config/cache.xml"); + + assertEquals("TestDynamicCache", cache.getName()); + } + +}
