use of org.apache.ignite.internal.processors.query.QuerySchemaPatch in project ignite by apache.
the class ValidationOnNodeJoinUtils method validateNode.
/**
* Checks a joining node to configuration consistency.
*
* @param node Node.
* @param discoData Disco data.
* @param marsh Marsh.
* @param ctx Context.
* @param cacheDescProvider Cache descriptor provider.
*/
@Nullable
static IgniteNodeValidationResult validateNode(ClusterNode node, DiscoveryDataBag.JoiningNodeDiscoveryData discoData, Marshaller marsh, GridKernalContext ctx, Function<String, DynamicCacheDescriptor> cacheDescProvider) {
if (discoData.hasJoiningNodeData() && discoData.joiningNodeData() instanceof CacheJoinNodeDiscoveryData) {
CacheJoinNodeDiscoveryData nodeData = (CacheJoinNodeDiscoveryData) discoData.joiningNodeData();
boolean isGridActive = ctx.state().clusterState().active();
StringBuilder errorMsg = new StringBuilder();
if (!node.isClient()) {
validateRmtRegions(node, ctx).forEach(error -> {
if (errorMsg.length() > 0)
errorMsg.append("\n");
errorMsg.append(error);
});
}
SecurityContext secCtx = null;
if (ctx.security().enabled()) {
try {
secCtx = nodeSecurityContext(marsh, U.resolveClassLoader(ctx.config()), node);
} catch (SecurityException se) {
errorMsg.append(se.getMessage());
}
}
for (CacheJoinNodeDiscoveryData.CacheInfo cacheInfo : nodeData.caches().values()) {
if (secCtx != null && cacheInfo.cacheType() == CacheType.USER) {
try (OperationSecurityContext s = ctx.security().withContext(secCtx)) {
GridCacheProcessor.authorizeCacheCreate(ctx.security(), cacheInfo.cacheData().config());
} catch (SecurityException ex) {
if (errorMsg.length() > 0)
errorMsg.append("\n");
errorMsg.append(ex.getMessage());
}
}
DynamicCacheDescriptor locDesc = cacheDescProvider.apply(cacheInfo.cacheData().config().getName());
if (locDesc == null)
continue;
String joinedSchema = cacheInfo.cacheData().config().getSqlSchema();
Collection<QueryEntity> joinedQryEntities = cacheInfo.cacheData().queryEntities();
String locSchema = locDesc.cacheConfiguration().getSqlSchema();
// QuerySchema is empty and schema name is null (when indexing enabled dynamically).
if (!F.eq(joinedSchema, locSchema) && (locSchema != null || !locDesc.schema().isEmpty()) && (joinedSchema != null || !F.isEmpty(joinedQryEntities))) {
errorMsg.append(String.format(SQL_SCHEMA_CONFLICTS_MESSAGE, locDesc.cacheName(), joinedSchema, locSchema));
}
QuerySchemaPatch schemaPatch = locDesc.makeSchemaPatch(joinedQryEntities);
if (schemaPatch.hasConflicts() || (isGridActive && !schemaPatch.isEmpty())) {
if (errorMsg.length() > 0)
errorMsg.append("\n");
if (schemaPatch.hasConflicts()) {
errorMsg.append(String.format(MERGE_OF_CONFIG_CONFLICTS_MESSAGE, locDesc.cacheName(), schemaPatch.getConflictsMessage()));
} else
errorMsg.append(String.format(MERGE_OF_CONFIG_REQUIRED_MESSAGE, locDesc.cacheName()));
}
// This check must be done on join, otherwise group encryption key will be
// written to metastore regardless of validation check and could trigger WAL write failures.
boolean locEnc = locDesc.cacheConfiguration().isEncryptionEnabled();
boolean rmtEnc = cacheInfo.cacheData().config().isEncryptionEnabled();
if (locEnc != rmtEnc) {
if (errorMsg.length() > 0)
errorMsg.append("\n");
// Message will be printed on remote node, so need to swap local and remote.
errorMsg.append(String.format(ENCRYPT_MISMATCH_MESSAGE, locDesc.cacheName(), rmtEnc, locEnc));
}
}
if (errorMsg.length() > 0) {
String msg = errorMsg.toString();
return new IgniteNodeValidationResult(node.id(), msg);
}
}
return null;
}
use of org.apache.ignite.internal.processors.query.QuerySchemaPatch in project ignite by apache.
the class ClusterCachesInfo method registerReceivedCaches.
/**
* Register caches received from cluster.
*
* @param cachesData Data received from cluster.
*/
private void registerReceivedCaches(CacheNodeCommonDiscoveryData cachesData) {
Map<DynamicCacheDescriptor, QuerySchemaPatch> patchesToApply = new HashMap<>();
Collection<DynamicCacheDescriptor> cachesToSave = new HashSet<>();
boolean hasSchemaPatchConflict = false;
for (CacheData cacheData : cachesData.caches().values()) {
CacheGroupDescriptor grpDesc = registeredCacheGrps.get(cacheData.groupId());
assert grpDesc != null : cacheData.cacheConfiguration().getName();
CacheConfiguration<?, ?> cfg = cacheData.cacheConfiguration();
DynamicCacheDescriptor desc = new DynamicCacheDescriptor(ctx, cacheData.cacheConfiguration(), cacheData.cacheType(), grpDesc, false, cacheData.receivedFrom(), cacheData.staticallyConfigured(), cacheData.sql(), cacheData.deploymentId(), new QuerySchema(cacheData.schema().entities()), cacheData.cacheConfigurationEnrichment());
Collection<QueryEntity> localQueryEntities = getLocalQueryEntities(cfg.getName());
QuerySchemaPatch schemaPatch = desc.makeSchemaPatch(localQueryEntities);
if (schemaPatch.hasConflicts()) {
hasSchemaPatchConflict = true;
log.warning("Skipping apply patch because conflicts : " + schemaPatch.getConflictsMessage());
} else if (!schemaPatch.isEmpty())
patchesToApply.put(desc, schemaPatch);
else if (!GridFunc.eqNotOrdered(desc.schema().entities(), localQueryEntities))
// received config is different of local config - need to resave
cachesToSave.add(desc);
desc.receivedOnDiscovery(true);
registeredCaches.put(cacheData.cacheConfiguration().getName(), desc);
registeredCachesById.put(desc.cacheId(), desc);
ctx.discovery().setCacheFilter(desc.cacheId(), grpDesc.groupId(), cfg.getName(), cfg.getNearConfiguration() != null);
}
updateRegisteredCachesIfNeeded(patchesToApply, cachesToSave, hasSchemaPatchConflict);
}
use of org.apache.ignite.internal.processors.query.QuerySchemaPatch in project ignite by apache.
the class GridCacheProcessor method prepareCacheContext.
/**
* Preparing cache context to start.
*
* @param desc Cache descriptor.
* @param reqNearCfg Near configuration if specified for client cache start request.
* @param exchTopVer Current exchange version.
* @param disabledAfterStart If true, then we will discard restarting state from proxies. If false then we will change
* state of proxies to restarting
* @return Created {@link GridCacheContext}.
* @throws IgniteCheckedException if failed.
*/
private GridCacheContext prepareCacheContext(DynamicCacheDescriptor desc, @Nullable NearCacheConfiguration reqNearCfg, AffinityTopologyVersion exchTopVer, boolean disabledAfterStart) throws IgniteCheckedException {
desc = enricher().enrich(desc, desc.cacheConfiguration().getCacheMode() == LOCAL || isLocalAffinity(desc.cacheConfiguration()));
CacheConfiguration startCfg = desc.cacheConfiguration();
if (caches.containsKey(startCfg.getName())) {
GridCacheAdapter<?, ?> existingCache = caches.get(startCfg.getName());
GridCacheContext<?, ?> cctx = existingCache.context();
assert cctx.isRecoveryMode();
QuerySchema localSchema = recovery.querySchemas.get(desc.cacheId());
QuerySchemaPatch localSchemaPatch = localSchema.makePatch(desc.schema().entities());
// Cache schema is changed after restart, workaround is stop existing cache and start new.
if (!localSchemaPatch.isEmpty() || localSchemaPatch.hasConflicts())
stopCacheSafely(cctx);
else
return existingCache.context();
}
assert !caches.containsKey(startCfg.getName()) : startCfg.getName();
CacheConfiguration ccfg = new CacheConfiguration(startCfg);
CacheObjectContext cacheObjCtx = ctx.cacheObjects().contextForCache(ccfg);
boolean affNode = checkForAffinityNode(desc, reqNearCfg, ccfg);
ctx.cache().context().database().checkpointReadLock();
try {
CacheGroupContext grp = getOrCreateCacheGroupContext(desc, exchTopVer, cacheObjCtx, affNode, startCfg.getGroupName(), false);
GridCacheContext cacheCtx = createCacheContext(ccfg, grp, null, desc, exchTopVer, cacheObjCtx, affNode, true, disabledAfterStart, false);
initCacheContext(cacheCtx, ccfg);
return cacheCtx;
} finally {
ctx.cache().context().database().checkpointReadUnlock();
}
}
Aggregations