/* * 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.util.HashMap; import java.util.Map; import java.util.UUID; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.configuration.CacheConfiguration; import org.apache.ignite.internal.GridKernalContext; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; import org.apache.ignite.internal.processors.cacheobject.IgniteCacheObjectProcessor; import org.apache.ignite.internal.processors.plugin.CachePluginManager; import org.apache.ignite.internal.processors.query.QuerySchema; import org.apache.ignite.internal.processors.query.schema.message.SchemaFinishDiscoveryMessage; import org.apache.ignite.internal.util.tostring.GridToStringExclude; import org.apache.ignite.internal.util.typedef.internal.CU; import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.lang.IgniteUuid; import org.jetbrains.annotations.Nullable; /** * Cache start descriptor. */ public class DynamicCacheDescriptor { /** Cache start ID. */ private IgniteUuid deploymentId; /** Cache configuration. */ @GridToStringExclude private CacheConfiguration cacheCfg; /** Locally configured flag. */ private boolean locCfg; /** Statically configured flag. */ private boolean staticCfg; /** Started flag. */ private boolean started; /** Cache type. */ private CacheType cacheType; /** */ private volatile Map<UUID, CacheConfiguration> rmtCfgs; /** Template configuration flag. */ private boolean template; /** Cache plugin manager. */ private final CachePluginManager pluginMgr; /** */ private boolean updatesAllowed = true; /** */ private AffinityTopologyVersion startTopVer; /** */ private boolean rcvdOnDiscovery; /** */ private Integer cacheId; /** */ private UUID rcvdFrom; /** */ private AffinityTopologyVersion rcvdFromVer; /** Mutex. */ private final Object mux = new Object(); /** Cached object context for marshalling issues when cache isn't started. */ private volatile CacheObjectContext objCtx; /** */ private transient AffinityTopologyVersion clientCacheStartVer; /** Mutex to control schema. */ private final Object schemaMux = new Object(); /** Current schema. */ private QuerySchema schema; /** * @param ctx Context. * @param cacheCfg Cache configuration. * @param cacheType Cache type. * @param template {@code True} if this is template configuration. * @param deploymentId Deployment ID. */ @SuppressWarnings("unchecked") public DynamicCacheDescriptor(GridKernalContext ctx, CacheConfiguration cacheCfg, CacheType cacheType, boolean template, IgniteUuid deploymentId, QuerySchema schema) { assert cacheCfg != null; assert schema != null; this.cacheCfg = cacheCfg; this.cacheType = cacheType; this.template = template; this.deploymentId = deploymentId; pluginMgr = new CachePluginManager(ctx, cacheCfg); cacheId = CU.cacheId(cacheCfg.getName()); synchronized (schemaMux) { this.schema = schema.copy(); } } /** * @return Cache ID. */ public Integer cacheId() { return cacheId; } /** * @return Start topology version. */ @Nullable public AffinityTopologyVersion startTopologyVersion() { return startTopVer; } /** * @param startTopVer Start topology version. */ public void startTopologyVersion(AffinityTopologyVersion startTopVer) { this.startTopVer = startTopVer; } /** * @return {@code True} if this is template configuration. */ public boolean template() { return template; } /** * @return Cache type. */ public CacheType cacheType() { return cacheType; } /** * @return Start ID. */ public IgniteUuid deploymentId() { return deploymentId; } /** * @param deploymentId Deployment ID. */ public void deploymentId(IgniteUuid deploymentId) { this.deploymentId = deploymentId; } /** * @return Locally configured flag. */ public boolean locallyConfigured() { return locCfg; } /** * @param locCfg Locally configured flag. */ public void locallyConfigured(boolean locCfg) { this.locCfg = locCfg; } /** * @return {@code True} if statically configured. */ public boolean staticallyConfigured() { return staticCfg; } /** * @param staticCfg {@code True} if statically configured. */ public void staticallyConfigured(boolean staticCfg) { this.staticCfg = staticCfg; } /** * @return {@code True} if started flag was flipped by this call. */ public boolean onStart() { if (!started) { started = true; return true; } return false; } /** * @return Started flag. */ public boolean started() { return started; } /** * @return Cache configuration. */ public CacheConfiguration cacheConfiguration() { return cacheCfg; } /** * Creates and caches cache object context if needed. * * @param proc Object processor. */ public CacheObjectContext cacheObjectContext(IgniteCacheObjectProcessor proc) throws IgniteCheckedException { if (objCtx == null) { synchronized (mux) { if (objCtx == null) objCtx = proc.contextForCache(cacheCfg); } } return objCtx; } /** * @return Cache plugin manager. */ public CachePluginManager pluginManager() { return pluginMgr; } /** * @param nodeId Remote node ID. * @return Configuration. */ public CacheConfiguration remoteConfiguration(UUID nodeId) { Map<UUID, CacheConfiguration> cfgs = rmtCfgs; return cfgs == null ? null : cfgs.get(nodeId); } /** * @param nodeId Remote node ID. * @param cfg Remote node configuration. */ public void addRemoteConfiguration(UUID nodeId, CacheConfiguration cfg) { Map<UUID, CacheConfiguration> cfgs = rmtCfgs; if (cfgs == null) rmtCfgs = cfgs = new HashMap<>(); cfgs.put(nodeId, cfg); } /** * */ public void clearRemoteConfigurations() { rmtCfgs = null; } /** * @return Updates allowed flag. */ public boolean updatesAllowed() { return updatesAllowed; } /** * @param updatesAllowed Updates allowed flag. */ public void updatesAllowed(boolean updatesAllowed) { this.updatesAllowed = updatesAllowed; } /** * @return {@code True} if received in discovery data. */ public boolean receivedOnDiscovery() { return rcvdOnDiscovery; } /** * @param rcvdOnDiscovery {@code True} if received in discovery data. */ public void receivedOnDiscovery(boolean rcvdOnDiscovery) { this.rcvdOnDiscovery = rcvdOnDiscovery; } /** * @param nodeId ID of node provided cache configuration in discovery data. */ public void receivedFrom(UUID nodeId) { rcvdFrom = nodeId; } /** * @return Topology version when node provided cache configuration was started. */ @Nullable public AffinityTopologyVersion receivedFromStartVersion() { return rcvdFromVer; } /** * @param rcvdFromVer Topology version when node provided cache configuration was started. */ public void receivedFromStartVersion(AffinityTopologyVersion rcvdFromVer) { this.rcvdFromVer = rcvdFromVer; } /** * @return ID of node provided cache configuration in discovery data. */ @Nullable public UUID receivedFrom() { return rcvdFrom; } /** * @return Version when client cache on local node was started. */ @Nullable AffinityTopologyVersion clientCacheStartVersion() { return clientCacheStartVer; } /** * @param clientCacheStartVer Version when client cache on local node was started. */ public void clientCacheStartVersion(AffinityTopologyVersion clientCacheStartVer) { this.clientCacheStartVer = clientCacheStartVer; } /** * @return Schema. */ public QuerySchema schema() { synchronized (schemaMux) { return schema.copy(); } } /** * Set schema * * @param schema Schema. */ public void schema(QuerySchema schema) { assert schema != null; synchronized (schemaMux) { this.schema = schema.copy(); } } /** * Try applying finish message. * * @param msg Message. */ public void schemaChangeFinish(SchemaFinishDiscoveryMessage msg) { synchronized (schemaMux) { schema.finish(msg); } } /** {@inheritDoc} */ @Override public String toString() { return S.toString(DynamicCacheDescriptor.class, this, "cacheName", U.maskName(cacheCfg.getName())); } }