# ignite-680
Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/5832b3a9 Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/5832b3a9 Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/5832b3a9 Branch: refs/heads/ignite-30 Commit: 5832b3a99f61ef298f2d8c75ae0d208a2f58be72 Parents: 414882c Author: sboikov <sboi...@gridgain.com> Authored: Tue Apr 7 11:50:45 2015 +0300 Committer: sboikov <sboi...@gridgain.com> Committed: Tue Apr 7 12:02:23 2015 +0300 ---------------------------------------------------------------------- .../cache/CacheTemplateConfigurationKey.java | 53 -- .../cache/DynamicCacheChangeRequest.java | 17 + .../cache/DynamicCacheDescriptor.java | 17 +- .../processors/cache/GridCacheProcessor.java | 478 ++++++++----------- .../GridDhtPartitionsExchangeFuture.java | 1 + .../IgniteCacheConfigurationTemplateTest.java | 61 +++ 6 files changed, 303 insertions(+), 324 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/5832b3a9/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheTemplateConfigurationKey.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheTemplateConfigurationKey.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheTemplateConfigurationKey.java deleted file mode 100644 index 310fa74..0000000 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheTemplateConfigurationKey.java +++ /dev/null @@ -1,53 +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.apache.ignite.internal.processors.cache; - -import java.io.*; - -/** - * - */ -public class CacheTemplateConfigurationKey implements GridCacheInternal, Externalizable { - /** */ - private static final long serialVersionUID = 0L; - - /** {@inheritDoc} */ - @Override public int hashCode() { - return getClass().getName().hashCode(); - } - - /** {@inheritDoc} */ - @Override public boolean equals(Object obj) { - return obj == this || (obj instanceof CacheTemplateConfigurationKey); - } - - /** {@inheritDoc} */ - @Override public void writeExternal(ObjectOutput out) throws IOException { - // No-op. - } - - /** {@inheritDoc} */ - @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { - // No-op. - } - - /** {@inheritDoc} */ - @Override public String toString() { - return "CacheTemplateConfigurationKey []"; - } -} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/5832b3a9/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/DynamicCacheChangeRequest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/DynamicCacheChangeRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/DynamicCacheChangeRequest.java index f7c8769..bd53cdb 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/DynamicCacheChangeRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/DynamicCacheChangeRequest.java @@ -60,6 +60,9 @@ public class DynamicCacheChangeRequest implements Serializable { /** Fail if exists flag. */ private boolean failIfExists; + /** Template configuration flag. */ + private boolean template; + /** * Constructor creates cache stop request. * @@ -85,6 +88,20 @@ public class DynamicCacheChangeRequest implements Serializable { } /** + * @param template {@code True} if this is request for adding template configuration. + */ + public void template(boolean template) { + this.template = template; + } + + /** + * @return {@code True} if this is template configuration. + */ + public boolean template() { + return template; + } + + /** * @return Deployment ID. */ public IgniteUuid deploymentId() { http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/5832b3a9/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/DynamicCacheDescriptor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/DynamicCacheDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/DynamicCacheDescriptor.java index 4f07658..d8da9ef 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/DynamicCacheDescriptor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/DynamicCacheDescriptor.java @@ -53,18 +53,33 @@ public class DynamicCacheDescriptor { /** */ private volatile Map<UUID, CacheConfiguration> rmtCfgs; + /** Template configuration flag. */ + private boolean template; + /** * @param cacheCfg Cache configuration. * @param cacheType Cache type. + * @param template {@code True} if this is template configuration. * @param deploymentId Deployment ID. */ - public DynamicCacheDescriptor(CacheConfiguration cacheCfg, CacheType cacheType, IgniteUuid deploymentId) { + public DynamicCacheDescriptor(CacheConfiguration cacheCfg, + CacheType cacheType, + boolean template, + IgniteUuid deploymentId) { this.cacheCfg = cacheCfg; this.cacheType = cacheType; + this.template = template; this.deploymentId = deploymentId; } /** + * @return {@code True} if this is template configuration. + */ + public boolean template() { + return template; + } + + /** * @return Cache type. */ public CacheType cacheType() { http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/5832b3a9/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java index eb98b89..fcf65b9 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java @@ -110,9 +110,15 @@ public class GridCacheProcessor extends GridProcessorAdapter { /** Pending cache starts. */ private ConcurrentMap<String, IgniteInternalFuture> pendingFuts = new ConcurrentHashMap<>(); + /** Template configuration add futures. */ + private ConcurrentMap<String, IgniteInternalFuture> pendingTemplateFuts = new ConcurrentHashMap<>(); + /** Dynamic caches. */ private ConcurrentMap<String, DynamicCacheDescriptor> registeredCaches = new ConcurrentHashMap<>(); + /** Cache templates. */ + private ConcurrentMap<String, DynamicCacheDescriptor> registeredTemplates = new ConcurrentHashMap<>(); + /** */ private IdentityHashMap<CacheStore, ThreadLocal> sesHolders = new IdentityHashMap<>(); @@ -438,7 +444,7 @@ public class GridCacheProcessor extends GridProcessorAdapter { if (ctx.config().getCacheMode() == LOCAL || !isNearEnabled(ctx)) return Collections.emptyList(); else - return F.asList((GridCacheManager)ctx.queries(), ctx.continuousQueries(), ctx.store()); + return F.asList(ctx.queries(), ctx.continuousQueries(), ctx.store()); } /** @@ -576,9 +582,6 @@ public class GridCacheProcessor extends GridProcessorAdapter { cfgs[i] = cfg; // Replace original configuration value. - if (cfg.getName() != null && cfg.getName().endsWith("*")) // Skip template configurations. - continue; - String masked = maskNull(cfg.getName()); if (registeredCaches.containsKey(masked)) { @@ -603,23 +606,43 @@ public class GridCacheProcessor extends GridProcessorAdapter { else cacheType = CacheType.USER; - DynamicCacheDescriptor desc = new DynamicCacheDescriptor(cfg, cacheType, IgniteUuid.randomUuid()); + boolean template = cfg.getName() != null && cfg.getName().endsWith("*"); + + DynamicCacheDescriptor desc = new DynamicCacheDescriptor(cfg, cacheType, template, IgniteUuid.randomUuid()); desc.locallyConfigured(true); desc.staticallyConfigured(true); - registeredCaches.put(masked, desc); + if (!template) { + registeredCaches.put(masked, desc); - ctx.discovery().setCacheFilter( - cfg.getName(), - cfg.getNodeFilter(), - cfg.getNearConfiguration() != null, - cfg.getCacheMode() == LOCAL); + ctx.discovery().setCacheFilter( + cfg.getName(), + cfg.getNodeFilter(), + cfg.getNearConfiguration() != null, + cfg.getCacheMode() == LOCAL); - if (!cacheType.userCache()) - stopSeq.addLast(cfg.getName()); - else - stopSeq.addFirst(cfg.getName()); + if (!cacheType.userCache()) + stopSeq.addLast(cfg.getName()); + else + stopSeq.addFirst(cfg.getName()); + } + else { + if (log.isDebugEnabled()) + log.debug("Use cache configuration as template: " + cfg); + + registeredTemplates.put(masked, desc); + } + + if (cfg.getName() == null) { // Use cache configuration with null name as template. + DynamicCacheDescriptor desc0 = + new DynamicCacheDescriptor(cfg, cacheType, true, IgniteUuid.randomUuid()); + + desc0.locallyConfigured(true); + desc0.staticallyConfigured(true); + + registeredTemplates.put(masked, desc0); + } } // Start shared managers. @@ -770,20 +793,6 @@ public class GridCacheProcessor extends GridProcessorAdapter { } ctx.cacheObjects().onCacheProcessorStarted(); - - List<CacheConfiguration> templateCfgs = null; - - for (CacheConfiguration cfg : ctx.config().getCacheConfiguration()) { - if (cfg.getName() == null || cfg.getName().endsWith("*")) { - if (templateCfgs == null) - templateCfgs = new ArrayList<>(); - - templateCfgs.add(cfg); - } - } - - if (templateCfgs != null) - addCacheConfigurations(templateCfgs); } /** {@inheritDoc} */ @@ -942,7 +951,7 @@ public class GridCacheProcessor extends GridProcessorAdapter { ctx.kernalContext().continuous().onCacheStop(ctx); U.stopLifecycleAware(log, lifecycleAwares(cache.configuration(), ctx.jta().tmLookup(), - ctx.store().configuredStore())); + ctx.store().configuredStore())); if (log.isInfoEnabled()) log.info("Stopped cache: " + cache.name()); @@ -1295,7 +1304,7 @@ public class GridCacheProcessor extends GridProcessorAdapter { } /** - * Gets a collection of currentlty started caches. + * Gets a collection of currently started caches. * * @return Collection of started cache names. */ @@ -1581,7 +1590,8 @@ public class GridCacheProcessor extends GridProcessorAdapter { /** {@inheritDoc} */ @Nullable @Override public Object collectDiscoveryData(UUID nodeId) { // Collect dynamically started caches to a single object. - Collection<DynamicCacheChangeRequest> reqs = new ArrayList<>(registeredCaches.size()); + Collection<DynamicCacheChangeRequest> reqs = + new ArrayList<>(registeredCaches.size() + registeredTemplates.size()); for (DynamicCacheDescriptor desc : registeredCaches.values()) { if (!desc.cancelled()) { @@ -1597,6 +1607,18 @@ public class GridCacheProcessor extends GridProcessorAdapter { } } + for (DynamicCacheDescriptor desc : registeredTemplates.values()) { + DynamicCacheChangeRequest req = new DynamicCacheChangeRequest(desc.cacheConfiguration().getName(), null); + + req.startCacheConfiguration(desc.cacheConfiguration()); + + req.template(true); + + req.deploymentId(desc.deploymentId()); + + reqs.add(req); + } + DynamicCacheChangeBatch req = new DynamicCacheChangeBatch(reqs); req.clientNodes(ctx.discovery().clientNodesMap()); @@ -1610,6 +1632,26 @@ public class GridCacheProcessor extends GridProcessorAdapter { DynamicCacheChangeBatch batch = (DynamicCacheChangeBatch)data; for (DynamicCacheChangeRequest req : batch.requests()) { + if (req.template()) { + CacheConfiguration ccfg = req.startCacheConfiguration(); + + assert ccfg != null : req; + + DynamicCacheDescriptor existing = registeredTemplates.get(maskNull(req.cacheName())); + + if (existing == null) { + DynamicCacheDescriptor desc = new DynamicCacheDescriptor( + ccfg, + req.cacheType(), + true, + req.deploymentId()); + + registeredTemplates.put(maskNull(req.cacheName()), desc); + } + + continue; + } + DynamicCacheDescriptor existing = registeredCaches.get(maskNull(req.cacheName())); if (req.start() && !req.clientStartOnly()) { @@ -1634,6 +1676,7 @@ public class GridCacheProcessor extends GridProcessorAdapter { DynamicCacheDescriptor desc = new DynamicCacheDescriptor( ccfg, req.cacheType(), + false, req.deploymentId()); // Received statically configured cache. @@ -1673,12 +1716,62 @@ public class GridCacheProcessor extends GridProcessorAdapter { if (publicJCache(cacheName, false) != null) // Cache with given name already started. return new GridFinishedFuture<>(); - GridCacheAdapter<CacheTemplateConfigurationKey, TemplateConfigurations> utilityCache = utilityCache(); + CacheConfiguration cfgTemplate = null; + + CacheConfiguration dfltCacheCfg = null; + + List<CacheConfiguration> wildcardNameCfgs = null; + + for (DynamicCacheDescriptor desc : registeredTemplates.values()) { + assert desc.template(); + + CacheConfiguration cfg = desc.cacheConfiguration(); + + assert cfg != null; + + if (F.eq(cacheName, cfg.getName())) { + cfgTemplate = cfg; + + break; + } + + if (cfg.getName() != null ) { + if (cfg.getName().endsWith("*")) { + if (cfg.getName().length() > 1) { + if (wildcardNameCfgs == null) + wildcardNameCfgs = new ArrayList<>(); + + wildcardNameCfgs.add(cfg); + } + else + dfltCacheCfg = cfg; // Template with name '*'. + } + } + else if (dfltCacheCfg == null) + dfltCacheCfg = cfg; + } + + if (cfgTemplate == null && cacheName != null && wildcardNameCfgs != null) { + Collections.sort(wildcardNameCfgs, new Comparator<CacheConfiguration>() { + @Override public int compare(CacheConfiguration cfg1, CacheConfiguration cfg2) { + Integer len1 = cfg1.getName() != null ? cfg1.getName().length() : 0; + Integer len2 = cfg2.getName() != null ? cfg2.getName().length() : 0; + + return len2.compareTo(len1); + } + }); - TemplateConfigurations cfgs = - utilityCache.localPeek(new CacheTemplateConfigurationKey(), CachePeekModes.ONHEAP_ONLY, null); + for (CacheConfiguration cfg : wildcardNameCfgs) { + if (cacheName.startsWith(cfg.getName().substring(0, cfg.getName().length() - 1))) { + cfgTemplate = cfg; - CacheConfiguration cfgTemplate = cfgs != null ? cfgs.configuration(cacheName) : null; + break; + } + } + } + + if (cfgTemplate == null) + cfgTemplate = dfltCacheCfg; if (cfgTemplate == null) throw new IllegalArgumentException("Failed to start cache " + @@ -1880,6 +1973,32 @@ public class GridCacheProcessor extends GridProcessorAdapter { */ private void onCacheChangeRequested(DynamicCacheChangeBatch batch) { for (DynamicCacheChangeRequest req : batch.requests()) { + if (req.template()) { + CacheConfiguration ccfg = req.startCacheConfiguration(); + + assert ccfg != null : req; + + DynamicCacheDescriptor desc = registeredTemplates.get(maskNull(req.cacheName())); + + if (desc == null) { + DynamicCacheDescriptor templateDesc = + new DynamicCacheDescriptor(ccfg, req.cacheType(), true, req.deploymentId()); + + DynamicCacheDescriptor old = registeredTemplates.put(maskNull(ccfg.getName()), templateDesc); + + assert old == null : + "Dynamic cache map was concurrently modified [new=" + templateDesc + ", old=" + old + ']'; + } + + TemplateConfigurationFuture fut = + (TemplateConfigurationFuture)pendingTemplateFuts.get(maskNull(ccfg.getName())); + + if (fut != null && fut.deploymentId().equals(req.deploymentId())) + fut.onDone(); + + continue; + } + DynamicCacheDescriptor desc = registeredCaches.get(maskNull(req.cacheName())); if (req.start()) { @@ -1917,7 +2036,7 @@ public class GridCacheProcessor extends GridProcessorAdapter { assert req.cacheType() != null : req; DynamicCacheDescriptor startDesc = - new DynamicCacheDescriptor(ccfg, req.cacheType(), req.deploymentId()); + new DynamicCacheDescriptor(ccfg, req.cacheType(), false, req.deploymentId()); DynamicCacheDescriptor old = registeredCaches.put(maskNull(ccfg.getName()), startDesc); @@ -2432,44 +2551,34 @@ public class GridCacheProcessor extends GridProcessorAdapter { * @throws IgniteCheckedException If failed. */ public void addCacheConfiguration(CacheConfiguration cacheCfg) throws IgniteCheckedException { - addCacheConfigurations(Collections.singleton(cacheCfg)); - } + String masked = maskNull(cacheCfg.getName()); - /** - * @param cfgs Cache configurations. - * @throws IgniteCheckedException If failed. - */ - private void addCacheConfigurations(Collection<CacheConfiguration> cfgs) throws IgniteCheckedException { - GridCacheAdapter<CacheTemplateConfigurationKey, TemplateConfigurations> utilityCache = utilityCache(); + DynamicCacheDescriptor desc = registeredTemplates.get(masked); - TemplateConfigurations templates = - utilityCache.localPeek(new CacheTemplateConfigurationKey(), CachePeekModes.ONHEAP_ONLY, null); + if (desc != null) + return; - if (templates != null) { - cfgs = templates.needAdd(cfgs); + DynamicCacheChangeRequest req = new DynamicCacheChangeRequest(cacheCfg.getName(), ctx.localNodeId()); - if (cfgs == null) - return; - } + CacheConfiguration cfg = new CacheConfiguration(cacheCfg); - final int RETRY_CNT = 5; + req.template(true); - for (int i = 0; i < RETRY_CNT; i++) { - try { - utilityCache.invoke( - new CacheTemplateConfigurationKey(), new AddCacheTemplateProcessor(cfgs)); + req.startCacheConfiguration(cfg); - break; - } - catch (IgniteCheckedException e) { - if (i < RETRY_CNT - 1) { - if (log.isDebugEnabled()) - log.debug("Failed to save cache template configuration, will retry: " + e); - } - else - throw e; - } - } + req.deploymentId(IgniteUuid.randomUuid()); + + TemplateConfigurationFuture fut = new TemplateConfigurationFuture(req.cacheName(), req.deploymentId()); + + TemplateConfigurationFuture old = + (TemplateConfigurationFuture)pendingTemplateFuts.putIfAbsent(maskNull(cacheCfg.getName()), fut); + + if (old != null) + fut = old; + + ctx.discovery().sendCustomEvent(new DynamicCacheChangeBatch(Collections.singleton(req))); + + fut.get(); } /** @@ -2719,213 +2828,55 @@ public class GridCacheProcessor extends GridProcessorAdapter { /** * */ - private class AddCacheTemplateProcessor implements - CacheEntryProcessor<CacheTemplateConfigurationKey, TemplateConfigurations, Void> { - /** */ - private static final long serialVersionUID = 0L; - - /** */ - private Collection<CacheConfiguration> cfgs; - - /** - * @param cfgs Cache configuration templates. - */ - public AddCacheTemplateProcessor(Collection<CacheConfiguration> cfgs) { - assert !F.isEmpty(cfgs); - - this.cfgs = cfgs; - } - - /** {@inheritDoc} */ - @Override public Void process(MutableEntry<CacheTemplateConfigurationKey, TemplateConfigurations> entry, - Object... args) - { - TemplateConfigurations cfgs0 = entry.getValue(); - - if (cfgs0 == null) - cfgs0 = new TemplateConfigurations(); - - cfgs0.add(cfgs); - - entry.setValue(cfgs0); - - return null; - } - } - - /** - * - */ - private static class TemplateConfigurations implements Externalizable { - /** */ - private static final long serialVersionUID = 0L; - - /** */ + @SuppressWarnings("ExternalizableWithoutPublicNoArgConstructor") + private class DynamicCacheStartFuture extends GridFutureAdapter<Object> { + /** Start ID. */ @GridToStringInclude - private List<CacheConfiguration> exactNameCfgs; + private IgniteUuid deploymentId; - /** */ - @GridToStringInclude - private List<CacheConfiguration> wildcardNameCfgs; + /** Cache name. */ + private String cacheName; - /** - * - */ - public TemplateConfigurations() { - // No-op. - } + /** Change request. */ + @GridToStringInclude + private DynamicCacheChangeRequest req; /** - * Checks if need to add new templates. - * - * @param cfgs Templates to add. - * @return Templates which should be added. + * @param cacheName Cache name. + * @param deploymentId Deployment ID. + * @param req Cache start request. */ - @Nullable Collection<CacheConfiguration> needAdd(Collection<CacheConfiguration> cfgs) { - Collection<CacheConfiguration> res = null; - - for (CacheConfiguration cfg : cfgs) { - boolean found = false; - - if (cfg.getName() != null && cfg.getName().endsWith("*")) { - String name0 = cfg.getName().substring(0, cfg.getName().length() - 1); - - if (wildcardNameCfgs != null) { - for (CacheConfiguration cfg0 : wildcardNameCfgs) { - if (F.eq(cfg0.getName(), name0)) { - found = true; - - break; - } - } - } - } - else { - if (exactNameCfgs != null) { - for (CacheConfiguration cfg0 : exactNameCfgs) { - if (F.eq(cfg0.getName(), cfg.getName())) { - found = true; - - break; - } - } - } - } - - if (!found) { - if (res == null) - res = new ArrayList<>(); - - System.out.println(Thread.currentThread().getName() + " need add: " + cfg + " " + exactNameCfgs); - - - res.add(cfg); - } - } - - return res; + private DynamicCacheStartFuture(String cacheName, IgniteUuid deploymentId, DynamicCacheChangeRequest req) { + this.deploymentId = deploymentId; + this.cacheName = cacheName; + this.req = req; } /** - * @param cfgs Configurations to add. + * @return Start ID. */ - void add(Collection<CacheConfiguration> cfgs) { - for (CacheConfiguration cfg : cfgs) { - CacheConfiguration template = new CacheConfiguration(cfg); - - if (cfg.getName() != null && cfg.getName().endsWith("*")) { - template.setName(cfg.getName().substring(0, cfg.getName().length() - 1)); - - boolean found = false; - - if (wildcardNameCfgs != null) { - for (CacheConfiguration cfg0 : wildcardNameCfgs) { - if (F.eq(cfg0.getName(), template.getName())) { - found = true; - - break; - } - } - } - else - wildcardNameCfgs = new ArrayList<>(cfgs.size()); - - if (!found) - wildcardNameCfgs.add(template); - } - else { - boolean found = false; - - if (exactNameCfgs != null) { - for (CacheConfiguration cfg0 : exactNameCfgs) { - if (F.eq(cfg0.getName(), template.getName())) { - found = true; - - break; - } - } - } - else - exactNameCfgs = new ArrayList<>(cfgs.size()); - - if (!found) - exactNameCfgs.add(template); - } - } - - if (wildcardNameCfgs != null) { - Collections.sort(wildcardNameCfgs, new Comparator<CacheConfiguration>() { - @Override public int compare(CacheConfiguration cfg1, CacheConfiguration cfg2) { - Integer len1 = cfg1.getName() != null ? cfg1.getName().length() : 0; - Integer len2 = cfg2.getName() != null ? cfg2.getName().length() : 0; - - return len2.compareTo(len1); - } - }); - } + public IgniteUuid deploymentId() { + return deploymentId; } /** - * @param name Cache name. - * @return Cache configuration for given name or {@code null} if template not found. + * @return Request. */ - @Nullable CacheConfiguration configuration(String name) { - CacheConfiguration dfltCfg = null; - - if (exactNameCfgs != null) { - for (CacheConfiguration cfg : exactNameCfgs) { - if (F.eq(name, cfg.getName())) - return cfg; - else if (cfg.getName() == null) - dfltCfg = cfg; - } - } - - if (wildcardNameCfgs != null && name != null) { - for (CacheConfiguration cfg : wildcardNameCfgs) { - if (name.startsWith(cfg.getName())) - return cfg; - } - } - - return dfltCfg; + public DynamicCacheChangeRequest request() { + return req; } /** {@inheritDoc} */ - @Override public void writeExternal(ObjectOutput out) throws IOException { - U.writeCollection(out, exactNameCfgs); - U.writeCollection(out, wildcardNameCfgs); - } + @Override public boolean onDone(@Nullable Object res, @Nullable Throwable err) { + // Make sure to remove future before completion. + pendingFuts.remove(maskNull(cacheName), this); - /** {@inheritDoc} */ - @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { - exactNameCfgs = U.readList(in); - wildcardNameCfgs = U.readList(in); + return super.onDone(res, err); } /** {@inheritDoc} */ @Override public String toString() { - return S.toString(TemplateConfigurations.class, this); + return S.toString(DynamicCacheStartFuture.class, this); } } @@ -2933,7 +2884,7 @@ public class GridCacheProcessor extends GridProcessorAdapter { * */ @SuppressWarnings("ExternalizableWithoutPublicNoArgConstructor") - private class DynamicCacheStartFuture extends GridFutureAdapter<Object> { + private class TemplateConfigurationFuture extends GridFutureAdapter<Object> { /** Start ID. */ @GridToStringInclude private IgniteUuid deploymentId; @@ -2941,19 +2892,13 @@ public class GridCacheProcessor extends GridProcessorAdapter { /** Cache name. */ private String cacheName; - /** Change request. */ - @GridToStringInclude - private DynamicCacheChangeRequest req; - /** * @param cacheName Cache name. * @param deploymentId Deployment ID. - * @param req Cache start request. */ - private DynamicCacheStartFuture(String cacheName, IgniteUuid deploymentId, DynamicCacheChangeRequest req) { + private TemplateConfigurationFuture(String cacheName, IgniteUuid deploymentId) { this.deploymentId = deploymentId; this.cacheName = cacheName; - this.req = req; } /** @@ -2963,24 +2908,17 @@ public class GridCacheProcessor extends GridProcessorAdapter { return deploymentId; } - /** - * @return Request. - */ - public DynamicCacheChangeRequest request() { - return req; - } - /** {@inheritDoc} */ @Override public boolean onDone(@Nullable Object res, @Nullable Throwable err) { // Make sure to remove future before completion. - pendingFuts.remove(maskNull(cacheName), this); + pendingTemplateFuts.remove(maskNull(cacheName), this); return super.onDone(res, err); } /** {@inheritDoc} */ @Override public String toString() { - return S.toString(DynamicCacheStartFuture.class, this); + return S.toString(TemplateConfigurationFuture.class, this); } } http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/5832b3a9/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java index ddf0df1..f6a0763 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java @@ -679,6 +679,7 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT /** * Starts dynamic caches. + * @throws IgniteCheckedException If failed. */ private void startCaches() throws IgniteCheckedException { cctx.cache().prepareCachesStart(F.view(reqs, new IgnitePredicate<DynamicCacheChangeRequest>() { http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/5832b3a9/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheConfigurationTemplateTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheConfigurationTemplateTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheConfigurationTemplateTest.java index c32d54b..9dfa913 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheConfigurationTemplateTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheConfigurationTemplateTest.java @@ -26,6 +26,7 @@ import org.apache.ignite.testframework.*; import org.apache.ignite.testframework.junits.common.*; import java.util.concurrent.*; +import java.util.concurrent.atomic.*; import static org.apache.ignite.cache.CacheAtomicityMode.*; @@ -163,6 +164,19 @@ public class IgniteCacheConfigurationTemplateTest extends GridCommonAbstractTest checkGetOrCreate(ignite1, "org.apache.ignite", 6); checkGetOrCreate(ignite2, "org.apache.ignite", 6); checkGetOrCreate(ignite3, "org.apache.ignite", 6); + + // Test name '*'. + CacheConfiguration template3 = new CacheConfiguration(); + + template3.setName("*"); + template3.setBackups(7); + + ignite1.addCacheConfiguration(template3); + + checkGetOrCreate(ignite0, "x", 7); + checkGetOrCreate(ignite1, "x", 7); + checkGetOrCreate(ignite2, "x", 7); + checkGetOrCreate(ignite3, "x", 7); } /** @@ -192,6 +206,53 @@ public class IgniteCacheConfigurationTemplateTest extends GridCommonAbstractTest } /** + * @throws Exception If failed. + */ + public void testAddCacheConfigurationMultinode() throws Exception { + addTemplate = true; + + final int GRID_CNT = 3; + + startGridsMultiThreaded(GRID_CNT); + + for (int i = 0; i < 10; i++) { + log.info("Iteration: " + i); + + final AtomicInteger idx = new AtomicInteger(); + + final int iter = i; + + GridTestUtils.runMultiThreaded(new Callable<Void>() { + @Override public Void call() throws Exception { + int node = idx.getAndIncrement() % GRID_CNT; + + Ignite ignite = grid(node); + + log.info("Add configuration using node: " + ignite.name()); + + CacheConfiguration cfg = new CacheConfiguration(); + + cfg.setName("org.apache.ignite" + iter + "*"); + + cfg.setBackups(iter); + + for (int i = 0; i < 100; i++) + ignite.addCacheConfiguration(cfg); + + return null; + } + }, 15, "add-configuration"); + + for (int grid = 0; grid < GRID_CNT; grid++) + checkGetOrCreate(grid(grid), "org.apache.ignite" + iter, iter); + } + + Ignite ignite = startGrid(GRID_CNT); + + checkGetOrCreate(ignite, "org.apache.ignite3", 3); + } + + /** * @param ignite Ignite. * @param name Cache name. * @param expBackups Expected number of backups.