Beispiel #1
0
        /// <summary>
        /// Sets the communication package send flag to true.
        /// </summary>
        /// <param name="id">The communication package id.</param>
        private void SetXmlSentWithRetry(Guid id)
        {
            bool isSet      = false;
            int  retryCount = 0;

            using (IUnitOfWork uow = Manager.CreateUnitOfWork())
            {
                uow.MapperFactory = this.mapperFactory;

                CommunicationPackageRepository repo = new CommunicationPackageRepository(uow);
                while (isSet == false && retryCount < 10)
                {
                    try
                    {
                        repo.MarkAsSend(id);
                        isSet = true;
                    }
                    catch (SqlException)
                    {
                        ++retryCount;
                        Wait();
                    }
                }

                if (!isSet)
                {
                    Log.Error("EXCEPTION: CRITICAL ERROR ALERT! What to do with unset (Sets the communication package send flag to true) SetXmlSentWithRetry(Guid id) PackageSender.cs");
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// Executes the local transaction.
        /// </summary>
        /// <param name="packageList">The list of packages belonging to one local transaction.</param>
        /// <param name="unitOfWork"></param>
        /// <returns>
        ///     <c>true</c> if succeeded; otherwise, <c>false</c>.
        /// </returns>
        public bool ExecuteLocalTransaction(IEnumerable <ICommunicationPackage> packageList, IUnitOfWork unitOfWork)
        {
            bool result             = true;
            Guid localTransactionId = Guid.NewGuid();
            Guid currentPackageId   = Guid.Empty;


            this.scriptFactory.UnitOfWork                     = unitOfWork;
            this.scriptFactory.LocalTransactionId             = localTransactionId;
            this.scriptFactory.IsHeadquarter                  = this.isHeadquarter;
            this.scriptFactory.ExecutionController.IsDeffered = true;
            this.scriptFactory.ExecutionController.UnitOfWork = unitOfWork;


            CommunicationPackageRepository repo = new CommunicationPackageRepository(unitOfWork);
            Stopwatch timer = new Stopwatch();

            timer.Start();
            foreach (ICommunicationPackage communicationPackage in packageList)
            {
                var currentPackage = communicationPackage;//.Clone() as ICommunicationPackage;
                currentPackageId = communicationPackage.XmlData.Id;
                this.Log.Info("Wykonywanie paczki: " + communicationPackage.OrderNumber + "=" + currentPackageId);
                if (this.IsExecutionRequired(communicationPackage))
                {
                    XDocument        commXml = XDocument.Parse(communicationPackage.XmlData.Content);
                    IExecutingScript script  = this.scriptFactory.CreateScript(communicationPackage.XmlData.XmlType, commXml);
                    script.UnitOfWork = unitOfWork;
                    script.Log        = this.Log;

                    try
                    {
                        this.BeforePackageExecution(unitOfWork);
                        result = script.ExecutePackage(currentPackage);
                    }
                    catch (ConflictException)
                    {
                        this.Log.Error("Conflict was detected while executing package, id=" + currentPackageId);
                        result = false;
                    }
                }
                else
                {
                    this.Log.Info("Pomijanie paczki: " + currentPackage.OrderNumber + "=" + currentPackageId);
                }

                if (result == false)
                {
                    return(false);
                }
            }

            this.scriptFactory.ExecutionController.RunDefferedActions();
            timer.Stop();
            packageList.ToList().ForEach(p => p.ExecutionTime = timer.Elapsed.TotalSeconds);
            return(result);
        }
Beispiel #3
0
 /// <summary>
 /// Sets whether current branch is headquarter.
 /// </summary>
 /// <param name="connectionManager">The database connection manager.</param>
 private void SetHeadquarterStatus(IDatabaseConnectionManager connectionManager)
 {
     using (IUnitOfWork uow = new UnitOfWork(connectionManager))
     {
         uow.MapperFactory = IoC.Get <IMapperFactory>();
         CommunicationPackageRepository repo = new CommunicationPackageRepository(uow);
         this.isHeadquarter = repo.IsHeadquarter();
     }
 }
Beispiel #4
0
        /// <summary>
        /// Process data that was received by web service method.
        /// </summary>
        /// <param name="data">The data received via web service method call.</param>
        /// <returns>Response to web service client.</returns>
        public object DataReceived(object data)
        {
            SendDataParameters methodParams = (SendDataParameters)data;

            if (methodParams == null)
            {
                return(null);
            }

            SendDataResponse response = new SendDataResponse();

            ICommunicationPackage communicationPackage = (methodParams.Xml == null) ? null : CreateCommunicationPackage(methodParams);

            DatabaseConnector.DatabaseConnectorManager dbm = GetDatabaseConnector();
            dbm.StartModule();
            try
            {
                using (IUnitOfWork uow = new UnitOfWork(dbm))
                {
                    uow.MapperFactory = IoC.Get <IMapperFactory>();
                    uow.StartTransaction(IsolationLevel.Serializable);

                    CommunicationPackageRepository repo = new CommunicationPackageRepository(uow);
                    if (communicationPackage != null)
                    {
                        repo.Add(communicationPackage);
                    }
                    if (methodParams.IsLastInTransaction)
                    {
                        repo.MarkTransactionAsCompleted(communicationPackage.XmlData.LocalTransactionId);
                    }
                    if (methodParams.Statistics != null)
                    {
                        repo.UpdateStatistics(methodParams.Statistics, methodParams.DepartmentIdentifier);
                    }

                    uow.SubmitChanges();
                }
            }
            catch (System.Data.SqlClient.SqlException e)
            {
                response.Result = false;
                Log.Error(e.ToString(), false);
                return(response);
            }
            catch (CommunicationPackageExistsException e) //Xml already in database.
            {
                Log.Info(e.ToString(), false);
            }
            finally
            {
                dbm.StopModule();
            }

            response.Result = true;
            return(response);
        }
Beispiel #5
0
        private Guid?GetLastTransactionId()
        {
            using (IUnitOfWork uow = Manager.CreateUnitOfWork())
            {
                uow.MapperFactory = this.mapperFactory;

                CommunicationPackageRepository repo = new CommunicationPackageRepository(uow);
                return(repo.GetLastReceivedTransacionId(repo.GetDatabaseId()));
            }
        }
Beispiel #6
0
        /// <summary>
        /// Gets the statistics from every registered logger.
        /// </summary>
        /// <returns>Retrieved statistics.</returns>
        private CommunicationStatistics GetStatistics()
        {
            CommunicationStatistics stats = new CommunicationStatistics();

            Logging.LogMessage msg;
            if (this.ExecutorLogger != null)
            {
                msg = this.ExecutorLogger.PopLastMessage();
                if (msg != null)
                {
                    stats.LastExecutionMessage = new MessageData(msg.Message, msg.MessageTime);
                }

                stats.LastExecutionTime = (DateTime?)this.ExecutorLogger.GetProperty("LastExecutionTime");
            }

            if (this.ReceiverLogger != null)
            {
                msg = this.ReceiverLogger.PopLastMessage();
                if (msg != null)
                {
                    stats.LastReceiveMessage = new MessageData(msg.Message, msg.MessageTime);
                }
            }

            if (this.SenderLogger != null)
            {
                msg = this.SenderLogger.PopLastMessage();
                if (msg != null)
                {
                    stats.LastSendMessage = new MessageData(msg.Message, msg.MessageTime);
                }
            }

            using (IUnitOfWork uow = Manager.CreateUnitOfWork())
            {
                uow.MapperFactory = this.mapperFactory;

                CommunicationPackageRepository repo = new CommunicationPackageRepository(uow);
                stats.PackagesToExecute = repo.GetUnprocessedPackagesQuantity();
                stats.PackagesToSend    = repo.GetUndeliveredPackagesQuantity();

                if (String.IsNullOrEmpty(this.Manager.TransmitterConfiguration.AdditionalDataStoreProcedure) == false)
                {
                    string newData = repo.GetAdditionalData(this.Manager.TransmitterConfiguration.AdditionalDataStoreProcedure).ToString(System.Xml.Linq.SaveOptions.DisableFormatting);
                    if (newData != this.additionalData)
                    {
                        stats.AdditionalData = repo.GetAdditionalData(this.Manager.TransmitterConfiguration.AdditionalDataStoreProcedure).ToString(System.Xml.Linq.SaveOptions.DisableFormatting);
                        this.additionalData  = newData;
                    }
                }
            }

            return(stats);
        }
Beispiel #7
0
        /// <summary>
        /// Task main method.
        /// </summary>
        /// <remarks>
        /// Run method steps:
        /// 1. Retrives next package.
        /// 2. Presists package.
        /// 3. Waits before repeating process.
        /// </remarks>
        protected override void Run()
        {
            Guid?lastReceivedXmlId         = null;
            Guid?lastReceivedTransactionId = null;
            Guid databaseId = this.Manager.DatabaseId;

            lastReceivedTransactionId = GetLastTransactionId();

            while (IsEnabled)
            {
                lock (Makolab.Fractus.Communication.Transmitter.TransmitterSemaphore.locker)
                {
                    try
                    {
                        GetDataResponse response = GetNextXmlPackage(lastReceivedXmlId, databaseId);
                        if (lastReceivedTransactionId != null && response != GetDataResponse.ExceptionResponse && (response.XmlData == null || response.XmlData.LocalTransactionId != lastReceivedTransactionId.Value))
                        {
                            using (IUnitOfWork uow = Manager.CreateUnitOfWork())
                            {
                                uow.MapperFactory = this.mapperFactory;
                                CommunicationPackageRepository repo = new CommunicationPackageRepository(uow);
                                repo.MarkTransactionAsCompleted(lastReceivedTransactionId.Value);
                                lastReceivedTransactionId = null;
                            }
                        }

                        if (response.XmlData != null && ProcessXml(response.XmlData, response.DatabaseId) == true)
                        {
                            lastReceivedXmlId         = response.XmlData.Id;
                            lastReceivedTransactionId = response.XmlData.LocalTransactionId;
                        }
                        else
                        {
                            lastReceivedXmlId = null;
                        }

                        if (response.AdditionalData != null && response.AdditionalData.UndeliveredPackagesQuantity != null)
                        {
                            this.WaitingPackages = response.AdditionalData.UndeliveredPackagesQuantity.Value;
                        }
                    }
                    catch (Exception e)
                    {
                        Log.Error(String.Format(CultureInfo.InvariantCulture, "Uncaught exception in PackageReceiver: {0}", e.ToString()));
                    }
                }

                Wait();
            }
        }
Beispiel #8
0
        /// <summary>
        /// Saves the specified xml to storage.
        /// </summary>
        /// <param name="xmlData">The xml to save.</param>
        /// <param name="databaseId">The database id.</param>
        /// <returns>
        ///     <c>true</c> if  is saving successful; otherwise, <c>false</c>.
        /// </returns>
        public bool ProcessXml(XmlTransferObject xmlData, Guid?databaseId)
        {
            bool isSaved = false;
            ICommunicationPackage xml = this.packageFactory.CreatePackage(xmlData);

            xml.DatabaseId = databaseId;
            xml.Decompress();
            if (xml.CheckSyntax())
            {
                int retryCount = 0;
                using (IUnitOfWork uow = Manager.CreateUnitOfWork())
                {
                    uow.MapperFactory = this.mapperFactory;

                    CommunicationPackageRepository repo = new CommunicationPackageRepository(uow);
                    while (isSaved == false && retryCount < 10)
                    {
                        try
                        {
                            repo.Add(xml);
                            isSaved = true;
                        }
                        catch (SqlException)
                        {
                            ++retryCount;
                            Wait();
                        }
                        catch (CommunicationPackageExistsException e) // Xml with the same id exists in db
                        {
                            this.Log.Info(e.ToString(), false);
                            isSaved = true;
                        }
                    }

                    if (!isSaved)
                    {
                        Log.Error("EXCEPTION: CRITICAL ERROR ALERT! What to do with unset (Saves the specified xml to storage) ProcessXml(XmlTransferObject xmlData,Guid? databaseId) PackageReceiver.cs");
                    }
                }
            }
            else
            {
                Log.Error("Invalid xml received, syntax error. Xml id=" + xmlData.Id + " content=" + xmlData.Content);
                ////it shouldnt be received in the first place = validation on the WebService site

                return(false);
            }

            return(isSaved);
        }
        private void ForwardPackage(ICommunicationPackage communicationPackage, Guid targetBranchId)
        {
            XmlTransferObject forwardedPkgData = new XmlTransferObject
            {
                DeferredTransactionId = communicationPackage.XmlData.DeferredTransactionId,
                Id = Guid.NewGuid(),
                LocalTransactionId = Guid.NewGuid(),
                XmlType            = "CommercialDocumentSnapshotEx",
                Content            = this.CurrentPackage.Xml.ToString(System.Xml.Linq.SaveOptions.DisableFormatting)
            };
            ICommunicationPackage pkg = new CommunicationPackage(forwardedPkgData);

            pkg.DatabaseId = Makolab.Fractus.Kernel.Mappers.DictionaryMapper.Instance.GetBranch(targetBranchId).DatabaseId;
            CommunicationPackageRepository pkgRepo = new CommunicationPackageRepository(this.UnitOfWork);

            pkgRepo.PutToOutgoingQueue(pkg);
        }
Beispiel #10
0
        /// <summary>
        /// Process communication package persisting it's data to database.
        /// </summary>
        /// <param name="communicationPackage">The communication package to execute.</param>
        /// <returns>
        ///     <c>true</c> if execution succeeded; otherwise, <c>false</c>
        /// </returns>
        public override bool ExecutePackage(ICommunicationPackage communicationPackage)
        {
            if (base.ExecutePackage(communicationPackage) == false)
            {
                return(false);
            }

            CommunicationPackage payment = PackageExecutionHelper.ExtractPaymentPackage(this.CurrentPackage, communicationPackage);

            if (payment != null)
            {
                payment.XmlData.LocalTransactionId = this.LocalTransactionId;
                var pkgRepo   = new CommunicationPackageRepository(this.UnitOfWork);
                var forwarder = Makolab.Fractus.Commons.DependencyInjection.IoC.Get <IPackageForwarder>();
                forwarder.Log = this.Log;
                forwarder.ForwardPackage(payment, pkgRepo);
            }
            return(true);
        }
Beispiel #11
0
        /// <summary>
        /// Retrives new portion of undelivered packages.
        /// </summary>
        private void GetNewXmlPackages(Guid databaseId)
        {
            if (this.XmlList.Count == 0)
            {
                using (IUnitOfWork uow = Manager.CreateUnitOfWork())
                {
                    uow.MapperFactory = this.mapperFactory;

                    CommunicationPackageRepository repo = new CommunicationPackageRepository(uow);
                    this.XmlList = repo.FindUndeliveredPackages(Manager.TransmitterConfiguration.MaxTransactionCount, databaseId);
                    if (this.XmlList.Count > 0)
                    {
                        this.WaitingPackages = repo.GetUndeliveredPackagesQuantity();
                    }
                    else
                    {
                        this.WaitingPackages = 0;
                    }
                }
            }
        }
Beispiel #12
0
        /// <summary>
        /// Executes group of packages that belongs to specified local transaction.
        /// </summary>
        /// <param name="transactionId">The local transaction id.</param>
        /// <returns><c>true</c> if execution is successful; otherwise, <c>false</c>.</returns>
        private bool ExecuteLocalTransaction(Guid transactionId)
        {
            bool result             = true;
            Guid localTransactionId = Guid.NewGuid();
            IEnumerable <ICommunicationPackage> packages = from communicationPackage in this.XmlList
                                                           where communicationPackage.XmlData.LocalTransactionId == transactionId
                                                           orderby communicationPackage.OrderNumber ascending
                                                           select communicationPackage;

            using (IUnitOfWork uow = Manager.CreateUnitOfWork())
            {
                this.executionManager.BeforeTransactionExecution(uow);
                uow.MapperFactory = this.mapperFactory;
                uow.StartTransaction();

                result = (this.Manager.ExecutorConfiguration.UseCustomPackageExecutor == true) ? this.executionManager.ExecuteLocalTransaction(packages, uow) : this.ExecuteLocalTransaction(packages, uow);
                if (result == true)
                {
                    CommunicationPackageRepository repo = new CommunicationPackageRepository(uow);
                    foreach (var package in packages)
                    {
                        //Console.WriteLine("id=" + package.XmlData.Id);
                        repo.MarkAsExecuted(package.XmlData.Id, package.ExecutionTime);
                        Manager.Log.SetProperty("LastExecutionTime", DateTime.Now);
                        var forwardedPackage = package.Clone() as ICommunicationPackage;
                        forwardedPackage.XmlData.Id = Guid.NewGuid();
                        forwardedPackage.XmlData.LocalTransactionId = localTransactionId;
                        this.packageForwarder.ForwardPackage(forwardedPackage, repo);
                    }
                    uow.SubmitChanges();
                }
                else
                {
                    uow.CancelChanges();
                }
            }


            return(result);
        }
Beispiel #13
0
        private void ExecuteIncomeShift()
        {
            CommunicationPackage statusPkg = GenerateShiftDocumentStatusPackage();

            string oppositeWarehouseFieldId = DictionaryMapper.Instance.GetDocumentField(Makolab.Fractus.Kernel.Enums.DocumentFieldName.ShiftDocumentAttribute_OppositeWarehouseId).Id.Value.ToString().ToUpperInvariant();
            string oppositeWarehouseId      = this.CurrentPackage.Xml.Root.Element("documentAttrValue").Elements()
                                              .Where(row => row.Element("documentFieldId").Value.Equals(oppositeWarehouseFieldId))
                                              .Select(row => row.Element("textValue").Value)
                                              .SingleOrDefault();

            if (oppositeWarehouseId == null)
            {
                throw new InvalidDataException("Missing opposite warehouse id in document attributes");
            }

            Warehouse w = DictionaryMapper.Instance.GetWarehouse(new Guid(oppositeWarehouseId));

            statusPkg.DatabaseId = DictionaryMapper.Instance.GetBranch(w.BranchId).DatabaseId;
            CommunicationPackageRepository pkgRepo = new CommunicationPackageRepository(this.UnitOfWork);

            pkgRepo.PutToOutgoingQueue(statusPkg);
        }
Beispiel #14
0
        /// <summary>
        /// Retrives new portion of unprocessed packages.
        /// </summary>
        private void GetNewXmlPackages()
        {
            if (this.XmlList.Count == 0)
            {
                using (IUnitOfWork uow = Manager.CreateUnitOfWork())
                {
                    uow.MapperFactory = this.mapperFactory;

                    CommunicationPackageRepository repo = new CommunicationPackageRepository(uow);
                    this.XmlList = repo.FindUnprocessedPackages(Manager.ExecutorConfiguration.MaxTransactionCount);

                    if (this.XmlList.Count > 0)
                    {
                        this.WaitingPackages = repo.GetUnprocessedPackagesQuantity();
                    }
                    else
                    {
                        this.WaitingPackages = 0;
                    }
                }
            }
        }
Beispiel #15
0
        /// <summary>
        /// Executes the communication package.
        /// </summary>
        /// <param name="communicationPackage">The communication package to execute.</param>
        /// <returns>
        ///     <c>true</c> if execution succeeded; otherwise, <c>false</c>
        /// </returns>
        public override bool ExecutePackage(ICommunicationPackage communicationPackage)
        {
            SessionManager.VolatileElements.DeferredTransactionId = communicationPackage.XmlData.DeferredTransactionId;
            SessionManager.VolatileElements.LocalTransactionId    = this.LocalTransactionId;

            try
            {
                XDocument commPkg = XDocument.Parse(communicationPackage.XmlData.Content);
                var       commercialDocumentIdElement = commPkg.Root.Element("id");
                if (commercialDocumentIdElement == null || commercialDocumentIdElement.Value.Length == 0)
                {
                    throw new InvalidDataException("Invalid xml data.");
                }
                Guid commercialDocumentId = new Guid(commercialDocumentIdElement.Value);
                var  pkgRepo = new CommunicationPackageRepository(this.UnitOfWork);
                this.repository.UnrelateCommercialDocument(commercialDocumentId, this.LocalTransactionId, communicationPackage.XmlData.DeferredTransactionId, pkgRepo.GetDatabaseId());
                return(true);
            }
            catch (SqlException e)
            {
                this.Log.Error("UnrelateCommercialDocument:ExecutePackage " + e.ToString());
                return(false);
            }
        }
Beispiel #16
0
        /// <summary>
        /// Respond to request for data received by web service method call.
        /// (TODO wtf translate the above comment to english please :) )
        /// </summary>
        /// <param name="data">The data received via web service method call.</param>
        /// <returns>Response to web service client.</returns>
        public object DataRequested(object data)
        {
            GetDataParameters methodParams = (GetDataParameters)data;

            if (methodParams == null)
            {
                return(null);
            }

            DatabaseConnector.DatabaseConnectorManager dbm = GetDatabaseConnector();
            dbm.StartModule();

            //ICommunicationPackageMapper mapper = NullMapperFactory.Instance.CreateMapper<ICommunicationPackageMapper>(dbm);
            List <ICommunicationPackage> packagesQueue = null;

            try
            {
                using (IUnitOfWork uow = new UnitOfWork(dbm))
                {
                    uow.MapperFactory = IoC.Get <IMapperFactory>();
                    CommunicationPackageRepository repo = new CommunicationPackageRepository(uow);
                    if (methodParams.LastReceivedXmlId != null)
                    {
                        repo.MarkAsSend(methodParams.LastReceivedXmlId.Value);
                    }

                    packagesQueue = repo.FindUndeliveredPackages(1, methodParams.LastReceivedXmlId, methodParams.DatabaseId);
                    if (packagesQueue.Count == 0)
                    {
                        return(null);
                    }

                    ICommunicationPackage pkg = packagesQueue.Single(cPkg => cPkg.OrderNumber == packagesQueue.Min(communicationPackage => communicationPackage.OrderNumber));

                    //IEnumerable<ICommunicationPackage> tmp = packagesQueue.Where(cPkg => cPkg.BranchId == methodParams.DatabaseId);
                    //ICommunicationPackage pkg = tmp.Single(cPkg => cPkg.OrderNumber == tmp.Min(communicationPackage => communicationPackage.OrderNumber));
                    //from pkg2 in packagesQueue where pkg2.OrderNumber == packagesQueue.Min(communicationPackage => communicationPackage.OrderNumber) select pkg2;
                    //packagesQueue[packagesQueue.Min(communicationPackage => communicationPackage.OrderNumber) - 1];
                    if (pkg.CheckSyntax() == false)
                    {
                        Log.Error("Invalid xml in outgoing queue.- syntax error. Xml Id=" + pkg.XmlData.Id);
                        return(null);
                    }

                    if (isValidationEnabled)
                    {
                        if (validator == null)
                        {
                            object context = IoC.Get <IContextProvider>().CreateContext(IoC.Container(), "IDatabaseConnectionManager", uow.ConnectionManager);
                            //throws XmlSchemaValidationException
                            this.validator = IoC.Get <IPackageValidator>(context);
                        }
                        this.validator.ConnectionManager = uow.ConnectionManager;
                        this.validator.Validate(pkg);
                    }

                    pkg.Compress();
                    GetDataResponse response = new GetDataResponse();
                    response.XmlData        = pkg.XmlData;
                    response.DatabaseId     = pkg.DatabaseId;
                    response.AdditionalData = GetUndeliveredPackagesQuantity(response.AdditionalData, repo, methodParams);
                    return(response);
                }
            }
            finally
            {
                dbm.StopModule();
            }
        }
Beispiel #17
0
        private AdditionalInfo GetUndeliveredPackagesQuantity(AdditionalInfo additionalData, CommunicationPackageRepository repository, GetDataParameters source)
        {
            int packagesLeft = repository.GetUndeliveredPackagesQuantity(source.DatabaseId);

            if (packagesLeft > 0)
            {
                if (additionalData == null)
                {
                    additionalData = new AdditionalInfo();
                }
                additionalData.UndeliveredPackagesQuantity = packagesLeft;
            }

            return(additionalData);
        }