private async Task ValidateCkModel(IOspSession session, GraphRuleEngineResult graphRuleEngineResult, IReadOnlyList <EntityUpdateInfo> entityUpdateInfoList, IReadOnlyList <AssociationUpdateInfo> associationUpdateInfoList) { await ValidateOrigin(session, entityUpdateInfoList, associationUpdateInfoList); await ValidateTarget(session, entityUpdateInfoList, associationUpdateInfoList); // Ensure that all associations exists when creating an entity // Currently, the only mandatory association has multiplicity of One foreach (var entityUpdateInfo in entityUpdateInfoList.Where(x => x.ModOption == EntityModOptions.Create)) { var cacheItem = _ckCache.GetEntityCacheItem(entityUpdateInfo.RtEntity.CkId); var inboundAssociationCacheItems = cacheItem.InboundAssociations.Values.SelectMany(x => x.Where(a => a.InboundMultiplicity == Multiplicities.One)); foreach (var inboundAssociationCacheItem in inboundAssociationCacheItems) { if (!associationUpdateInfoList.Any(x => x.ModOption == AssociationModOptionsDto.Create && x.RoleId == inboundAssociationCacheItem.RoleId)) { throw new CkModelViolationException($"Inbound association '{inboundAssociationCacheItem.RoleId}' has multiplicity of 'One', but create statement is missing. Error occurred at CK type '{entityUpdateInfo.RtEntity.CkId}' (from RtId '{entityUpdateInfo.RtEntity.RtId}')."); } } } // Delete all corresponding associations if an entity is deleted foreach (var entityUpdateInfo in entityUpdateInfoList.Where(x => x.ModOption == EntityModOptions.Delete)) { var result = await _tenantRepository.GetRtAssociationsAsync(session, entityUpdateInfo.RtEntity.RtId.ToString(), GraphDirections.Any); graphRuleEngineResult.RtAssociationsToDelete.AddRange(result); } }
public async Task <GraphRuleEngineResult> ValidateAsync(IOspSession session, IReadOnlyList <EntityUpdateInfo> entityUpdateInfoList, IReadOnlyList <AssociationUpdateInfo> associationUpdateInfoList) { var graphValidationResult = new GraphRuleEngineResult(); // Validate if the associations are valid to be added/deleted based on the current database content var createAssociations = associationUpdateInfoList.Where(x => x.ModOption == AssociationModOptionsDto.Create); var deleteAssociations = associationUpdateInfoList.Where(x => x.ModOption == AssociationModOptionsDto.Delete); await ValidateAssociationsToCreate(session, createAssociations, graphValidationResult); await ValidateAssociationsToDelete(session, deleteAssociations, graphValidationResult); // Validate the consistency of the construction kit model await ValidateCkModel(session, graphValidationResult, entityUpdateInfoList, associationUpdateInfoList); return(graphValidationResult); }
private async Task ValidateAssociationsToCreate(IOspSession session, IEnumerable <AssociationUpdateInfo> createAssociations, GraphRuleEngineResult graphRuleEngineResult) { foreach (var associationUpdateInfo in createAssociations) { var origin = associationUpdateInfo.Origin; var target = associationUpdateInfo.Target; var rtAssociation = await _tenantRepository.GetRtAssociationAsync(session, origin, target, associationUpdateInfo.RoleId); if (rtAssociation != null) { throw new OperationFailedException($"Association from '{origin}' to '{target}' in role '{associationUpdateInfo.RoleId}' already exits."); } graphRuleEngineResult.RtAssociationsToCreate.Add(new RtAssociation { OriginRtId = associationUpdateInfo.Origin.RtId.ToObjectId(), OriginCkId = associationUpdateInfo.Origin.CkId, TargetRtId = associationUpdateInfo.Target.RtId.ToObjectId(), TargetCkId = associationUpdateInfo.Target.CkId, AssociationRoleId = associationUpdateInfo.RoleId }); } }
private async Task ValidateAssociationsToDelete(IOspSession session, IEnumerable <AssociationUpdateInfo> deleteAssociations, GraphRuleEngineResult graphRuleEngineResult) { foreach (var d in deleteAssociations) { var origin = d.Origin; var target = d.Target; var rtAssociation = await _tenantRepository.GetRtAssociationAsync(session, origin, target, d.RoleId); if (rtAssociation == null) { throw new OperationFailedException($"Association from '{origin}' to '{target}' in role '{d.RoleId}' does not exist"); } graphRuleEngineResult.RtAssociationsToDelete.Add(rtAssociation); } }