Пример #1
0
        /// <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);
        }
Пример #2
0
 ///<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);
 }
Пример #3
0
        ///<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);
        }
Пример #4
0
 ///<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);
     }
 }
Пример #5
0
        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());
            }
        }
Пример #7
0
        /// <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;
            }
        }