/// <summary> /// Gets the protocol record recipients. /// </summary> /// <param name="context">The context.</param> /// <returns></returns> private List<ReplicationNode> getProtocolRecordRecipients(SaveProtocolRecordParams context) { var result = new List<ReplicationNode>(); var reference = context.ProtocolRecord.AuditedObject; if (reference != null && reference.Target != null) { // target object type var ti = context.ObjectSpace.TypesInfo.FindTypeInfo(reference.Target.GetType()); var objType = ti.Type; var modelClass = XafDeltaModule.XafApp.Model.Application.BOModel.GetClass(objType); // prepare context list for select recipients var genType = typeof (RecipientsContext<>).MakeGenericType(objType); var sourceNodes = context.AllNodes; // for broadcast routing type assume the only recipient node is current (sender) node if (Owner.RoutingType == RoutingType.BroadcastRouting) sourceNodes = new List<ReplicationNode> {context.CurrentNode}; var allContext = (from c in sourceNodes select createRecipientContext(context, c, genType)).ToList(); result = selectRecipients(modelClass, allContext).ToList(); // if protocol record's target object is IReplicable then call it's GetRecipients method if (reference.Target is IReplicable) ((IReplicable) reference.Target).GetRecipients( new GetRecipientsEventArgs(context.ProtocolRecord, context.ObjectSpace, result)); } else { if (Owner.RoutingType == RoutingType.BroadcastRouting) result.Add(context.CurrentNode); else result.AddRange(context.AllNodes); } // raise module's GetRecipients event Owner.OnGetRecipients(new GetRecipientsEventArgs(context.ProtocolRecord, context.ObjectSpace, result)); // remove invalid recipients if (Owner.RoutingType != RoutingType.BroadcastRouting) { result.Remove(context.CurrentNode); var disabledNodes = from n in result where n.Disabled select n; result = result.Except(disabledNodes).ToList(); } if (context.ProtocolSession is ExternalProtocolSession) { // prevent package 'reflection' - don't replicate it to nodes already specified in route var externalSession = (ExternalProtocolSession) context.ProtocolSession; var passedNodes = externalSession.Route.Split('\n'); result = (from c in result where !passedNodes.Contains(c.NodeId) select c).ToList(); } return result; }
/// <summary> /// Creates the recipient context. /// </summary> /// <param name="context">The context.</param> /// <param name="recipient">The recipient.</param> /// <param name="genType">Type of the gen.</param> /// <returns></returns> private RecipientsContextBase createRecipientContext(SaveProtocolRecordParams context, ReplicationNode recipient, Type genType) { var result = (RecipientsContextBase)context.ObjectSpace.CreateObject(genType); result.RecipientNode = recipient; result.SenderNode = ReplicationNode.GetCurrentNode(context.ObjectSpace); result.ProtocolRecord = context.ProtocolRecord; /* 11.2.7 */ result.RoutingType = ((IModelReplicationNode)XafDeltaModule.XafApp.Model.GetNode("Replication")).RoutingType; return result; }
/// <summary> /// Creates the package record. /// </summary> /// <param name="context">The context.</param> /// <param name="recipient">The recipient.</param> private void createPackageRecord(SaveProtocolRecordParams context, ReplicationNode recipient) { // skip protocol records registered before last snapshot if (context.ProtocolRecord.ModifiedOn <= recipient.SnapshotDateTime) return; // look for recipient package in context.CreatedPackages dictionary. // if not found then create new one. if(!context.CreatedPackages.ContainsKey(recipient)) { var package = Owner.MessagingService.CreateOutputPackage(context.ObjectSpace, recipient, PackageType.Protocol); package.CreateLogRecord(PackageEventType.Created); context.CreatedPackages.Add(recipient, new PackageSaveInfo { Package = package }); context.Worker.ReportProgress(Color.Green, Localizer.PackageCreated, package.FileName); } // create PackageSession if needed var saveInfo = context.CreatedPackages[recipient]; var packageSession = PackageSession.CreateForProtocolSession(saveInfo.Package.UnitOfWork, context.ProtocolSession, context.CurrentNode.NodeId); saveInfo.CurrentSession = packageSession; // create package protocol record PackageRecord.CreateForProtocolRecord(saveInfo.CurrentSession, context.ProtocolRecord, recipient); }
/// <summary> /// Creates the packages for prepared data. /// </summary> /// <param name="rootContext">The root context.</param> private void createPackages(SaveProtocolParams rootContext) { if (rootContext.Worker.CancellationPending) return; removeEmptySessions(); var i = 0; foreach (var sessionList in BuildSessionInfo.PacketTargets.Values) { rootContext.Worker.ReportPercent((double)i++ / (double)BuildSessionInfo.PacketTargets.Values.Count()); if (rootContext.Worker.CancellationPending) break; foreach (var saveSessionInfo in sessionList) { if (rootContext.Worker.CancellationPending) break; var sessionParams = new SaveProtocolSessionParams(rootContext, saveSessionInfo.ProtocolSession); foreach (var protocolRecord in saveSessionInfo.ProtocolRecords) { if (rootContext.Worker.CancellationPending) break; var recordParams = new SaveProtocolRecordParams(sessionParams, protocolRecord); createPackageRecord(recordParams, saveSessionInfo.TargetNode); } } } BuildSessionInfo.PacketTargets.Clear(); }
/// <summary> /// Specify protocol record recipients. /// </summary> /// <param name="context">The context.</param> private void routeProtocolRecord(SaveProtocolRecordParams context) { var recipients = getProtocolRecordRecipients(context); recipients.ForEach(x => BuildSessionInfo.GetInstance(x, context.ProtocolSession).ProtocolRecords.Add(context.ProtocolRecord)); }