/// <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"); } } }
/// <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); }
/// <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(); } }
/// <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); }
private Guid?GetLastTransactionId() { using (IUnitOfWork uow = Manager.CreateUnitOfWork()) { uow.MapperFactory = this.mapperFactory; CommunicationPackageRepository repo = new CommunicationPackageRepository(uow); return(repo.GetLastReceivedTransacionId(repo.GetDatabaseId())); } }
/// <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); }
/// <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(); } }
/// <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); }
/// <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); }
/// <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; } } } }
/// <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); }
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); }
/// <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; } } } }
/// <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); } }
/// <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(); } }
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); }