/// <summary> /// Procesa un item de descubrimiento /// </summary> /// <param name="itemIDstring">Identificador del item</param> /// <returns></returns> public bool ProcessItem(string itemIDstring) { Guid itemID = JsonConvert.DeserializeObject <Guid>(itemIDstring); try { DiscoverItemBDService discoverItemBDService = _serviceScopeFactory.CreateScope().ServiceProvider.GetRequiredService <DiscoverItemBDService>(); ProcessDiscoverStateJobBDService processDiscoverStateJobBDService = _serviceScopeFactory.CreateScope().ServiceProvider.GetRequiredService <ProcessDiscoverStateJobBDService>(); CallCronApiService callCronApiService = _serviceScopeFactory.CreateScope().ServiceProvider.GetRequiredService <CallCronApiService>(); CallEtlApiService callEtlApiService = _serviceScopeFactory.CreateScope().ServiceProvider.GetRequiredService <CallEtlApiService>(); CallUrisFactoryApiService callUrisFactoryApiService = _serviceScopeFactory.CreateScope().ServiceProvider.GetRequiredService <CallUrisFactoryApiService>(); DiscoverItem discoverItem = discoverItemBDService.GetDiscoverItemById(itemID); if (discoverItem != null) { //Aplicamos el proceso de descubrimiento DiscoverResult resultado = Init(discoverItem, callEtlApiService, callUrisFactoryApiService); Process(discoverItem, resultado, discoverItemBDService, callCronApiService, callUrisFactoryApiService, processDiscoverStateJobBDService ); } } catch (Exception ex) { Logging.Error(ex); //Se ha producido un error al aplicar el descubrimiento //Modificamos los datos del DiscoverItem que ha fallado DiscoverItemBDService discoverItemBDService = _serviceScopeFactory.CreateScope().ServiceProvider.GetRequiredService <DiscoverItemBDService>(); DiscoverItem discoverItemBBDD = discoverItemBDService.GetDiscoverItemById(itemID); discoverItemBBDD.UpdateError($"{ex.Message}\n{ex.StackTrace}\n"); discoverItemBDService.ModifyDiscoverItem(discoverItemBBDD); if (!string.IsNullOrEmpty(discoverItemBBDD.JobID)) { //Si viene de una tarea actualizamos su estado de descubrimiento ProcessDiscoverStateJobBDService processDiscoverStateJobBDService = _serviceScopeFactory.CreateScope().ServiceProvider.GetRequiredService <ProcessDiscoverStateJobBDService>(); ProcessDiscoverStateJob processDiscoverStateJob = processDiscoverStateJobBDService.GetProcessDiscoverStateJobByIdJob(discoverItemBBDD.JobID); if (processDiscoverStateJob != null) { processDiscoverStateJob.State = "Error"; processDiscoverStateJobBDService.ModifyProcessDiscoverStateJob(processDiscoverStateJob); } else { processDiscoverStateJob = new ProcessDiscoverStateJob() { State = "Error", JobId = discoverItemBBDD.JobID }; processDiscoverStateJobBDService.AddProcessDiscoverStateJob(processDiscoverStateJob); } } } return(true); }
///<summary> ///Añade un estado de descubrimiento de una tarea ///</summary> ///<param name="processDiscoverStateJob">Estado de descubrimiento de una tarea</param> public Guid AddProcessDiscoverStateJob(ProcessDiscoverStateJob processDiscoverStateJob) { if (processDiscoverStateJob.Id == Guid.Empty) { processDiscoverStateJob.Id = Guid.NewGuid(); } _context.ProcessDiscoverStateJob.Add(processDiscoverStateJob); _context.SaveChanges(); return(processDiscoverStateJob.Id); }
///<summary> ///Modifica un estado de descubrimiento de una tarea ///</summary> ///<param name="processDiscoverStateJob">Estado de descubrimiento de una tarea</param> public bool ModifyProcessDiscoverStateJob(ProcessDiscoverStateJob processDiscoverStateJob) { bool modified = false; ProcessDiscoverStateJob processDiscoverStateJobOriginal = GetProcessDiscoverStateJobById(processDiscoverStateJob.Id); if (processDiscoverStateJobOriginal != null) { processDiscoverStateJobOriginal.JobId = processDiscoverStateJob.JobId; processDiscoverStateJobOriginal.State = processDiscoverStateJob.State; _context.SaveChanges(); modified = true; } return(modified); }
///<summary> ///Elimina un estado de descubrimiento de una tarea ///</summary> ///<param name="id">Identificador del estado de descubrimiento de la tarea</param> public bool RemoveDiscoverItem(Guid id) { try { ProcessDiscoverStateJob processDiscoverStateJob = GetProcessDiscoverStateJobById(id); if (processDiscoverStateJob != null) { _context.Entry(processDiscoverStateJob).State = EntityState.Deleted; _context.SaveChanges(); } return(true); } catch (Exception ex) { return(false); } }
public IActionResult DetailsJob(string id, Guid repository_id) { var job = _serviceApi.GetJob(id); ProcessDiscoverStateJob stateJob = _processDiscoverStateJobBDService.GetProcessDiscoverStateJobByIdJob(job.Id); if (stateJob != null) { job.DiscoverState = stateJob.State; } if (!Guid.Empty.Equals(repository_id)) { job.IdRepository = repository_id; } job.DiscoverStates = _discoverItemService.GetDiscoverItemsStatesByJob(id); var discoverItemsErrorMini = _discoverItemService.GetDiscoverItemsErrorByJobMini(id); job.DiscoverItemsMini = discoverItemsErrorMini; return(View(job)); }
public IActionResult Details(Guid id) { RepositoryConfigViewModel result = _serviceApi.GetRepositoryConfig(id); result.ListRecurringJobs = _respositoryJobService.GetRecurringJobsOfRepo(id); result.ListJobs = _respositoryJobService.GetJobsOfRepo(id); result.ListScheduledJobs = _respositoryJobService.GetScheduledJobsOfRepo(id); if (result.ListJobs != null && result.ListJobs.Count > 0) { var job = result.ListJobs.OrderByDescending(item => item.ExecutedAt).FirstOrDefault(); result.LastJob = job.Id; result.LastState = job.State; int succed = result.ListJobs.Count(item => item.State.Equals("Succeeded")); double percentage = ((double)succed / result.ListJobs.Count) * 100; result.PorcentajeTareas = Math.Round(percentage, 2); List <ProcessDiscoverStateJob> statesDiscoverJob = _processDiscoverStateJobBDService.GetProcessDiscoverStateJobByIdJobs(result.ListJobs.Select(x => x.Id).ToList()); foreach (JobViewModel jobVM in result.ListJobs) { ProcessDiscoverStateJob state = statesDiscoverJob.FirstOrDefault(x => x.JobId == jobVM.Id); if (state != null) { jobVM.DiscoverState = state.State; } jobVM.IdRepository = id; } } if (result != null) { return(View(result)); } else { return(NotFound()); } }
/// <summary> /// Procesa los resultados del descubrimiento /// </summary> /// <param name="pDiscoverItem">Objeto con los datos de com procesar el proeso de descubrimiento</param> /// <param name="pDiscoverResult">Resultado de la aplicación del descubrimiento</param> /// <param name="pDiscoverItemBDService">Clase para gestionar las operaciones de las tareas de descubrimiento</param> /// <param name="pCallCronApiService">Servicio para hacer llamadas a los métodos del apiCron</param> /// <param name="pCallUrisFactoryApiService">Servicio para hacer llamadas a los métodos del Uris Factory</param> /// <param name="pProcessDiscoverStateJobBDService">Clase para gestionar los estados de descubrimiento de las tareas</param> /// <returns></returns> public void Process(DiscoverItem pDiscoverItem, DiscoverResult pDiscoverResult, DiscoverItemBDService pDiscoverItemBDService, CallCronApiService pCallCronApiService, CallUrisFactoryApiService pCallUrisFactoryApiService, ProcessDiscoverStateJobBDService pProcessDiscoverStateJobBDService) { #region Cargamos configuraciones ConfigSparql ConfigSparql = new ConfigSparql(); string SGI_SPARQLEndpoint = ConfigSparql.GetEndpoint(); string SGI_SPARQLGraph = ConfigSparql.GetGraph(); string SGI_SPARQLQueryParam = ConfigSparql.GetQueryParam(); string SGI_SPARQLUsername = ConfigSparql.GetUsername(); string SGI_SPARQLPassword = ConfigSparql.GetPassword(); string Unidata_SPARQLEndpoint = ConfigSparql.GetUnidataEndpoint(); string Unidata_SPARQLGraph = ConfigSparql.GetUnidataGraph(); string Unidata_SPARQLQueryParam = ConfigSparql.GetUnidataQueryParam(); string Unidata_SPARQLUsername = ConfigSparql.GetUnidataUsername(); string Unidata_SPARQLPassword = ConfigSparql.GetUnidataPassword(); ConfigService ConfigService = new ConfigService(); string UnidataDomain = ConfigService.GetUnidataDomain(); string UnidataUriTransform = ConfigService.GetUnidataUriTransform(); #endregion /* * En función del resultado obtenido se realiza una de las siguientes acciones: * Si para alguna entidad hay más de un candidato que supere el umbral máximo o hay alguna entidad que supere el umbral mínimo pero no alcance el máximo se agregará el RDF a una BBDD junto con todos los datos necesarios para que el administrador decida como proceder. * Si no estamos en el punto anterior * Se obtienen las entidades principales del RDF y se eliminan todos los triples que haya en la BBDD en los que aparezcan como sujeto u objeto. * Se eliminan todos los triples cuyo sujeto y predicado estén en el RDF a cargar y estén marcados como monovaluados. * Se vuelcan los triples a la BBDD. * * */ if (pDiscoverItem.Publish) { if (pDiscoverResult.discoveredEntitiesProbability.Count > 0) { //Hay dudas en la desambiguación, por lo que lo actualizamos en la BBDD con su estado correspondiente pDiscoverItem.UpdateDissambiguationProblems( pDiscoverResult.discoveredEntitiesProbability, pDiscoverResult.reconciliationData.reconciliatedEntitiesWithBBDD.Values.Select(x => x.uri).Union(pDiscoverResult.reconciliationData.reconciliatedEntitiesWithIds.Values).Union(pDiscoverResult.reconciliationData.reconciliatedEntitiesWithSubject).Union(pDiscoverResult.reconciliationData.reconciliatedEntitiesWithExternalIntegration.Values.Select(x => x.uri)).ToList(), pDiscoverResult.GetDataGraphRDF()); pDiscoverItemBDService.ModifyDiscoverItem(pDiscoverItem); } else { string urlDiscoverAgent = pCallUrisFactoryApiService.GetUri("Agent", "discover"); //Creamos los SameAs hacia unidata para las entidades que NO lo tengan hacia Unidata //TODO descomentar cuando esté habilitaado Unidata //pDiscoverResult.dataGraph = AsioPublication.CreateUnidataSameAs(pDiscoverResult.dataGraph, UnidataDomain, UnidataUriTransform); //Publicamos en el SGI AsioPublication asioPublication = new AsioPublication(SGI_SPARQLEndpoint, SGI_SPARQLQueryParam, SGI_SPARQLGraph, SGI_SPARQLUsername, SGI_SPARQLPassword); asioPublication.PublishRDF(pDiscoverResult.dataGraph, pDiscoverResult.ontologyGraph, new KeyValuePair <string, string>(urlDiscoverAgent, "Algoritmos de descubrimiento"), pDiscoverResult.start, pDiscoverResult.end, pDiscoverResult.discoverLinkData, pCallUrisFactoryApiService); //TODO Lógica nombres de personas SparqlResultSet sparqlResultSet = (SparqlResultSet)pDiscoverResult.dataGraph.ExecuteQuery("select ?s ?name where {?s a <http://purl.org/roh/mirror/foaf#Person>. ?s <http://purl.org/roh/mirror/foaf#name> ?name}"); foreach (SparqlResult sparqlResult in sparqlResultSet.Results) { string s = sparqlResult["s"].ToString(); string nombre = sparqlResult["name"].ToString(); if (sparqlResult["name"] is ILiteralNode) { nombre = ((ILiteralNode)sparqlResult["name"]).Value; } _discoverCacheGlobal.PersonsNormalizedNames[s] = DiscoverUtility.NormalizeName(nombre); } //TODO Lógica titles SparqlResultSet sparqlResultSetTitles = (SparqlResultSet)pDiscoverResult.dataGraph.ExecuteQuery("select * where {?s a ?rdftype. ?s <http://purl.org/roh#title> ?title}"); foreach (SparqlResult sparqlResult in sparqlResultSetTitles.Results) { string s = sparqlResult["s"].ToString(); string rdftype = sparqlResult["rdftype"].ToString(); string title = sparqlResult["title"].ToString(); if (sparqlResult["title"] is ILiteralNode) { title = ((ILiteralNode)sparqlResult["title"]).Value; } title = DiscoverUtility.NormalizeTitle(title); if (!_discoverCacheGlobal.EntitiesNormalizedTitles.ContainsKey(rdftype)) { _discoverCacheGlobal.EntitiesNormalizedTitles.Add(rdftype, new Dictionary <string, HashSet <string> >()); } if (!_discoverCacheGlobal.EntitiesNormalizedTitles[rdftype].ContainsKey(title)) { _discoverCacheGlobal.EntitiesNormalizedTitles[rdftype].Add(title, new HashSet <string>()); } _discoverCacheGlobal.EntitiesNormalizedTitles[rdftype][title].Add(s); } //TODO descomentar cuando esté habilitaado Unidata if (false) { //Publicamos en UNIDATA AsioPublication asioPublicationUnidata = new AsioPublication(Unidata_SPARQLEndpoint, Unidata_SPARQLQueryParam, Unidata_SPARQLGraph, Unidata_SPARQLUsername, Unidata_SPARQLPassword); // Prepara el grafo para su carga en Unidata, para ello coge las URIs de Unidata del SameAs y la aplica a los sujetos y los antiguos sujetos se agregan al SameAs RohGraph unidataGraph = AsioPublication.TransformUrisToUnidata(pDiscoverResult.dataGraph, UnidataDomain, UnidataUriTransform); //Eliminamos los triples de crisIdentifier ya que no hay que volcarlos en unidata { TripleStore store = new TripleStore(); store.Add(unidataGraph); SparqlUpdateParser parser = new SparqlUpdateParser(); //Actualizamos los sujetos SparqlUpdateCommandSet updateSubject = parser.ParseFromString( @" DELETE { ?s ?p ?o. } WHERE { ?s ?p ?o. FILTER(?p =<" + mPropertySGIRohCrisIdentifier + @">) }"); LeviathanUpdateProcessor processor = new LeviathanUpdateProcessor(store); processor.ProcessCommandSet(updateSubject); } asioPublicationUnidata.PublishRDF(unidataGraph, pDiscoverResult.ontologyGraph, new KeyValuePair <string, string>(urlDiscoverAgent, "Algoritmos de descubrimiento"), pDiscoverResult.start, pDiscoverResult.end, pDiscoverResult.discoverLinkData, pCallUrisFactoryApiService); } //Lo marcamos como procesado en la BBDD y eliminamos sus metadatos pDiscoverItem.UpdateProcessed(); pDiscoverItemBDService.ModifyDiscoverItem(pDiscoverItem); } //Actualizamos el estado de descubrimiento de la tarea si el estado encolado esta en estado Succeeded o Failed (ha finalizado) //TODO cambiar por query a BBDD string statusQueueJob = pCallCronApiService.GetJob(pDiscoverItem.JobID).State; if ((statusQueueJob == "Failed" || statusQueueJob == "Succeeded")) { ProcessDiscoverStateJob processDiscoverStateJob = pProcessDiscoverStateJobBDService.GetProcessDiscoverStateJobByIdJob(pDiscoverItem.JobID); string state; //Actualizamos a error si existen items en estado error o con problemas de desambiguación if (pDiscoverItemBDService.ExistsDiscoverItemsErrorOrDissambiguatinProblems(pDiscoverItem.JobID)) { state = "Error"; } else if (pDiscoverItemBDService.ExistsDiscoverItemsPending(pDiscoverItem.JobID)) { //Actualizamos a 'Pending' si aún existen items pendientes state = "Pending"; } else { //Actualizamos a Success si no existen items en estado error ni con problemas de desambiguación y no hay ninguno pendiente state = "Success"; } if (processDiscoverStateJob != null) { processDiscoverStateJob.State = state; pProcessDiscoverStateJobBDService.ModifyProcessDiscoverStateJob(processDiscoverStateJob); } else { processDiscoverStateJob = new ProcessDiscoverStateJob() { State = state, JobId = pDiscoverItem.JobID }; pProcessDiscoverStateJobBDService.AddProcessDiscoverStateJob(processDiscoverStateJob); } } } else { //Actualizamos en BBDD DiscoverItem discoverItemBD = pDiscoverItemBDService.GetDiscoverItemById(pDiscoverItem.ID); //Reporte de descubrimiento string discoverReport = "Time processed (seconds): " + pDiscoverResult.secondsProcessed + "\n"; if (pDiscoverResult.reconciliationData.reconciliatedEntitiesWithSubject != null && pDiscoverResult.reconciliationData.reconciliatedEntitiesWithSubject.Count > 0) { discoverReport += "Entities discover with the same uri: " + pDiscoverResult.reconciliationData.reconciliatedEntitiesWithSubject.Count + "\n"; foreach (string uri in pDiscoverResult.reconciliationData.reconciliatedEntitiesWithSubject) { discoverReport += "\t" + uri + "\n"; } } if (pDiscoverResult.reconciliationData.reconciliatedEntitiesWithIds != null && pDiscoverResult.reconciliationData.reconciliatedEntitiesWithIds.Count > 0) { discoverReport += "Entities discover with some common identifier: " + pDiscoverResult.reconciliationData.reconciliatedEntitiesWithIds.Count + "\n"; foreach (string uri in pDiscoverResult.reconciliationData.reconciliatedEntitiesWithIds.Keys) { discoverReport += "\t" + uri + " --> " + pDiscoverResult.reconciliationData.reconciliatedEntitiesWithIds[uri] + "\n"; } } if (pDiscoverResult.reconciliationData.reconciliatedEntitiesWithBBDD != null && pDiscoverResult.reconciliationData.reconciliatedEntitiesWithBBDD.Count > 0) { discoverReport += "Entities discover with reconciliation config: " + pDiscoverResult.reconciliationData.reconciliatedEntitiesWithBBDD.Count + "\n"; foreach (string uri in pDiscoverResult.reconciliationData.reconciliatedEntitiesWithBBDD.Keys) { discoverReport += "\t" + uri + " --> " + pDiscoverResult.reconciliationData.reconciliatedEntitiesWithBBDD[uri] + "\n"; } } if (pDiscoverResult.reconciliationData.reconciliatedEntitiesWithExternalIntegration != null && pDiscoverResult.reconciliationData.reconciliatedEntitiesWithExternalIntegration.Count > 0) { discoverReport += "Entities discover with external integrations config: " + pDiscoverResult.reconciliationData.reconciliatedEntitiesWithExternalIntegration.Count + "\n"; foreach (string uri in pDiscoverResult.reconciliationData.reconciliatedEntitiesWithExternalIntegration.Keys) { discoverReport += "\t" + uri + " --> " + pDiscoverResult.reconciliationData.reconciliatedEntitiesWithExternalIntegration[uri] + "\n"; } } if (pDiscoverResult.discoverLinkData != null && pDiscoverResult.discoverLinkData.entitiesProperties != null && pDiscoverResult.discoverLinkData.entitiesProperties.Count > 0) { discoverReport += "Entities with identifiers obtained with External integration: " + pDiscoverResult.discoverLinkData.entitiesProperties.Count + "\n"; foreach (string uri in pDiscoverResult.discoverLinkData.entitiesProperties.Keys) { foreach (DiscoverLinkData.PropertyData property in pDiscoverResult.discoverLinkData.entitiesProperties[uri]) { foreach (string value in property.valueProvenance.Keys) { foreach (string provenance in property.valueProvenance[value]) { discoverReport += "\t" + uri + " - " + property.property + " - " + value + " --> " + provenance + "\n"; } } } } } discoverItemBD.UpdateReport(pDiscoverResult.discoveredEntitiesProbability, pDiscoverResult.GetDataGraphRDF(), discoverReport); pDiscoverItemBDService.ModifyDiscoverItem(discoverItemBD); } }
///<summary> ///Método para la sincronización de repositorios ///</summary> ///<param name="idRepositoryGuid">identificador del repositorio a sincronizar</param> /// <param name="pSet">tipo del objeto, usado para filtrar por agrupaciones</param> /// <param name="codigoObjeto">codigo del objeto a sincronizar, es necesario pasar el parametro set si se quiere pasar este parámetro</param> public string PublishRepositories(Guid idRepositoryGuid, PerformContext context, string pSet = null, string codigoObjeto = null) { string idRepository = idRepositoryGuid.ToString(); RepositoryConfig repositoryConfig = _context.RepositoryConfig.Include(item => item.RepositoryConfigSet).FirstOrDefault(x => x.RepositoryConfigID == idRepositoryGuid); //Nos quedariamos con la fecha de la fila que tenga en el 'set' lo que viene en el pSet, si viene nulo, habría que coger la fila que tenga '-' en caso de que exista DateTime?fecha = null; string setAux = "-"; if (!string.IsNullOrEmpty(pSet)) { setAux = pSet; } if (repositoryConfig.RepositoryConfigSet.FirstOrDefault(x => x.Set == setAux) != null) { fecha = repositoryConfig.RepositoryConfigSet.FirstOrDefault(x => x.Set == setAux).LastUpdate; } string idJob = context.BackgroundJob.Id; DateTime fechaJob = context.BackgroundJob.CreatedAt; var discover = _context.ProcessDiscoverStateJob.FirstOrDefault(item => item.JobId.Equals(idJob)); if (discover == null) { ProcessDiscoverStateJob discoveryState = new ProcessDiscoverStateJob() { Id = Guid.NewGuid(), JobId = idJob, State = "Pending" }; _context.ProcessDiscoverStateJob.Add(discoveryState); _context.SaveChanges(); } try { object objeto = new { repository_identifier = idRepositoryGuid, codigo_objeto = codigoObjeto, fecha_from = fecha, set = pSet, job_id = idJob, job_created_date = fechaJob }; string result = _serviceApi.CallPostApi($"sync/execute", objeto, _token);///{idRepository} result = JsonConvert.DeserializeObject <string>(result); #region Actualizamos ProcessDiscoverStateJob string state; //Actualizamos a error si existen items en estado error o con problemas de desambiguación if (_context.DiscoverItem.Any(x => x.JobID == idJob && (x.Status == DiscoverItem.DiscoverItemStatus.Error.ToString() || x.Status == DiscoverItem.DiscoverItemStatus.ProcessedDissambiguationProblem.ToString()))) { state = "Error"; } else if (_context.DiscoverItem.Any(x => x.JobID == idJob && (x.Status == DiscoverItem.DiscoverItemStatus.Pending.ToString()))) { //Actualizamos a 'Pending' si aún existen items pendientes state = "Pending"; } else { //Actualizamos a Success si no existen items en estado error ni con problemas de desambiguación y no hay ninguno pendiente state = "Success"; } ProcessDiscoverStateJob processDiscoverStateJob = _context.ProcessDiscoverStateJob.FirstOrDefault(item => item.JobId.Equals(idJob)); if (processDiscoverStateJob != null) { processDiscoverStateJob.State = state; } else { processDiscoverStateJob = new ProcessDiscoverStateJob() { State = state, JobId = idJob }; _context.ProcessDiscoverStateJob.Add(processDiscoverStateJob); } _context.SaveChanges(); #endregion return(result); } catch (Exception ex) { string timeStamp = CreateTimeStamp(); CreateLoggin(timeStamp, idRepository); Log.Error($"{ex.Message}\n{ex.StackTrace}\n"); throw new Exception(ex.Message); //return ex.Message; } }