Esempio n. 1
0
            /// <summary>
            /// Obtiene el filtro global
            /// </summary>
            /// <param name="assembly">asembly donde obtener la metadata</param>
            /// <returns></returns>
            public static GlobalFilters GetGlobalFilter(Assembly assembly)
            {
                // obtiene el assembly.
                var types = Common.GetTypeModel(assembly);


                //
                var toValueTypes = ToValueTypes(types);

                var toValues = GetToValues(types, toValueTypes);


                var ToProcesTypes = ToProcess.ToProcessTypes(types, 0, true, null);

                var toProcess = ToProcess.GetFilterProcess(types, 0, true, null);

                var tp = ToProcesTypes.First().toProcess.TargetType;

                var tpIndex = Reflection.Entities.GetIndex(tp).Value;



                return(new GlobalFilters
                {
                    EntityForGlobalFilters = tp.Name,
                    IndexEntityForGlobalFilters = tpIndex,
                    ToProcess = toProcess,
                    ToValue = toValues
                });
            }
Esempio n. 2
0
        /// <summary>
        /// Writes all messages currently in the queue to MongoDb and acknowledges
        /// </summary>
        protected override void ProcessQueue()
        {
            // Will happen when ProcessQueue is called due to the timer, before we receive our first message
            if (Model == null)
            {
                return;
            }

            lock (LockObj)
            {
                if (ToProcess.Count == 0)
                {
                    return;
                }

                Logger.Info($"Queue contains {ToProcess.Count} message to write");

                foreach ((string modality, List <BsonDocument> modalityDocs) in
                         MongoModalityGroups.GetModalityChunks(ToProcess.Select(x => x.Item1).ToList()))
                {
                    Logger.Debug($"Attempting to write {modalityDocs.Count} documents of modality {modality}");

                    while (FailedWriteAttempts < FailedWriteLimit)
                    {
                        WriteResult imageWriteResult = MongoDbAdapter.WriteMany(modalityDocs, modality);

                        if (imageWriteResult == WriteResult.Success)
                        {
                            Logger.Debug($"Wrote {modalityDocs.Count} documents successfully, sending ACKs");

                            // Hopefully this uses ReferenceEquals, otherwise will be slow...
                            foreach (ulong deliveryTag in ToProcess
                                     .Where(x => modalityDocs.Contains(x.Item1))
                                     .Select(x => x.Item2))
                            {
                                Model.BasicAck(deliveryTag, false);
                            }

                            AckCount           += modalityDocs.Count;
                            FailedWriteAttempts = 0;
                            break;
                        }

                        Logger.Warn($"Failed to write {FailedWriteAttempts + 1} time(s) in a row");

                        if (++FailedWriteAttempts < FailedWriteLimit)
                        {
                            continue;
                        }

                        throw new ApplicationException("Failed write attempts exceeded");
                    }
                }

                Logger.Debug("Wrote and acknowledged all documents in queue. Clearing and continutig");
                ToProcess.Clear();
            }
        }
        public override int GetHashCode()
        {
            var hashCode = -1374379752;

            hashCode = hashCode * -1521134295 + Processed.GetHashCode();
            hashCode = hashCode * -1521134295 + ToProcess.GetHashCode();
            hashCode = hashCode * -1521134295 + Errors.GetHashCode();
            hashCode = hashCode * -1521134295 + Processing.GetHashCode();
            return(hashCode);
        }
Esempio n. 4
0
        /// <summary>
        /// Writes all messages currently in the queue to MongoDb and acknowledges
        /// </summary>
        protected override void ProcessQueue()
        {
            // Will happen when ProcessQueue is called before we receive our first message
            if (Model == null)
            {
                return;
            }

            lock (LockObj)
            {
                if (ToProcess.Count == 0)
                {
                    return;
                }

                Logger.Debug("SeriesMessageProcessor: Queue contains " + ToProcess.Count + " message to write");

                IEnumerable <string> batchDirectories = ToProcess.Select(t => t.Item1.GetValue("header")["DirectoryPath"].AsString).Distinct();
                Logger.Trace($"Writing series from directories: {string.Join(", ", batchDirectories)}");

                WriteResult seriesWriteResult = MongoDbAdapter.WriteMany(ToProcess.Select(t => t.Item1).ToList());

                // Result => Need to differentiate between connection loss and error in the data to be written
                // As well as making sure either all are written or none

                if (seriesWriteResult == WriteResult.Success)
                {
                    Logger.Debug("SeriesMessageProcessor: Wrote " + ToProcess.Count + " messages successfully, sending ACKs");

                    foreach (ulong deliveryTag in ToProcess.Select(t => t.Item2))
                    {
                        Model.BasicAck(deliveryTag, false);
                    }

                    AckCount += ToProcess.Count;
                    ToProcess.Clear();
                    FailedWriteAttempts = 0;
                }
                else
                {
                    Logger.Warn($"SeriesMessageProcessor: Failed to write {FailedWriteAttempts + 1} time(s) in a row");

                    if (++FailedWriteAttempts < FailedWriteLimit)
                    {
                        return;
                    }

                    throw new ApplicationException("Failed write attempts exceeded");
                }
            }
        }
Esempio n. 5
0
        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.WriteEncodedInt(1); //version

            writer.Write(NextRecharge);
            writer.Write(m_Charges);

            if (DateTime.UtcNow > NextRecharge)
            {
                ToProcess.Add(this);
            }
        }
Esempio n. 6
0
 public override void AddToWriteQueue(SeriesMessage message, IMessageHeader header, ulong deliveryTag)
 {
     ToProcess.Enqueue(new Tuple <BsonDocument, ulong>(new BsonDocument {
         { "hello", "world" }
     }, deliveryTag));
 }
Esempio n. 7
0
        public override void AddToWriteQueue(SeriesMessage message, IMessageHeader header, ulong deliveryTag)
        {
            // Only time we are not processing is if we are shutting down anyway
            if (IsStopping)
            {
                return;
            }

            if (Model == null)
            {
                throw new ApplicationException("Model needs to be set before messages can be processed");
            }

            DicomDataset dataset;

            try
            {
                dataset = DicomTypeTranslater.DeserializeJsonToDataset(message.DicomDataset);
            }
            catch (Exception e)
            {
                throw new ApplicationException("Could not deserialize json to dataset", e);
            }

            BsonDocument datasetDoc;

            try
            {
                datasetDoc = DicomTypeTranslaterReader.BuildBsonDocument(dataset);
            }
            catch (Exception e)
            {
                throw new ApplicationException("Exception converting dataset to BsonDocument", e);
            }

            BsonDocument bsonHeader = MongoDocumentHeaders.SeriesDocumentHeader(message);

            BsonDocument document = new BsonDocument()
                                    .Add("header", bsonHeader)
                                    .AddRange(datasetDoc);

            int docByteLength = document.ToBson().Length;

            if (docByteLength > MaxDocumentSize)
            {
                throw new ApplicationException($"BsonDocument was larger than the max allowed size (have {docByteLength}, max is {MaxDocumentSize})");
            }

            var forceProcess = false;

            lock (LockObj)
            {
                ToProcess.Enqueue(new Tuple <BsonDocument, ulong>(document, deliveryTag));

                if (ToProcess.Count >= MaxQueueSize)
                {
                    forceProcess = true;
                }
            }

            if (!forceProcess)
            {
                return;
            }

            Logger.Debug("SeriesMessageProcessor: Max queue size reached, calling ProcessQueue");
            ProcessQueue();
        }
Esempio n. 8
0
        /// <summary>
        /// Asigna los procesos (relaciones de filtro) involucrados en cada entidad.
        /// Esto permite asignar en la metadata que elementos filtran a otros.
        /// y que elementos son filtrados por otros.
        /// </summary>
        /// <param name="asm">Assembly del modelo</param>
        /// <param name="gfc">filtros globales del modelo</param>
        /// <param name="entity">metadata de la entidad</param>
        /// <param name="docProcess">Documentación de los filtros</param>
        /// <returns></returns>
        private static EntityMetadata GetEntityWithProcess(Assembly asm, GlobalFilters gfc, EntityMetadata entity, DocFilter[] docProcess)
        {
            // obtiene los tipos de tipo modelo (las relaciones de filtro solo se encuentran en el modelo).
            var mdlTypes = Common.GetTypeModel(asm);



            if (!docProcess.Any())
            {
                throw new CustomException("No existe documentación de filtros");
            }


            // desde la documentación encontrada, usa los índices para encontrar los filtros en todo el modelo.
            var filterProcess = docProcess.SelectMany(dp => ToProcess.GetFilterProcess(mdlTypes, dp.Index, false, gfc));

            // si no existen filtros, retorna la metadata sin modificar.
            if (!filterProcess.Any())
            {
                // no existen procesos en el modelo.
                return(entity);
            }


            // obtiene los filtros, que tengan como origen la entidad.
            var filterProcessForEntity = filterProcess.Where(s => s.SourceIndex == entity.Index);

            // si existen filtros que tengan la entidad como origen.
            if (filterProcessForEntity.Any())
            {
                // busca documentación para el filtro.
                var docFiltersAvailableForEntity = docProcess.Where(s => filterProcessForEntity.Any(a => a.SourceIndex == entity.Index));

                // documentación de filtros de la entidad.
                if (docFiltersAvailableForEntity.Any())
                {
                    // asigna a la entidad, la documentación de filtros encontrados.
                    entity.DocFilters = docFiltersAvailableForEntity.ToArray();

                    // obtiene los procesos para la entidad.
                    var targetProcesForEntity = filterProcessForEntity.Where(s => s.SourceIndex == entity.Index);

                    // ToProcessFilter indica que entidades esta entidad puede filtrar.
                    if (targetProcesForEntity.Any())
                    {
                        entity.ToProcessFilter = targetProcesForEntity.ToArray();
                    }
                }
            }


            // se encuentan procesos que apunten a esta entidad.
            var filterAvailableForEntity = filterProcess.Where(s => s.TargetRealIndex == entity.Index).ToList();


            // si existe un filtro global en el modelo.
            if (gfc != null)
            {
                // obtiene la colección de rutas del filtro global (índice 0).
                var globalTarget = ToProcess.GetFilterProcess(mdlTypes, 0, true, null);
                // procesos de índice 0 (filtro global).
                var docFiltersAvailableToEntity = docProcess.Where(s => s.Index == 0);

                // el IndexEntityForGlobalFilters determina una entidad en común por filtro global.
                // por ejemplo, para el modelo agricola, es barrack, debido a que
                // los filtros globales filtran barrack y barrack filtra el resto.
                // esta condición se cumplirá solo si el filtro global apunta a la entidad actual.
                if (gfc.IndexEntityForGlobalFilters == entity.Index)
                {
                    // obtiene el listado de elementos que filtra la entidad
                    var lst = entity.FiltersAvailable?.ToList() ?? new List <RelatedItem>();

                    // todos las entidades que pertenecen al globalFilter, filtran o apuntan
                    // directa o indirectamente a una entidad principal.
                    // se asignan como filtros
                    lst.AddRange(globalTarget.Where(s => s.TargetRealIndex == entity.Index).Select(s => new RelatedItem
                    {
                        PathToEntity = s,
                        ClassName    = s.SourceName,
                        docFilter    = docFiltersAvailableToEntity.First(a => a.Index == s.Index),
                        Index        = s.Index
                    }));

                    entity.FiltersAvailable = lst.ToArray();

                    // se quitan los procesos del filtro global que apunten a la entidad principal
                    filterAvailableForEntity = filterAvailableForEntity.Where(s => !(s.TargetRealIndex == entity.Index && s.Index == 0)).ToList();
                }
            }


            // si existen filtros que apunten a la entidad
            if (filterAvailableForEntity.Any())
            {
                // documentos que tangan los índices de los filtros que apuntan a la entidad.
                var docFiltersAvailableToEntity = docProcess.Where(s => filterAvailableForEntity.Any(a => s.Index == a.Index)).ToList();

                if (!docFiltersAvailableToEntity.Any())
                {
                    throw new Exception($"no existe documentación para uno de los siguentes indices {string.Join(",", filterAvailableForEntity.Select(s => s.Index).Distinct().ToArray())}");
                }

                var lst = entity.FiltersAvailable?.ToList() ?? new List <RelatedItem>();

                // asigna todas las entidades que filtran la entidad.
                lst.AddRange(filterAvailableForEntity.Select(s => new RelatedItem
                {
                    PathToEntity = s,
                    ClassName    = s.SourceName,
                    docFilter    = docFiltersAvailableToEntity.First(a => a.Index == s.Index),
                    Index        = s.Index
                }));
                entity.FiltersAvailable = lst.ToArray();
            }

            // entidad con los procesos (filtros).
            return(entity);
        }