public void IndexLinkedResource(Uri pidUri, Entity resource, ResourcesCTO repoResources)
        {
            // TODO: Repos resources
            var resourceIndex = new ResourceIndexingDTO(ResourceCrudAction.Linking, pidUri, resource, repoResources);

            IndexResource(resourceIndex);
        }
        public async void CreateResource_Success_WithPreviousVersion()
        {
            // Arrange
            var requestBuilder = new ResourceBuilder()
                                 .GenerateSampleData();

            var request  = requestBuilder.BuildRequestDto();
            var resource = requestBuilder.Build();

            request.HasPreviousVersion = Graph.Metadata.Constants.Entity.IdPrefix + Guid.NewGuid();

            var resourceCto      = new ResourcesCTO(null, null);
            var validationFacade = new EntityValidationFacade(ResourceCrudAction.Create, resource, resourceCto, request.HasPreviousVersion, _metadata, null);

            var preProcessServiceResult = Task.FromResult(new Tuple <ValidationResult, bool, EntityValidationFacade>(null, false, validationFacade));

            _mockPreProcessService.Setup(t => t.ValidateAndPreProcessResource(It.IsAny <string>(), request, It.IsAny <ResourcesCTO>(), ResourceCrudAction.Create, It.IsAny <bool>(), It.IsAny <string>())).Returns(preProcessServiceResult);

            // Act
            var result = await _service.CreateResource(request);

            // Assert
            Assert.NotNull(result);
            _mockResourceRepo.Verify(t => t.Create(validationFacade.RequestResource, It.IsAny <IList <MetadataProperty> >()), Times.Once);
            _mockResourceLinkingService.Verify(t => t.LinkResourceIntoList(validationFacade.RequestResource.PidUri, It.IsAny <Uri>()), Times.Once);
        }
        public void IndexUnlinkedResource(Uri pidUri, ResourcesCTO resource, Uri unlinkedPidUri, ResourcesCTO unlinkedListResource)
        {
            var resourceIndex = new ResourceIndexingDTO(ResourceCrudAction.Unlinking, pidUri, resource.GetDraftOrPublishedVersion(), resource);

            IndexResource(resourceIndex);

            IndexLinkedResource(unlinkedPidUri, unlinkedListResource.GetDraftOrPublishedVersion(), unlinkedListResource);
        }
        public void IndexNewResource(Uri pidUri, Resource resource, IList <VersionOverviewCTO> resourceVersions)
        {
            var repoResource = new ResourcesCTO(null, null, resourceVersions);

            var resourceIndex = new ResourceIndexingDTO(ResourceCrudAction.Create, pidUri, resource, repoResource);

            IndexResource(resourceIndex);
        }
        /// <summary>
        /// There is an id for the endpoint, but a new id must be assigned to the endpoint if a draft is created from a published entry.
        /// However, the process must be performed as an update to ensure that certain properties such as identifiers are inherited from the published entry.
        /// This does not apply to attachments.
        /// </summary>
        /// <param name="key">The property key of the sub entity.</param>
        /// <param name="subEntity">The sub entity.</param>
        /// <param name="mainResource">The resource, where the sub entity belongs to.</param>
        /// <returns>The entity id of the nested entity. Empty, if the subproperty should be saved as a copy with a new id.</returns>
        private string GetNestedEntityId(string key, Entity subEntity, ResourcesCTO mainResource)
        {
            /* if(key != Graph.Metadata.Constants.AttachmentConstants.HasAttachment && mainResource.HasPublishedAndNoDraft)
             * {
             *   return string.Empty;
             * }*/

            return(subEntity.Id);
        }
        public async void PublishResource_Should_ThrowError_Exception_AlreadyPublished()
        {
            // Arrange
            var resource    = new ResourceBuilder().GenerateSampleData().Build();
            var resourceCto = new ResourcesCTO(null, resource);

            _mockResourceRepo.Setup(s => s.GetResourcesByPidUri(resource.PidUri, It.IsAny <IList <string> >())).Returns(resourceCto);

            // Act
            await Assert.ThrowsAsync <BusinessException>(() => _service.PublishResource(resource.PidUri));
        }
Esempio n. 7
0
 public EntityValidationFacade(ResourceCrudAction resourceCrucAction,
                               Resource requestResource,
                               ResourcesCTO resourcesCTO,
                               string previousVersion,
                               IList <MetadataProperty> metadataProperties,
                               string consumerGroup)
 {
     ResourceCrudAction = resourceCrucAction;
     RequestResource    = requestResource;
     ResourcesCTO       = resourcesCTO;
     PreviousVersion    = previousVersion;
     MetadataProperties = metadataProperties;
     ConsumerGroup      = consumerGroup;
     ValidationResults  = new List <ValidationResultProperty>();
 }
        public async void EditResource_Success()
        {
            // Arrange
            var requestBuilder = new ResourceBuilder()
                                 .GenerateSampleData();

            var request = requestBuilder.BuildRequestDto();

            var resource    = requestBuilder.Build();
            var publishedId = Graph.Metadata.Constants.Entity.IdPrefix + Guid.NewGuid();

            resource.Id = publishedId;

            var resourceCto = new ResourcesCTO(null, resource);

            _mockResourceRepo.Setup(s => s.GetResourcesByPidUri(resource.PidUri, It.IsAny <IList <string> >())).Returns(resourceCto);

            var validationFacade        = new EntityValidationFacade(ResourceCrudAction.Create, resource, resourceCto, request.HasPreviousVersion, _metadata, null);
            var validationResult        = new ValidationResult();
            var preProcessServiceResult = new Tuple <ValidationResult, bool, EntityValidationFacade>(validationResult, false, validationFacade);

            var newResourceId = string.Empty;

            _mockPreProcessService.Setup(t => t.ValidateAndPreProcessResource(It.IsAny <string>(), request, It.IsAny <ResourcesCTO>(), ResourceCrudAction.Update, It.IsAny <bool>(), It.IsAny <string>()))
            .ReturnsAsync(preProcessServiceResult)
            .Callback <string, ResourceRequestDTO, ResourcesCTO, ResourceCrudAction, bool, string>((a, b, c, d, e, f) =>
            {
                newResourceId = a;
                validationResult.Results.Add(new ValidationResultProperty(a, "some path", "some value", "some message", ValidationResultSeverity.Warning));
            });

            // Act
            var result = await _service.EditResource(resource.PidUri, request);

            // Assert
            Assert.All(result.ValidationResult.Results, t =>
            {
                Assert.Equal(t.Node, newResourceId);
            });

            _mockResourceRepo.Verify(s => s.DeleteDraft(result.Resource.PidUri, new Uri(result.Resource.Id)), Times.Once);
            _mockResourceRepo.Verify(s => s.Create(resource, _metadata), Times.Once);
            _mockResourceRepo.Verify(s => s.CreateLinkingProperty(resource.PidUri, new Uri(
                                                                      Graph.Metadata.Constants.Resource.HasPidEntryDraft),
                                                                  Graph.Metadata.Constants.Resource.ColidEntryLifecycleStatus.Published,
                                                                  Graph.Metadata.Constants.Resource.ColidEntryLifecycleStatus.Draft), Times.Once);
            _mockIdentifierService.Verify(s => s.DeleteAllUnpublishedIdentifiers(It.IsAny <Entity>()), Times.Never);
        }
Esempio n. 9
0
        public void HandleOverwriteProperties_Success()
        {
            // Arrange
            var propertyKey = Graph.Metadata.Constants.RDF.Type;

            var requestResource = CreateResourceWithType(Graph.Metadata.Constants.Resource.Type.GenericDataset);
            var repoResource    = CreateResourceWithType(Graph.Metadata.Constants.Resource.Type.Ontology);
            var resourcesCTO    = new ResourcesCTO(repoResource, repoResource, new List <VersionOverviewCTO>());

            var entityValidationFacade = new EntityValidationFacade(ResourceCrudAction.Update, requestResource, resourcesCTO, string.Empty, _metadata, string.Empty);

            // Act
            _validator.Validate(propertyKey, entityValidationFacade);

            // Assert
            var resourceType = entityValidationFacade.RequestResource.Properties[Graph.Metadata.Constants.RDF.Type];

            Assert.All(resourceType, t => Assert.Equal(Graph.Metadata.Constants.Resource.Type.Ontology, t));
        }
Esempio n. 10
0
        public void InternalHasValidationResult_Success_ReplaceAuthorWithEmailOnUpdate()
        {
            // Arrange
            _mockUserInfoService.Setup(mock => mock.GetRoles()).Returns(new List <string>());
            Resource     newResource     = CreateResourceWithAuthor("*****@*****.**");
            Resource     repoResource    = CreateResourceWithAuthor("*****@*****.**");
            ResourcesCTO repoResourceCTO = new ResourcesCTO()
            {
                Draft = repoResource, Published = repoResource
            };

            EntityValidationFacade validationFacade = new EntityValidationFacade(ResourceCrudAction.Update, newResource, repoResourceCTO, null, _metadata, null);

            // Act
            _validator.HasValidationResult(validationFacade, GetAuthorProperty(newResource));

            // Assert
            AssertValidationFacade(validationFacade, "*****@*****.**");
        }
Esempio n. 11
0
        public void InternalHasValidationResult_OverwritePropertyWithRepoDateTime()
        {
            // Arrange
            var repoDate     = DateTime.UtcNow.AddDays(-1);
            var repoResource = CreateResource(repoDate);
            var resourceCto  = new ResourcesCTO(repoResource, null);
            var resource     = CreateResource(DateTime.UtcNow);

            EntityValidationFacade validationFacade = new EntityValidationFacade(ResourceCrudAction.Update, resource, resourceCto, null, _metadata, null);

            // Act
            _validator.HasValidationResult(validationFacade, GetDateTimeProperty(resource));

            // Assert
            Assert.Contains(Graph.Metadata.Constants.Resource.DateCreated, validationFacade.RequestResource.Properties);
            var dateCreatedList = GetDateTimeProperty(validationFacade.RequestResource).Value;

            Assert.All(dateCreatedList, t =>
            {
                Assert.Equal(repoDate.ToString("o"), t);
            });
        }
        public async void EditResource__Should_ThrowError_ResourceValidation()
        {
            // Arrange
            var requestBuilder = new ResourceBuilder()
                                 .GenerateSampleData();

            var request = requestBuilder.BuildRequestDto();

            var resource    = requestBuilder.Build();
            var publishedId = Graph.Metadata.Constants.Entity.IdPrefix + Guid.NewGuid();

            resource.Id = publishedId;

            var resourceCto = new ResourcesCTO(null, resource);

            _mockResourceRepo.Setup(s => s.GetResourcesByPidUri(resource.PidUri, It.IsAny <IList <string> >())).Returns(resourceCto);

            var validationFacade        = new EntityValidationFacade(ResourceCrudAction.Create, resource, resourceCto, request.HasPreviousVersion, _metadata, null);
            var validationResult        = new ValidationResult();
            var preProcessServiceResult = new Tuple <ValidationResult, bool, EntityValidationFacade>(validationResult, true, validationFacade);

            var newResourceId = string.Empty;

            _mockPreProcessService.Setup(t => t.ValidateAndPreProcessResource(It.IsAny <string>(), request, It.IsAny <ResourcesCTO>(), ResourceCrudAction.Update, It.IsAny <bool>(), It.IsAny <string>()))
            .ReturnsAsync(preProcessServiceResult)
            .Callback <string, ResourceRequestDTO, ResourcesCTO, ResourceCrudAction, bool, string>((a, b, c, d, e, f) =>
            {
                newResourceId = a;
                validationResult.Results.Add(new ValidationResultProperty(a, "some path", "some value", "some message", ValidationResultSeverity.Warning));
            });

            // Act
            var result = await Assert.ThrowsAsync <ResourceValidationException>(() => _service.EditResource(resource.PidUri, request));

            // Assert
            _mockResourceRepo.Verify(s => s.CreateTransaction(), Times.Never);
            Assert.All(result.ValidationResult.Results, t => Assert.Equal(t.Node, publishedId));
        }
Esempio n. 13
0
        public void InternalHasValidationResult_OverwritePropertyWithNewDateTime()
        {
            // Arrange
            var resourceDateCreated = DateTime.UtcNow.AddDays(-1);
            var resource            = CreateResource(resourceDateCreated);
            var resourceCto         = new ResourcesCTO(resource, null, new List <VersionOverviewCTO>());
            var new_resource        = CreateResource(DateTime.UtcNow);

            EntityValidationFacade validationFacade = new EntityValidationFacade(ResourceCrudAction.Update, new_resource, resourceCto, null, _metadata, null);

            // Act
            _validator.HasValidationResult(validationFacade, GetDateTimeProperty(new_resource));

            // Assert
            Assert.Contains(Graph.Metadata.Constants.Resource.DateCreated, validationFacade.RequestResource.Properties);
            var dateCreatedList = GetDateTimeProperty(validationFacade.RequestResource).Value;

            Assert.All(dateCreatedList, t =>
            {
                DateTime dateCreated = Convert.ToDateTime(t);
                Assert.Equal(1, dateCreated.CompareTo(resourceDateCreated));
            });
        }
        public ResourcesCTO GetResourcesByPidUri(Uri pidUri, IList <string> resourceTypes)
        {
            SparqlParameterizedString parameterizedString = new SparqlParameterizedString
            {
                CommandText =
                    @"SELECT DISTINCT ?subject ?object ?predicate ?object_ ?publishedVersion ?objectPidUri ?inbound ?inboundPredicate ?inboundPidUri
                  @fromResourceNamedGraph
                  WHERE { {
                     ?subject @hasPid @pidUri.
                     BIND(?subject as ?object).
                     ?subject ?predicate ?object_.
                     OPTIONAL { ?publishedVersion @hasPidEntryDraft ?subject }
                     OPTIONAL { ?object_ @hasPid ?objectPidUri. }
                  } UNION {
                    ?subject @hasPid @pidUri.
                    ?subject (rdf:| !rdf:)+ ?object.
                    ?object rdf:type ?objectType.
                    FILTER (?objectType NOT IN ( @resourceTypes ) )
                    ?object ?predicate ?object_.
                    }
                    UNION {
                    ?subject @hasPid @pidUri.
                    ?object ?inboundPredicate ?subject.
                    ?object @hasPid ?inboundPidUri.
                    BIND(@true as ?inbound).
                    Filter NOT EXISTS { ?draftResource @hasPidEntryDraft ?object}
                    }
                    }"
            };

            parameterizedString.SetPlainLiteral("fromResourceNamedGraph", _metadataGraphConfigurationRepository.GetGraphs(QueryGraphs).JoinAsFromNamedGraphs());
            parameterizedString.SetUri("hasPid", new Uri(Graph.Metadata.Constants.EnterpriseCore.PidUri));
            parameterizedString.SetUri("pidUri", pidUri);
            parameterizedString.SetUri("hasPidEntryDraft", new Uri(Graph.Metadata.Constants.Resource.HasPidEntryDraft));
            parameterizedString.SetPlainLiteral("resourceTypes", resourceTypes.JoinAsGraphsList());
            parameterizedString.SetLiteral("true", Graph.Metadata.Constants.Boolean.True);

            var resources = BuildResourceFromQuery(parameterizedString, pidUri);

            var resourceDraft = resources.FirstOrDefault(r =>
                                                         r.Properties.GetValueOrNull(Graph.Metadata.Constants.Resource.HasEntryLifecycleStatus, true) == Graph.Metadata.Constants.Resource.ColidEntryLifecycleStatus.Draft); // firstResource
            var resourcePublished = resources.FirstOrDefault(r =>
            {
                var lifecycleStatus =
                    r.Properties.GetValueOrNull(Graph.Metadata.Constants.Resource.HasEntryLifecycleStatus, true);

                return(lifecycleStatus == Graph.Metadata.Constants.Resource.ColidEntryLifecycleStatus.Published ||
                       lifecycleStatus == Graph.Metadata.Constants.Resource.ColidEntryLifecycleStatus.MarkedForDeletion);
            });

            IList <VersionOverviewCTO> versions = new List <VersionOverviewCTO>();

            if (resourceDraft != null || resourcePublished != null)
            {
                versions = resourceDraft == null ? resourcePublished.Versions : resourceDraft.Versions;
            }

            ResourcesCTO resourcesCTO = new ResourcesCTO(resourceDraft, resourcePublished, versions);

            return(resourcesCTO);
        }
        /// <summary>
        /// Validates all linked entities that are not of type permanent identifier.
        /// </summary>
        /// <param name="property"></param>
        /// <param name="validationFacade"></param>
        /// <returns></returns>
        private async Task ValidateEndpoint(KeyValuePair <string, List <dynamic> > property, EntityValidationFacade validationFacade)
        {
            var key = property.Key;

            // TODO: Check for types permanent identifier
            if (key != Graph.Metadata.Constants.EnterpriseCore.PidUri && key != Graph.Metadata.Constants.Resource.BaseUri)
            {
                var newPropertyValue = new List <dynamic>();
                var tasks            = await Task.WhenAll(validationFacade.RequestResource.Properties[key].Select(async propertyValue =>
                {
                    if (!DynamicExtension.IsType <Entity>(propertyValue, out Entity parsedValue))
                    {
                        return(propertyValue);
                    }

                    var subEntityCrudAction = ResourceCrudAction.Create;
                    Entity repoEntity       = null;

                    // Only if something is updating, we can check if there is a related distribution endpoint
                    if (validationFacade.ResourceCrudAction != ResourceCrudAction.Create)
                    {
                        var repoResource = validationFacade.ResourcesCTO.GetDraftOrPublishedVersion();

                        // Try to get the distribution endpoint
                        foreach (var repoProperty in repoResource.Properties)
                        {
                            foreach (var repoPropertyValue in repoProperty.Value)
                            {
                                if (!DynamicExtension.IsType <Entity>(repoPropertyValue, out Entity parsedRepoValue) ||
                                    parsedRepoValue.Id != parsedValue.Id)
                                {
                                    continue;
                                }

                                repoEntity          = parsedRepoValue;
                                subEntityCrudAction = ResourceCrudAction.Update;
                            }
                        }
                    }

                    var entityRequest = new ResourceRequestDTO()
                    {
                        Properties = parsedValue.Properties
                    };
                    var entitiesCTO = new ResourcesCTO()
                    {
                        Draft = repoEntity, Published = repoEntity
                    };
                    var entityId = GetNestedEntityId(key, parsedValue, validationFacade.ResourcesCTO);

                    // The consumer group of the parent must be included in the process.
                    Tuple <ValidationResult, bool, EntityValidationFacade> subResult = await ValidateAndPreProcessResource(entityId, entityRequest, entitiesCTO, subEntityCrudAction, true, validationFacade.ConsumerGroup);

                    // Add validationResults to resource results
                    validationFacade.ValidationResults.AddRange(subResult.Item1.Results);

                    return(subResult.Item3.RequestResource);
                })).ConfigureAwait(true);

                validationFacade.RequestResource.Properties[key] = tasks.ToList();
            }
        }
        public void IndexUpdatedResource(Uri pidUri, Entity resource, ResourcesCTO repoResources)
        {
            var resourceIndex = new ResourceIndexingDTO(ResourceCrudAction.Update, pidUri, resource, repoResources);

            IndexResource(resourceIndex);
        }
        public async Task <Tuple <ValidationResult, bool, EntityValidationFacade> > ValidateAndPreProcessResource(string resourceId, ResourceRequestDTO resourceRequestDTO,
                                                                                                                  ResourcesCTO resourcesCTO, ResourceCrudAction resourceCrudAction, bool nestedValidation = false, string consumerGroup = null, bool changeResourceType = false)
        {
            var requestResource = _mapper.Map <Resource>(resourceRequestDTO);

            requestResource.Id = string.IsNullOrWhiteSpace(resourceId) ? CreateNewResourceId() : resourceId;

            string entityType = requestResource.Properties.GetValueOrNull(Graph.Metadata.Constants.RDF.Type, true).ToString();
            var    metadata   = _metadataService.GetMetadataForEntityType(entityType);

            // If it is a nested validation (example distribution endpoint), the consumer group of the parent must be included in the process.
            var actualConsumerGroup = nestedValidation ? consumerGroup : requestResource.Properties.GetValueOrNull(Graph.Metadata.Constants.Resource.HasConsumerGroup, true);

            var validationFacade = new EntityValidationFacade(resourceCrudAction, requestResource, resourcesCTO, resourceRequestDTO.HasPreviousVersion, metadata, actualConsumerGroup);

            if (changeResourceType)
            {
                // dirty solution for changing resource type. could be refactored in the future
                var validationRes = await _validationService.ValidateEntity(requestResource, metadata).ConfigureAwait(true);

                if (validationRes.Results.Count == 1 && validationRes.Results[0].Path == Graph.Metadata.Constants.Resource.BaseUri)
                {
                    validationFacade.ResourceCrudAction = ResourceCrudAction.Create;
                }
            }
            // Remove passed properties for several properties and replace it with repo-resource properties afterwards
            RemoveProperty(Graph.Metadata.Constants.Resource.HasLaterVersion, requestResource);
            //RemoveProperty(Graph.Metadata.Constants.Resource.HasHistoricVersion, requestResource);
            RemoveProperty(Graph.Metadata.Constants.Resource.ChangeRequester, requestResource);

            if (resourceCrudAction != ResourceCrudAction.Create)
            {
                UpdatePropertyFromRepositoryResource(Graph.Metadata.Constants.Resource.HasLaterVersion, validationFacade);
                //validationFacade.RequestResource.Properties.AddOrUpdate(Graph.Metadata.Constants.Resource.MetadataGraphConfiguration, new List<dynamic>() { _metadataConfigService.GetLatestConfiguration().Id });
            }
            if (!nestedValidation) // so only new resources get this property, no distribution endpoints
            {
                RemoveProperty(Graph.Metadata.Constants.Resource.MetadataGraphConfiguration, requestResource);
                validationFacade.RequestResource.Properties.AddOrUpdate(Graph.Metadata.Constants.Resource.MetadataGraphConfiguration, new List <dynamic>()
                {
                    _metadataConfigService.GetLatestConfiguration().Id
                });
            }

            // Each property have to be valiated and in same cases transformed
            var keys = requestResource.Properties.Keys.ToList();

            foreach (var key in keys)
            {
                var property = new KeyValuePair <string, List <dynamic> >(key, requestResource.Properties[key]);

                if (changeResourceType && (property.Key == Graph.Metadata.Constants.RDF.Type))
                {
                    continue;
                }
                _entityPropertyValidator.Validate(key, validationFacade);

                await ValidateEndpoint(property, validationFacade);
            }

            // The following processes may only be executed for the main entry, so that the function already ends here with nested validations.
            if (nestedValidation)
            {
                var nestedValidationResult = new ValidationResult()
                {
                    Results = validationFacade.ValidationResults
                };
                var failedValidation = !nestedValidationResult.Conforms &&
                                       nestedValidationResult.Severity != ValidationResultSeverity.Info;
                return(new Tuple <ValidationResult, bool, EntityValidationFacade>(nestedValidationResult, failedValidation, validationFacade));
            }

            var validationResult = await _validationService.ValidateEntity(requestResource, metadata).ConfigureAwait(true);

            validationResult.Results = validationResult.Results.Select(r =>
            {
                r.ResultSeverity = IsWarningSeverity(r, resourceCrudAction) ? ValidationResultSeverity.Warning : r.ResultSeverity;

                return(r);
            }).ToList();

            string validationResourceId = validationFacade.ResourceCrudAction == ResourceCrudAction.Create ? null : resourcesCTO.GetDraftOrPublishedVersion().Id;
            var    duplicateResults     = _identifierValidationService.CheckDuplicates(requestResource, validationResourceId, resourceRequestDTO.HasPreviousVersion);

            if (changeResourceType)
            {
                duplicateResults = duplicateResults.ToList().FindAll(r => r.Path != Graph.Metadata.Constants.Resource.hasPID);
            }
            // Check whether forbidden properties are contained in the entity.
            var forbiddenPropertiesResults = _validationService.CheckForbiddenProperties(requestResource);

            // TODO: Concat or AddRange check
            validationResult.Results = validationResult.Results.Concat(validationFacade.ValidationResults).Concat(duplicateResults).Concat(forbiddenPropertiesResults).OrderBy(t => t.ResultSeverity).ToList();

            var failed = ProcessFailed(validationResult, resourceCrudAction);

            // dirty solution for changing resource type (see also above)
            validationFacade.ResourceCrudAction = changeResourceType ? ResourceCrudAction.Update : validationFacade.ResourceCrudAction;
            if (failed)
            {
                // Reset the lifecycle Status to the correct value
                if (resourceCrudAction == ResourceCrudAction.Update)
                {
                    requestResource.Properties.AddOrUpdate(Graph.Metadata.Constants.Resource.HasEntryLifecycleStatus, new List <dynamic>()
                    {
                        resourcesCTO.HasDraft?Graph.Metadata.Constants.Resource.ColidEntryLifecycleStatus.Draft: Graph.Metadata.Constants.Resource.ColidEntryLifecycleStatus.Published
                    });
                }
            }
            else
            {
                if (resourceCrudAction == ResourceCrudAction.Update && resourcesCTO.HasPublished)
                {
                    requestResource.PublishedVersion = resourcesCTO.Published.Id;
                }
            }

            return(new Tuple <ValidationResult, bool, EntityValidationFacade>(validationResult, failed, validationFacade));
        }
        public void IndexMarkedForDeletionResource(Uri pidUri, Entity resource, ResourcesCTO repoResources)
        {
            var resourceIndex = new ResourceIndexingDTO(ResourceCrudAction.MarkedForDeletion, pidUri, resource, repoResources);

            IndexResource(resourceIndex);
        }
Esempio n. 19
0
        /// <summary>
        /// Read resources from SQS que and Validate
        /// </summary>
        /// <returns></returns>
        private async Task AddUpdateResources()
        {
            _logger.LogInformation("BackgroundService: Running.... ");
            Stopwatch stpWatch = new Stopwatch();

            stpWatch.Start();
            //Check for msgs in a loop
            int msgcount, totalMsgCount = 0;

            try
            {
                do
                {
                    //Check msgs available in SQS
                    var msgs = await _awsSQSHelper.ReceiveResourceMessageAsync();

                    msgcount       = msgs.Count;
                    totalMsgCount += msgs.Count;

                    //get Instance graphs if there is msg to process

                    Uri resInstanceGraph   = null;
                    Uri draftInstanceGraph = null;
                    if (msgs.Count > 0)
                    {
                        _logger.LogInformation("BackgroundService: Found {count} messages from resource queue ", msgs.Count);
                        if (resInstanceGraph == null)
                        {
                            resInstanceGraph = _metadataService.GetInstanceGraph(PIDO.PidConcept);
                        }

                        if (draftInstanceGraph == null)
                        {
                            draftInstanceGraph = _metadataService.GetInstanceGraph("draft");
                        }

                        //List to collect ValidationFacade of each resource
                        List <BulkUploadResult> totalValidationResult = new List <BulkUploadResult>();

                        //Iterate on each msg which will contain list of resource
                        foreach (var msg in msgs)
                        {
                            ResourceRequestDTO resource;
                            // Try Get reources from the msg
                            try
                            {
                                resource = JsonConvert.DeserializeObject <ResourceRequestDTO>(msg.Body);
                            }
                            catch (System.Exception ex)
                            {
                                //Collect result
                                totalValidationResult.Add(new BulkUploadResult
                                {
                                    ActionDone         = "Error",
                                    ErrorMessage       = "Unable to Deserialize the resource",
                                    TimeTaken          = stpWatch.ElapsedMilliseconds.ToString(),
                                    pidUri             = "",
                                    ResourceLabel      = ex.Message,
                                    ResourceDefinition = ""
                                });
                                // Delete msg from input Queue
                                if (DeleteMessageFromSQS(msg.ReceiptHandle).Result == false)
                                {
                                    _logger.LogInformation("BackgroundService: Could not delete meessage");
                                }
                                continue;
                            }

                            //Extract pidUri
                            var hasPid = resource.Properties.GetValueOrNull(Graph.Metadata.Constants.Resource.hasPID, true);
                            Uri pidUri = null;
                            try
                            {
                                if (hasPid != null && ((COLID.Graph.TripleStore.DataModels.Base.Entity)hasPid).Id != string.Empty)
                                {
                                    pidUri = new Uri(((COLID.Graph.TripleStore.DataModels.Base.Entity)hasPid).Id);
                                }
                            }
                            catch
                            {
                                pidUri = null;
                            }
                            //Check SourceId
                            string srcId = resource.Properties.GetValueOrNull(Graph.Metadata.Constants.Resource.HasSourceID, true);
                            if (srcId == null)
                            {
                                //Collect result
                                totalValidationResult.Add(new BulkUploadResult
                                {
                                    ActionDone         = "Error",
                                    ErrorMessage       = "SourceId not found.",
                                    TimeTaken          = stpWatch.ElapsedMilliseconds.ToString(),
                                    pidUri             = pidUri == null ? "" : pidUri.ToString(),
                                    ResourceLabel      = resource.Properties.GetValueOrNull(Graph.Metadata.Constants.Resource.HasLabel, true),
                                    ResourceDefinition = resource.Properties.GetValueOrNull(Graph.Metadata.Constants.Resource.HasResourceDefintion, true),
                                    StateItems         = resource.StateItems
                                });
                                // Delete msg from input Queue
                                if (DeleteMessageFromSQS(msg.ReceiptHandle).Result == false)
                                {
                                    _logger.LogInformation("BackgroundService: Could not delete meessage");
                                }
                                continue;
                            }

                            //Check Entity Type
                            try
                            {
                                _validationService.CheckInstantiableEntityType(resource);
                            }
                            catch (System.Exception ex)
                            {
                                //Collect result
                                totalValidationResult.Add(new BulkUploadResult
                                {
                                    ActionDone         = "Error",
                                    ErrorMessage       = ex.Message,
                                    TimeTaken          = stpWatch.ElapsedMilliseconds.ToString(),
                                    pidUri             = pidUri == null ? "" : pidUri.ToString(),
                                    SourceId           = srcId,
                                    ResourceLabel      = resource.Properties.GetValueOrNull(Graph.Metadata.Constants.Resource.HasLabel, true),
                                    ResourceDefinition = resource.Properties.GetValueOrNull(Graph.Metadata.Constants.Resource.HasResourceDefintion, true),
                                    StateItems         = resource.StateItems
                                });
                                // Delete msg from input Queue
                                if (DeleteMessageFromSQS(msg.ReceiptHandle).Result == false)
                                {
                                    _logger.LogInformation("BackgroundService: Could not delete meessage for sourceId {sourceId} ", srcId);
                                }
                                continue;
                            }

                            ResourcesCTO resourcesCTO = new ResourcesCTO();
                            bool         pidUriExistsinTripleStore = false;

                            if (pidUri == null)
                            {
                                //Check Whether resource is already present in Neptune (using SourceId)
                                ISet <Uri> resourceInstanceGraphs = new HashSet <Uri>();
                                resourceInstanceGraphs.Add(resInstanceGraph);
                                resourceInstanceGraphs.Add(draftInstanceGraph);
                                pidUri = _resourceRepository.GetPidUriBySourceId(srcId, resourceInstanceGraphs);
                            }
                            else
                            {
                                try
                                {
                                    resourcesCTO = _resourceService.GetResourcesByPidUri(pidUri);
                                    pidUriExistsinTripleStore = true;
                                }
                                catch
                                {
                                    pidUriExistsinTripleStore = false;
                                }
                            }

                            //if Pid Uri is null then Add
                            if (pidUri == null || (pidUri != null && pidUriExistsinTripleStore == false))
                            {
                                try
                                {
                                    string newResourceId = CreateNewResourceId();
                                    _logger.LogInformation("BackgroundService: About to Validate New resource: {msg}", msg.Body);
                                    //Validate
                                    var(validationResult, failed, validationFacade) =
                                        await _resourcePreprocessService.ValidateAndPreProcessResource(newResourceId, resource, new ResourcesCTO(), ResourceCrudAction.Create);

                                    _logger.LogInformation("BackgroundService: Validation Complete for: {srcId} having status {stat}", srcId, failed.ToString());

                                    //Update pidUri in stateItem
                                    if (failed == false && resource.StateItems[0].ContainsKey("pid_uri"))
                                    {
                                        resource.StateItems[0]["pid_uri"] = validationFacade.RequestResource.PidUri.ToString();
                                    }

                                    //Create result data
                                    BulkUploadResult result = new BulkUploadResult
                                    {
                                        ActionDone         = failed ? "Error" : "Validated",
                                        ErrorMessage       = failed ? "Validation Failed while Adding the resource." : string.Empty,
                                        Results            = validationResult.Results,
                                        Triples            = validationResult.Triples.Replace(ColidEntryLifecycleStatus.Draft, ColidEntryLifecycleStatus.Published),
                                        InstanceGraph      = resInstanceGraph.ToString(),
                                        TimeTaken          = stpWatch.ElapsedMilliseconds.ToString(),
                                        pidUri             = validationFacade.RequestResource.PidUri.ToString(),
                                        ResourceId         = newResourceId,
                                        SourceId           = srcId,
                                        ResourceLabel      = resource.Properties.GetValueOrNull(Graph.Metadata.Constants.Resource.HasLabel, true),
                                        ResourceDefinition = resource.Properties.GetValueOrNull(Graph.Metadata.Constants.Resource.HasResourceDefintion, true),
                                        StateItems         = resource.StateItems
                                    };

                                    //Get distribution
                                    if (resource.Properties.ContainsKey(Graph.Metadata.Constants.Resource.Distribution))
                                    {
                                        List <dynamic> distList = resource.Properties[Graph.Metadata.Constants.Resource.Distribution];
                                        foreach (dynamic dist in distList)
                                        {
                                            string EndPointPidUri = ((COLID.Graph.TripleStore.DataModels.Base.EntityBase)dist).Properties[Graph.Metadata.Constants.Resource.hasPID][0].Id;
                                            string EndPointUrl    = ((COLID.Graph.TripleStore.DataModels.Base.EntityBase)dist).Properties.GetValueOrNull(Graph.Metadata.Constants.Resource.DistributionEndpoints.HasNetworkAddress, true);
                                            result.DistributionEndPoint.Add(EndPointPidUri, EndPointUrl);
                                        }
                                    }

                                    //Collect Result
                                    totalValidationResult.Add(result);

                                    //if validation passed then Update Nginx Proxy info for the resource DynamoDB
                                    if (!failed)
                                    {
                                        _proxyConfigService.AddUpdateNginxConfigRepository(resource);
                                    }
                                }
                                catch (System.Exception ex)
                                {
                                    //Collect result
                                    totalValidationResult.Add(new BulkUploadResult
                                    {
                                        ActionDone         = "Error",
                                        ErrorMessage       = ex.Message,
                                        TimeTaken          = stpWatch.ElapsedMilliseconds.ToString(),
                                        pidUri             = pidUri == null ? "" : pidUri.ToString(),
                                        SourceId           = srcId,
                                        ResourceLabel      = resource.Properties.GetValueOrNull(Graph.Metadata.Constants.Resource.HasLabel, true),
                                        ResourceDefinition = resource.Properties.GetValueOrNull(Graph.Metadata.Constants.Resource.HasResourceDefintion, true)
                                    });

                                    // Delete msg from input Queue
                                    if (DeleteMessageFromSQS(msg.ReceiptHandle).Result == false)
                                    {
                                        _logger.LogInformation("BackgroundService: Could not delete meessage for sourceId {sourceId} ", srcId);
                                    }
                                    continue;
                                }
                            }
                            else //Update Resource
                            {
                                try
                                {
                                    //var resourcesCTO = _resourceService.GetResourcesByPidUri(pidUri);   // Draft und Published resource getrennt behandeln.
                                    var id = resourcesCTO.GetDraftOrPublishedVersion().Id; // Draft und Published resource getrennt behandeln.

                                    //Update resource with PidUri
                                    if (resource.Properties.ContainsKey(Graph.Metadata.Constants.Resource.hasPID))
                                    {
                                        ((COLID.Graph.TripleStore.DataModels.Base.Entity)resource.Properties[Graph.Metadata.Constants.Resource.hasPID][0]).Id = pidUri.ToString();
                                    }

                                    _logger.LogInformation("BackgroundService: About to Validate Existing resource: {msg}", msg.Body);
                                    var(validationResult, failed, validationFacade) =
                                        await _resourcePreprocessService.ValidateAndPreProcessResource(id, resource, resourcesCTO, ResourceCrudAction.Publish, false, null);

                                    _logger.LogInformation("BackgroundService: Validation Complete for: {srcId} having status {stat}", srcId, failed.ToString());

                                    // The validation failed, if the results are cricital errors.
                                    if (failed)
                                    {
                                        //Collect result
                                        totalValidationResult.Add(new BulkUploadResult
                                        {
                                            ActionDone         = "Error",
                                            ErrorMessage       = "Validation Failed while updating the resource.",
                                            Results            = validationResult.Results,
                                            TimeTaken          = stpWatch.ElapsedMilliseconds.ToString(),
                                            pidUri             = validationFacade.RequestResource.PidUri.ToString(),
                                            ResourceId         = id,
                                            SourceId           = srcId,
                                            ResourceLabel      = resource.Properties.GetValueOrNull(Graph.Metadata.Constants.Resource.HasLabel, true),
                                            ResourceDefinition = resource.Properties.GetValueOrNull(Graph.Metadata.Constants.Resource.HasResourceDefintion, true),
                                            StateItems         = resource.StateItems
                                        });
                                        // Delete msg from input Queue
                                        if (DeleteMessageFromSQS(msg.ReceiptHandle).Result == false)
                                        {
                                            _logger.LogInformation("BackgroundService: Could not delete meessage for sourceId {sourceId} ", srcId);
                                        }
                                        continue;
                                    }

                                    if (resourcesCTO.HasPublished && (!_resourceService.ResourceHasChanged(resourcesCTO.Published, validationFacade.RequestResource)))
                                    {
                                        //Collect result
                                        totalValidationResult.Add(new BulkUploadResult
                                        {
                                            ActionDone         = "Error",
                                            ErrorMessage       = "No changes found in this resource.",
                                            TimeTaken          = stpWatch.ElapsedMilliseconds.ToString(),
                                            pidUri             = validationFacade.RequestResource.PidUri.ToString(),
                                            ResourceId         = id,
                                            SourceId           = srcId,
                                            ResourceLabel      = resource.Properties.GetValueOrNull(Graph.Metadata.Constants.Resource.HasLabel, true),
                                            ResourceDefinition = resource.Properties.GetValueOrNull(Graph.Metadata.Constants.Resource.HasResourceDefintion, true),
                                            StateItems         = resource.StateItems
                                        });
                                        // Delete msg from input Queue
                                        if (DeleteMessageFromSQS(msg.ReceiptHandle).Result == false)
                                        {
                                            _logger.LogInformation("BackgroundService: Could not delete meessage for sourceId {sourceId} ", srcId);
                                        }
                                        continue;
                                    }

                                    var resourcetoCreate = _resourceService.SetHasLaterVersionResourceId(validationFacade.RequestResource);
                                    using (var transaction = _resourceRepository.CreateTransaction())
                                    {
                                        // try deleting draft version and all inbound edges are changed to the new entry.
                                        _resourceRepository.DeleteDraft(validationFacade.RequestResource.PidUri,
                                                                        new Uri(validationFacade.RequestResource.Id), draftInstanceGraph);

                                        if (resourcesCTO.HasDraft)
                                        {
                                            _identifierService.DeleteAllUnpublishedIdentifiers(resourcesCTO.Draft);
                                        }

                                        if (resourcesCTO.HasPublished)
                                        {
                                            // Try to delete published and all inbound edges are changed to the new entry.
                                            _resourceRepository.DeletePublished(validationFacade.RequestResource.PidUri,
                                                                                new Uri(validationFacade.RequestResource.Id), resInstanceGraph);
                                        }

                                        //Add existing revision to the new resource
                                        if (resourcesCTO.Published != null)
                                        {
                                            var existingRevisions = resourcesCTO.Published.Properties.TryGetValue(COLID.Graph.Metadata.Constants.Resource.HasRevision, out List <dynamic> revisionValues) ? revisionValues : null;
                                            if (existingRevisions != null)
                                            {
                                                resourcetoCreate.Properties.Add(COLID.Graph.Metadata.Constants.Resource.HasRevision, existingRevisions);
                                            }
                                        }

                                        //Add Published
                                        _resourceRepository.Create(resourcetoCreate, validationFacade.MetadataProperties, resInstanceGraph);

                                        //Update revision
                                        if (resourcesCTO.Published == null)
                                        {
                                            await _revisionService.InitializeResourceInAdditionalsGraph(resourcetoCreate, validationFacade.MetadataProperties);
                                        }
                                        else
                                        {
                                            Graph.Metadata.DataModels.Resources.Resource updatedResource = await _revisionService.AddAdditionalsAndRemovals(resourcesCTO.Published, validationFacade.RequestResource);
                                        }

                                        _logger.LogInformation("BackgroundService: Commit - {sparqlQuery}", transaction.GetSparqlString());

                                        transaction.Commit();
                                        //Index resource
                                        //_indexingService.IndexPublishedResource(pidUri, updatedResource, validationFacade.ResourcesCTO);
                                    }
                                    _logger.LogInformation("BackgroundService: Resource updated having sourceId {sourceId} ", srcId);
                                    //Create result data
                                    BulkUploadResult result = new BulkUploadResult
                                    {
                                        ActionDone         = "Updated",
                                        TimeTaken          = stpWatch.ElapsedMilliseconds.ToString(),
                                        pidUri             = pidUri == null ? "" : pidUri.ToString(),
                                        ResourceId         = id,
                                        SourceId           = srcId,
                                        ResourceLabel      = resource.Properties.GetValueOrNull(Graph.Metadata.Constants.Resource.HasLabel, true),
                                        ResourceDefinition = resource.Properties.GetValueOrNull(Graph.Metadata.Constants.Resource.HasResourceDefintion, true),
                                        StateItems         = resource.StateItems
                                    };

                                    //Get distribution
                                    if (resource.Properties.ContainsKey(Graph.Metadata.Constants.Resource.Distribution))
                                    {
                                        List <dynamic> distList = resource.Properties[Graph.Metadata.Constants.Resource.Distribution];
                                        foreach (dynamic dist in distList)
                                        {
                                            string EndPointPidUri = ((COLID.Graph.TripleStore.DataModels.Base.EntityBase)dist).Properties[Graph.Metadata.Constants.Resource.hasPID][0].Id;
                                            string EndPointUrl    = ((COLID.Graph.TripleStore.DataModels.Base.EntityBase)dist).Properties.GetValueOrNull(Graph.Metadata.Constants.Resource.DistributionEndpoints.HasNetworkAddress, true);
                                            result.DistributionEndPoint.Add(EndPointPidUri, EndPointUrl);
                                        }
                                    }

                                    //Collect Result
                                    totalValidationResult.Add(result);

                                    //Update Nginx Proxy info for the resource DynamoDB
                                    _proxyConfigService.AddUpdateNginxConfigRepository(resource);
                                }
                                catch (System.Exception ex)
                                {
                                    _logger.LogInformation("BackgroundService:  Error while updating - {msg} ", ex.Message);
                                    //Collect result
                                    totalValidationResult.Add(new BulkUploadResult
                                    {
                                        ActionDone         = "Error",
                                        ErrorMessage       = ex.Message,
                                        TimeTaken          = stpWatch.ElapsedMilliseconds.ToString(),
                                        pidUri             = pidUri == null ? "" : pidUri.ToString(),
                                        SourceId           = srcId,
                                        ResourceLabel      = resource.Properties.GetValueOrNull(Graph.Metadata.Constants.Resource.HasLabel, true),
                                        ResourceDefinition = resource.Properties.GetValueOrNull(Graph.Metadata.Constants.Resource.HasResourceDefintion, true),
                                        StateItems         = resource.StateItems
                                    });

                                    // Delete msg from input Queue
                                    if (DeleteMessageFromSQS(msg.ReceiptHandle).Result == false)
                                    {
                                        _logger.LogInformation("BackgroundService: Could not delete meessage for sourceId {sourceId} ", srcId);
                                    }
                                    continue;
                                }
                            }

                            // Delete msg from input Queue
                            if (DeleteMessageFromSQS(msg.ReceiptHandle).Result == false)
                            {
                                _logger.LogInformation("BackgroundService: Could not delete meessage for sourceId {sourceId} ", srcId);
                            }
                        }

                        //Send msg to output queue
                        try
                        {
                            await _awsSQSHelper.SendResourceMessageAsync(totalValidationResult);
                        }
                        catch (System.Exception ex)
                        {
                            _logger.LogInformation("BackgroundService: Could not send meessage to output queue {msg} ", ex.Message);
                        }
                    }
                } while (msgcount > 0);
            }
            catch (System.Exception ex)
            {
                _logger.LogError("BackgroundService: " + ex.InnerException == null ? ex.Message : ex.InnerException.Message);
            }

            stpWatch.Stop();
            if (totalMsgCount > 0)
            {
                //_logger.LogInformation("BackgroundService: Processed {totMsgCount} messages in {milsec} Milliseconds.", totalMsgCount, stpWatch.ElapsedMilliseconds);
            }
        }