public async Task <IActionResult> CreateResource([FromBody] ResourceRequestDTO resource) { //Validate Resource var result = await _resourceService.CreateResource(resource); return(Ok(result)); }
public async Task <IActionResult> CreateResourceBatch([FromBody] ResourceRequestDTO resource) { //Validate Resource var result = _resourceService.QueueResourceCreation(resource); return(Ok(result)); }
private async Task <ColidIdentifierResponse> CheckDuplicate(ResourceRequestDTO resourceRequestDto, string previousVersion = "") { var url = $"{_apiPathV3}/checkForDuplicate"; if (!string.IsNullOrWhiteSpace(previousVersion)) { url += $"?previousVersion={previousVersion}"; } var response = await _client.PostAsync(url, BuildJsonHttpContent(resourceRequestDto)); var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false); _output.WriteLine(content); Assert.NotNull(content); var result = JsonConvert.DeserializeObject <List <ValidationResultProperty> >(content); Assert.NotNull(result); if (!response.IsSuccessStatusCode) { _output.WriteLine(result.ToString()); } return(new ColidIdentifierResponse(response, content, result)); }
/// <summary> /// Gets the NGINX proxy configuration for a resource. /// </summary> /// <param name="resource">Resource</param> /// <returns>Serialized NGINX configuration</returns> private string GetProxyConfigurationByResource(ResourceRequestDTO resource) { List <ResourceProxyDTO> publishedResourceProxyDTOs = new List <ResourceProxyDTO>(); publishedResourceProxyDTOs.Add(ConvertResourceToProxyDto(resource)); var nginxConfigSections = GenerateConfigSections(publishedResourceProxyDTOs); nginxConfigSections = FilterDuplicateConfigurationSections(nginxConfigSections); nginxConfigSections = OrderConfigurationSections(nginxConfigSections); return(SerializeNginxConfigList(nginxConfigSections));; }
public async Task <ResourceWriteResultCTO> EditResource(Uri pidUri, ResourceRequestDTO resourceRequest) { _validationService.CheckInstantiableEntityType(resourceRequest); using (var lockService = _lockServiceFactory.CreateLockService()) { await lockService.CreateLockAsync(pidUri.ToString()); var resourcesCTO = GetResourcesByPidUri(pidUri); var id = resourcesCTO.GetDraftOrPublishedVersion().Id; if (resourcesCTO.HasPublishedAndNoDraft) { id = CreateNewResourceId(); } var(validationResult, failed, validationFacade) = await _resourcePreprocessService.ValidateAndPreProcessResource(id, resourceRequest, resourcesCTO, ResourceCrudAction.Update); HandleValidationFailures(resourcesCTO.GetDraftOrPublishedVersion(), id, validationResult, failed, validationFacade); 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)); // all inbound edges pointing to an entry of a pid uri(published entry) will be duplicated to the request id as well. _resourceRepository.Relink(pidUri, new Uri(validationFacade.RequestResource.Id)); if (resourcesCTO.HasDraft) { _identifierService.DeleteAllUnpublishedIdentifiers(resourcesCTO.Draft); } _resourceRepository.Create(validationFacade.RequestResource, validationFacade.MetadataProperties); CreateHasPidEntryDraftProperty(validationFacade.RequestResource.PidUri); transaction.Commit(); } // Check whether the correct entity type is specified -> throw exception return(new ResourceWriteResultCTO(validationFacade.RequestResource, validationResult)); } }
public void AddUpdateNginxConfigRepository(ResourceRequestDTO resource) { var hasPid = resource.Properties.GetValueOrNull(Graph.Metadata.Constants.Resource.hasPID, true); string pidUri = hasPid != null ? hasPid.Id : ""; Dictionary <string, AttributeValue> attributes = new Dictionary <string, AttributeValue>(); // PidUri is hash-key attributes["pid_uri"] = new AttributeValue { S = pidUri }; //Try deleting if there is an existing entry in dynamoDB try { _amazonDynamoDbService.DeleteItemAsync(_nginxConfigDynamoDbTable, attributes); } catch (System.Exception ex) { _logger.LogInformation($"ProxyConfigService: could not delete Nginx Config before Added/Updated for : {pidUri} Error {ex.StackTrace}", pidUri, ex); } // Title is range-key attributes["configString"] = new AttributeValue { S = GetProxyConfigurationByResource(resource) }; //Add new Entry try { _amazonDynamoDbService.PutItemAsync(_nginxConfigDynamoDbTable, attributes); _logger.LogInformation($"ProxyConfigService: Nginx Config Added/Updated for : {pidUri}", pidUri); } catch (System.Exception ex) { _logger.LogError($"ProxyConfigService: Error occured while Add & Update DynamoDb: {ex.StackTrace}", ex); } }
public async Task <ResourceWriteResultCTO> CreateResource(ResourceRequestDTO resourceRequest) { var newResourceId = CreateNewResourceId(); _logger.LogInformation("Create resource with id={id}", newResourceId); // Check whether the correct entity type is specified -> throw exception _validationService.CheckInstantiableEntityType(resourceRequest); var(validationResult, failed, validationFacade) = await _resourcePreprocessService.ValidateAndPreProcessResource(newResourceId, resourceRequest, new ResourcesCTO(), ResourceCrudAction.Create); validationFacade.RequestResource.Id = newResourceId; if (failed) { throw new ResourceValidationException(validationResult, validationFacade.RequestResource); } using (var transaction = _resourceRepository.CreateTransaction()) { _resourceRepository.Create(validationFacade.RequestResource, validationFacade.MetadataProperties); transaction.Commit(); // TODO: Handle error if linking failed if (!string.IsNullOrWhiteSpace(resourceRequest.HasPreviousVersion)) { _resourceLinkingService.LinkResourceIntoList(validationFacade.RequestResource.PidUri, new Uri(resourceRequest.HasPreviousVersion)); } } return(new ResourceWriteResultCTO(validationFacade.RequestResource, validationResult)); }
private ResourceProxyDTO ConvertResourceToProxyDto(ResourceRequestDTO resource) { var hasPid = resource.Properties.GetValueOrNull(Graph.Metadata.Constants.Resource.hasPID, true); string pidUri = hasPid != null ? hasPid.Id : ""; var hasBaseUri = resource.Properties.GetValueOrNull(Graph.Metadata.Constants.Resource.BaseUri, true); string baseUri = hasBaseUri != null ? hasBaseUri.Id : null; ResourceProxyDTO resourceProxyDto = new ResourceProxyDTO { PidUrl = pidUri, TargetUrl = null, ResourceVersion = null, NestedProxies = new List <ResourceProxyDTO>() }; // 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 distributionPidUri = ((COLID.Graph.TripleStore.DataModels.Base.EntityBase)dist).Properties[Graph.Metadata.Constants.Resource.hasPID][0].Id; string distributionNetworkAddress = ((COLID.Graph.TripleStore.DataModels.Base.EntityBase)dist).Properties.GetValueOrNull(Graph.Metadata.Constants.Resource.DistributionEndpoints.HasNetworkAddress, true); bool isDistributionEndpointDeprecated = ((COLID.Graph.TripleStore.DataModels.Base.EntityBase)dist).Properties.GetValueOrNull(Graph.Metadata.Constants.Resource.DistributionEndpoints.DistributionEndpointLifecycleStatus, true) == Common.Constants.DistributionEndpoint.LifeCycleStatus.Deprecated; //string distBaseUri = ((COLID.Graph.TripleStore.DataModels.Base.EntityBase)dist).Properties.GetValueOrNull(Graph.Metadata.Constants.Resource.DistributionEndpoints.HasNetworkAddress, true); resourceProxyDto.NestedProxies.Add( new ResourceProxyDTO { PidUrl = distributionPidUri, TargetUrl = isDistributionEndpointDeprecated ? pidUri : distributionNetworkAddress, ResourceVersion = null, BaseUrl = baseUri }); } } //Get Main distribution string baseUriDistTargetUrl = ""; if (resource.Properties.ContainsKey(Graph.Metadata.Constants.Resource.MainDistribution)) { List <dynamic> distList = resource.Properties[Graph.Metadata.Constants.Resource.MainDistribution]; foreach (dynamic dist in distList) { string mainDistributionPidUri = ((COLID.Graph.TripleStore.DataModels.Base.EntityBase)dist).Properties[Graph.Metadata.Constants.Resource.hasPID][0].Id; string mainDistributionNetworkAddress = ((COLID.Graph.TripleStore.DataModels.Base.EntityBase)dist).Properties.GetValueOrNull(Graph.Metadata.Constants.Resource.DistributionEndpoints.HasNetworkAddress, true); bool isDistributionEndpointDeprecated = ((COLID.Graph.TripleStore.DataModels.Base.EntityBase)dist).Properties.GetValueOrNull(Graph.Metadata.Constants.Resource.DistributionEndpoints.DistributionEndpointLifecycleStatus, true) == Common.Constants.DistributionEndpoint.LifeCycleStatus.Deprecated; //string distBaseUri = ((COLID.Graph.TripleStore.DataModels.Base.EntityBase)dist).Properties.GetValueOrNull(Graph.Metadata.Constants.Resource.DistributionEndpoints.HasNetworkAddress, true); baseUriDistTargetUrl = isDistributionEndpointDeprecated ? pidUri : mainDistributionNetworkAddress; resourceProxyDto.NestedProxies.Add( new ResourceProxyDTO { PidUrl = mainDistributionPidUri, TargetUrl = baseUriDistTargetUrl, ResourceVersion = null, BaseUrl = baseUri }); } } // Proxy for base URI if (!string.IsNullOrWhiteSpace(baseUri)) { string resourceVersion = resource.Properties.GetValueOrNull(Graph.Metadata.Constants.Resource.HasVersion, true); // distribution target uri is null -> base uri have to redirect to resourcePidUri if (!string.IsNullOrWhiteSpace(baseUriDistTargetUrl)) { if (Uri.TryCreate(baseUriDistTargetUrl, UriKind.Absolute, out _)) { resourceProxyDto.NestedProxies.Add(new ResourceProxyDTO { PidUrl = baseUri, TargetUrl = string.IsNullOrWhiteSpace(baseUriDistTargetUrl) ? pidUri : baseUriDistTargetUrl, ResourceVersion = resourceVersion, BaseUrl = baseUri }); } else { resourceProxyDto.NestedProxies.Add(new ResourceProxyDTO { PidUrl = baseUri, TargetUrl = pidUri, ResourceVersion = resourceVersion, BaseUrl = baseUri }); } } else { resourceProxyDto.NestedProxies.Add(new ResourceProxyDTO { PidUrl = baseUri, TargetUrl = pidUri, ResourceVersion = resourceVersion }); } } return(resourceProxyDto); }
public async Task <IActionResult> EditResource([FromQuery] Uri pidUri, [FromBody] ResourceRequestDTO resource) { var result = await _resourceService.EditResource(pidUri, resource); return(Ok(result)); }
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)); }
/// <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 async Task <IActionResult> EditResourceBatch([FromQuery] Uri pidUri, [FromBody] ResourceRequestDTO resource) { var result = _resourceService.QueueResourceEdit(pidUri, resource); return(Ok(result)); }