/// <summary> /// Apply changes sent by a client to the server. /// </summary> /// <param name="serverBlob">Blob sent in the incoming request</param> /// <param name="entities">Changes from the client</param> /// <returns>Response containing the new knowledge and conflict/error information.</returns> public ApplyChangesResponse ApplyChanges(byte[] serverBlob, List<IOfflineEntity> entities) { WebUtil.CheckArgumentNull(serverBlob, "serverBlob"); WebUtil.CheckArgumentNull(entities, "entities"); if (0 == serverBlob.Length) { throw new InvalidOperationException("serverBlob is empty"); } var syncBlob = new SyncBlob(); SyncBlob incomingBlob = SyncBlob.DeSerialize(serverBlob); PopulateClientScopeNameAndSyncId(incomingBlob); // Set the scope name in the response blob. syncBlob.ClientScopeName = incomingBlob.ClientScopeName; // If the requested scope does not exists, then throw an error since we // don't initialize scopes on upload requests. if (!CheckIfScopeExists()) { throw SyncServiceException.CreateResourceNotFound("Scope does not exist"); } byte[] clientKnowledgeBlob = incomingBlob.ClientKnowledge; // Initialize a SqlSyncProvider object. _sqlSyncProvider = CreateSqlSyncProviderInstance(_clientScopeName, _serverConnectionString, _configuration.SyncObjectSchema); var response = new ApplyChangesResponse(); // Deserialize the knowledge or create new empty knowledge. SyncKnowledge clientKnowledge = GetSyncKnowledgeFromBlob(clientKnowledgeBlob); // If there are no entities to upload, then return the client knowledge as is. if (entities.Count == 0) { response.Conflicts = new List<SyncConflict>(); response.Errors = new List<SyncError>(); syncBlob.ClientKnowledge = clientKnowledge.Serialize(); response.ServerBlob = syncBlob.Serialize(); return response; } // Client never has any forgotten knowledge. So create a new one. var forgottenKnowledge = new ForgottenKnowledge(_sqlSyncProvider.IdFormats, clientKnowledge); // Convert the entities to dataset using the custom converter. DataSet changesDS = _converter.ConvertEntitiesToDataSet(entities); var stats = new SyncSessionStatistics(); var sessionContext = new SyncSessionContext(_sqlSyncProvider.IdFormats, new SyncCallbacks()); _sqlSyncProvider.BeginSession(SyncProviderPosition.Remote, sessionContext); ulong tickCount = 0; SyncKnowledge updatedClientKnowldege; try { uint batchSize; SyncKnowledge serverKnowledge; // This gives us the server knowledge. _sqlSyncProvider.GetSyncBatchParameters(out batchSize, out serverKnowledge); var changeBatch = new ChangeBatch(_sqlSyncProvider.IdFormats, clientKnowledge, forgottenKnowledge); changeBatch.SetLastBatch(); //Note: There is a possiblity of (-ve) item exceptions , between two uploads from the // same client (for example: in case of RI failures). This would result in an incorrect value if the function // FindMinTickCountForReplica is used to get the last tickcount. So, we need to ignore the -ve item exceptions // when finding the tickcount for the client replica from the server knowledge. /* Logic: * SyncKnowledge.GetKnowledgeForItemId could be used for itemid Zero and then we can find the mintickcount for client replica id. * This does not however seem to work, so we use the KnowledgeInspector and enumerate over each ClockVector * and find the client clockvector and get its tickcount. * * Assumption: The above approach assumes that we don't have any positive exceptions in the knowledge. */ try { // Check if the client replica key exists. uint clientReplicaKey = serverKnowledge.ReplicaKeyMap.LookupReplicaKey(_clientSyncId); var ki = new KnowledgeInspector(1, serverKnowledge); var clockVector = (ClockVector)ki.ScopeClockVector; int noOfReplicaKeys = clockVector.Count; for (int i = noOfReplicaKeys - 1; i >= 0; i--) { if (clockVector[i].ReplicaKey == clientReplicaKey) { tickCount = clockVector[i].TickCount; break; } } } catch (ReplicaNotFoundException exception) { SyncTracer.Info("ReplicaNotFoundException. NEW CLIENT. Exception details: {0}", WebUtil.GetExceptionMessage(exception)); // If the knowedge does not contain the client replica (first apply), initialize tickcount to zero. tickCount = 0; } // Increment the tickcount tickCount++; // update the made with knowledge to include the new tickcount. updatedClientKnowldege = new SyncKnowledge(_sqlSyncProvider.IdFormats, _clientSyncId, tickCount); updatedClientKnowldege.Combine(clientKnowledge); // The incoming data does not have metadata for each item, so we need to create it at this point. AddSyncColumnsToDataSet(changesDS, tickCount); // Make DbSyncContext var dbSyncContext = new DbSyncContext { IsDataBatched = false, IsLastBatch = true, DataSet = changesDS, MadeWithKnowledge = updatedClientKnowldege, MadeWithForgottenKnowledge = forgottenKnowledge, ScopeProgress = new DbSyncScopeProgress() }; _conflicts = new List<SyncConflict>(); _syncErrors = new List<SyncError>(); // Subscribe to the ApplyChangeFailed event to handle conflicts. _sqlSyncProvider.ApplyChangeFailed += SqlSyncProviderApplyChangeFailed; // Subscribe to the ChangesApplied event to read the server tickcount incase there are any conflicts. _sqlSyncProvider.ChangesApplied += SqlSyncProviderChangesApplied; //NOTE: The ConflictResolutionPolicy pass into the method is IGNORED. // Conflicts can be logged by subscribing to the failed events _sqlSyncProvider.ProcessChangeBatch(Microsoft.Synchronization.ConflictResolutionPolicy.DestinationWins, changeBatch, dbSyncContext, new SyncCallbacks(), stats); if (0 != _conflicts.Count) { _sqlSyncProvider.GetSyncBatchParameters(out batchSize, out serverKnowledge); // The way the current P2P provider works, versions are bumped up when conflicts are resolved on the server. // This would result in us sending the changes to the client on the next download request. We want // to not enumerate that change again on the next request from the same client. // The solution is to get the server knowledge after all changes are applied and then // project the knowledge of each conflictign item and add it as a positive exception to the updated client knowledge. AddConflictItemsKnowledgeToClientKnowledge(updatedClientKnowldege, serverKnowledge); } } finally { _sqlSyncProvider.EndSession(sessionContext); } // Don't send any updates to the server knowledge since the client has not got any updates yet. // This updated knowledge will only include an update to the client tickcount. // The client would obtain the server knowledge when it does a get changes. // If we include the serverknowlege, the client would never get any items that are // between the current server knowledge and the client known server knowledge. syncBlob.ClientKnowledge = updatedClientKnowldege.Serialize(); response.ServerBlob = syncBlob.Serialize(); response.Conflicts = _conflicts; response.Errors = _syncErrors; return response; }
public override void ProcessChangeBatch(ConflictResolutionPolicy resolutionPolicy, ChangeBatch sourceChanges, object changeDataRetriever, SyncCallbacks syncCallbacks, SyncSessionStatistics sessionStatistics) { SyncSessionStatistics stats = Proxy.ApplyChanges(resolutionPolicy, sourceChanges, changeDataRetriever); sessionStatistics.ChangesApplied += stats.ChangesApplied; sessionStatistics.ChangesFailed += stats.ChangesFailed; }
public override void ProcessChangeBatch(ConflictResolutionPolicy resolutionPolicy, ChangeBatch sourceChanges, object changeDataRetriever, SyncCallbacks syncCallbacks, SyncSessionStatistics sessionStatistics) { DbSyncContext context = changeDataRetriever as DbSyncContext; // Check if the data is batched if (context != null && context.IsDataBatched) { string filename = new FileInfo(context.BatchFileName).Name; // Retrieve the remote id from the MadeWithKnowledge.ReplicaId. MadeWithKnowledge is the local knowledge of the peer // that is enumerating the changes string remoteId = context.MadeWithKnowledge.ReplicaId.ToString(); // Check if service already has this file if (!Proxy.HasUploadedBatchFile(filename, remoteId)) { // Upload this file to remote service byte[] content = null; using (Stream stream = new FileStream(context.BatchFileName, FileMode.Open, FileAccess.Read)) { content = new byte[stream.Length]; stream.Read(content, 0, content.Length); } if (content != null) { Proxy.UploadBatchFile(filename, content, remoteId); } } context.BatchFileName = filename; } SyncSessionStatistics stats = Proxy.ApplyChanges(resolutionPolicy, sourceChanges, changeDataRetriever); sessionStatistics.ChangesApplied += stats.ChangesApplied; sessionStatistics.ChangesFailed += stats.ChangesFailed; }
public SyncSessionStatistics ApplyChanges(ConflictResolutionPolicy resolutionPolicy, ChangeBatch sourceChanges, object changeData) { SyncSessionStatistics sessionStatistics = new SyncSessionStatistics(); Provider.ProcessChangeBatch(resolutionPolicy, sourceChanges, changeData, new SyncCallbacks(), sessionStatistics); return(sessionStatistics); }
public override void ProcessFullEnumerationChangeBatch( ConflictResolutionPolicy resolutionPolicy, FullEnumerationChangeBatch sourceChanges, object changeDataRetriever, SyncCallbacks syncCallbacks, SyncSessionStatistics sessionStatistics) { throw new NotImplementedException(); }
public SyncSessionStatistics ApplyChanges(ConflictResolutionPolicy resolutionPolicy, ChangeBatch sourceChanges, object changeData) { Log("ProcessChangeBatch: {0}", this.peerProvider.Connection.ConnectionString); DbSyncContext dataRetriever = changeData as DbSyncContext; if (dataRetriever != null && dataRetriever.IsDataBatched) { string remotePeerId = dataRetriever.MadeWithKnowledge.ReplicaId.ToString(); //Data is batched. The client should have uploaded this file to us prior to calling ApplyChanges. //So look for it. //The Id would be the DbSyncContext.BatchFileName which is just the batch file name without the complete path string localBatchFileName = null; if (!this.batchIdToFileMapper.TryGetValue(dataRetriever.BatchFileName, out localBatchFileName)) { //Service has not received this file. Throw exception throw new FaultException <WebSyncFaultException>(new WebSyncFaultException("No batch file uploaded for id " + dataRetriever.BatchFileName, null)); } dataRetriever.BatchFileName = localBatchFileName; } SyncSessionStatistics sessionStatistics = new SyncSessionStatistics(); this.peerProvider.ProcessChangeBatch(resolutionPolicy, sourceChanges, changeData, new SyncCallbacks(), sessionStatistics); return(sessionStatistics); }
public override void ProcessChangeBatch(ConflictResolutionPolicy resolutionPolicy, ChangeBatch sourceChanges, object changeDataRetriever, SyncCallbacks syncCallback, SyncSessionStatistics sessionStatistics) { SyncSessionStatistics remoteSessionStatistics = new SyncSessionStatistics(); syncProxy.ApplyChanges(resolutionPolicy, sourceChanges, changeDataRetriever, ref remoteSessionStatistics); sessionStatistics.ChangesApplied = remoteSessionStatistics.ChangesApplied; sessionStatistics.ChangesFailed = remoteSessionStatistics.ChangesFailed; }
public override void ProcessChangeBatch(ConflictResolutionPolicy resolutionPolicy, ChangeBatch sourceChanges, object changeDataRetriever, SyncCallbacks syncCallback, SyncSessionStatistics sessionStatistics) { _metadataStore.BeginTransaction(); IEnumerable<ItemChange> localChanges = _metadataStore.Metadata.GetLocalVersions(sourceChanges); NotifyingChangeApplier changeApplier = new NotifyingChangeApplier(_idFormats); changeApplier.ApplyChanges(resolutionPolicy, sourceChanges, changeDataRetriever as IChangeDataRetriever, localChanges, _metadataStore.Metadata.GetKnowledge(), _metadataStore.Metadata.GetForgottenKnowledge(), _changeApplier, _currentSessionContext, syncCallback); _metadataStore.CommitTransaction(); }
public void ApplyChanges( ConflictResolutionPolicy resolutionPolicy, ChangeBatch sourceChanges, object changeData, ref SyncSessionStatistics sessionStatistics) { SyncCallbacks syncCallback = new SyncCallbacks(); peerProvider.ProcessChangeBatch(resolutionPolicy, sourceChanges, changeData, syncCallback, sessionStatistics); }
public override void ProcessFullEnumerationChangeBatch( ConflictResolutionPolicy resolutionPolicy, FullEnumerationChangeBatch sourceChanges, object changeDataRetriever, SyncCallbacks syncCallback, SyncSessionStatistics sessionStatistics) { CachedChangeDataRetriever cachedChangeDataRetriever = new CachedChangeDataRetriever( changeDataRetriever as IChangeDataRetriever, sourceChanges); byte[] newChangeApplierInfo = this.client.ProcessFullEnumerationChangeBatch( resolutionPolicy, sourceChanges, cachedChangeDataRetriever, this.syncSessionContext.ChangeApplierInfo); this.syncSessionContext.ChangeApplierInfo = newChangeApplierInfo; }
public override void ProcessChangeBatch(ConflictResolutionPolicy resolutionPolicy, ChangeBatch sourceChanges, object changeDataRetriever, SyncCallbacks syncCallbacks, SyncSessionStatistics sessionStatistics) { var context = changeDataRetriever as DbSyncContext; if (context != null && context.IsDataBatched) { var fileName = new FileInfo(context.BatchFileName).Name; //Retrieve the remote peer id from the MadeWithKnowledge.ReplicaId. //MadeWithKnowledge is the local knowledge of the peer //that is enumerating the changes. var peerId = context.MadeWithKnowledge.ReplicaId.ToString(); //Check to see if service already has this file if (!_proxy.HasUploadedBatchFile(fileName, peerId)) { //Upload this file to remote service var stream = new FileStream(context.BatchFileName, FileMode.Open, FileAccess.Read); var contents = new byte[stream.Length]; using (stream) { stream.Read(contents, 0, contents.Length); } _proxy.UploadBatchFile(fileName, contents, peerId); } context.BatchFileName = fileName; } var stats = _proxy.ApplyChanges(resolutionPolicy, sourceChanges, changeDataRetriever); sessionStatistics.ChangesApplied += stats.ChangesApplied; sessionStatistics.ChangesFailed += stats.ChangesFailed; }
public override void ProcessChangeBatch( ConflictResolutionPolicy resolutionPolicy, ChangeBatch sourceChanges, object changeDataRetriever, SyncCallbacks syncCallback, SyncSessionStatistics sessionStatistics) { try { CachedChangeDataRetriever cachedChangeDataRetriever = new CachedChangeDataRetriever( changeDataRetriever as IChangeDataRetriever, sourceChanges); byte[] newChangeApplierInfo = this.client.ProcessChangeBatch( resolutionPolicy, sourceChanges, cachedChangeDataRetriever, this.syncSessionContext.ChangeApplierInfo); this.syncSessionContext.ChangeApplierInfo = newChangeApplierInfo; } catch (Exception ex) { Console.WriteLine(ex.Message); } }
public SyncSessionStatistics ApplyChanges(ConflictResolutionPolicy resolutionPolicy, ChangeBatch sourceChanges, object changeData) { DbSyncContext dataRetriever = changeData as DbSyncContext; if (dataRetriever != null && dataRetriever.IsDataBatched) { string remotePeerId = dataRetriever.MadeWithKnowledge.ReplicaId.ToString(); //Data is batched. The client should have uploaded this file to us prior to calling ApplyChanges. //So look for it. //The Id would be the DbSyncContext.BatchFileName which is just the batch file name without the complete path string localBatchFileName = null; if (!this.batchIdToFileMapper.TryGetValue(dataRetriever.BatchFileName, out localBatchFileName)) { //Service has not received this file. Throw exception throw new FaultException<WebSyncFaultException>(new WebSyncFaultException("No batch file uploaded for id " + dataRetriever.BatchFileName, null)); } dataRetriever.BatchFileName = localBatchFileName; } SyncSessionStatistics sessionStatistics = new SyncSessionStatistics(); this.peerProvider.ProcessChangeBatch(resolutionPolicy, sourceChanges, changeData, new SyncCallbacks(), sessionStatistics); return sessionStatistics; }
public SyncSessionStatistics ApplyChanges(ConflictResolutionPolicy resolutionPolicy, ChangeBatch sourceChanges, object changeData) { DbSyncContext context = changeData as DbSyncContext; // Check to see if data is batched if (context != null && context.IsDataBatched) { string remoteId = context.MadeWithKnowledge.ReplicaId.ToString(); // Data is batched. The client should have uploaded this file to us prior to calling ApplyChanges, so look for it // The id would be the DbSyncContext.BatchFileName which is just the batch filename without the complete path string localBatchFilename = null; if (!batchIdToFileMapper.TryGetValue(context.BatchFileName, out localBatchFilename)) // Service did not received this file { throw new FaultException <WebSyncFaultException>(new WebSyncFaultException(string.Format("No batch file uploaded for the id {0}.", context.BatchFileName), null)); } context.BatchFileName = localBatchFilename; } SyncSessionStatistics sessionStatistics = new SyncSessionStatistics(); Provider.ProcessChangeBatch(resolutionPolicy, sourceChanges, changeData, new SyncCallbacks(), sessionStatistics); return(sessionStatistics); }
//If full enumeration is needed because this provider is out of date due to tombstone cleanup, then this method will be called by the engine. public override void ProcessFullEnumerationChangeBatch(ConflictResolutionPolicy resolutionPolicy, FullEnumerationChangeBatch sourceChanges, object changeDataRetriever, SyncCallbacks syncCallback, SyncSessionStatistics sessionStatistics) { _metadataStore.BeginTransaction(); //Get all my local change versions from the metadata store IEnumerable<ItemChange> localChanges = _metadata.GetFullEnumerationLocalVersions(sourceChanges); //Create a changeapplier object to make change application easier (make the engine call me //when it needs data and when I should save data) NotifyingChangeApplier changeApplier = new NotifyingChangeApplier(_idFormats); changeApplier.ApplyFullEnumerationChanges(resolutionPolicy, sourceChanges, changeDataRetriever as IChangeDataRetriever, localChanges, _metadata.GetKnowledge(), _metadata.GetForgottenKnowledge(), this, _currentSessionContext, syncCallback); _metadataStore.CommitTransaction(); }
/// <summary> /// Download Mechanism /// </summary> /// <param name="resolutionPolicy"></param> /// <param name="sourceChanges"></param> /// <param name="changeDataRetriever"></param> /// <param name="syncCallback"></param> /// <param name="sessionStatistics"></param> public override void ProcessChangeBatch(ConflictResolutionPolicy resolutionPolicy, ChangeBatch sourceChanges, object changeDataRetriever, SyncCallbacks syncCallback, SyncSessionStatistics sessionStatistics) { ChangeBatch localVersions = sync.GetChanges(sourceChanges); ForgottenKnowledge destinationForgottenKnowledge = new ForgottenKnowledge(sync.IdFormats, sync.SyncKnowledge); NotifyingChangeApplier changeApplier = new NotifyingChangeApplier(sync.IdFormats); changeApplier.ApplyChanges(resolutionPolicy, CollisionConflictResolutionPolicy.Merge, sourceChanges, (IChangeDataRetriever)changeDataRetriever, localVersions, sync.SyncKnowledge.Clone(), destinationForgottenKnowledge, this, _memConflictLog, currentSessionContext, syncCallback); }
//If full enumeration is needed because this provider is out of date due to tombstone cleanup, then this method will be called by the engine. public override void ProcessFullEnumerationChangeBatch(ConflictResolutionPolicy resolutionPolicy, FullEnumerationChangeBatch sourceChanges, object changeDataRetriever, SyncCallbacks syncCallback, SyncSessionStatistics sessionStatistics) { _metadataStore.BeginTransaction(); //Get all my local change versions from the metadata store IEnumerable <ItemChange> localChanges = _metadata.GetFullEnumerationLocalVersions(sourceChanges); //Create a changeapplier object to make change application easier (make the engine call me //when it needs data and when I should save data) NotifyingChangeApplier changeApplier = new NotifyingChangeApplier(_idFormats); changeApplier.ApplyFullEnumerationChanges(resolutionPolicy, sourceChanges, changeDataRetriever as IChangeDataRetriever, localChanges, _metadata.GetKnowledge(), _metadata.GetForgottenKnowledge(), this, _currentSessionContext, syncCallback); _metadataStore.CommitTransaction(); }
/// <inheritdoc /> public override void ProcessChangeBatch(ConflictResolutionPolicy resolutionPolicy, ChangeBatch sourceChanges, object changeDataRetriever, SyncCallbacks syncCallbacks, SyncSessionStatistics sessionStatistics) { // anyone know how to implement ??? throw new NotImplementedException(); }
/// <summary> /// When overridden in a derived class, processes a set of changes for a full enumeration by applying changes to the item store. /// </summary> /// <param name="resolutionPolicy">The conflict resolution policy to use when this method applies changes.</param> /// <param name="sourceChanges">A batch of changes from the source provider to be applied locally.</param> /// <param name="changeDataRetriever">An object that can be used to retrieve change data. It can be an <see cref="T:Microsoft.Synchronization.IChangeDataRetriever"/> object or a provider-specific object.</param> /// <param name="syncCallbacks">An object that receives event notifications during change application.</param> /// <param name="sessionStatistics">Tracks change statistics. For a provider that uses custom change application, this object must be updated with the results of the change application.</param> public override void ProcessFullEnumerationChangeBatch(ConflictResolutionPolicy resolutionPolicy, FullEnumerationChangeBatch sourceChanges, object changeDataRetriever, SyncCallbacks syncCallbacks, SyncSessionStatistics sessionStatistics) { CachedChangeDataRetriever cachedChangeDataRetriever = new CachedChangeDataRetriever( changeDataRetriever as IChangeDataRetriever, sourceChanges); byte[] rawSourceChanges = sourceChanges.Serialize(); byte[] rawCachedChangeDataRetriever = SerializerHelper.BinarySerialize(cachedChangeDataRetriever); byte[] newChangeApplierInfo = _syncService.ProcessFullEnumerationChangeBatch( (int)resolutionPolicy, rawSourceChanges, rawCachedChangeDataRetriever, _syncSessionContext.ChangeApplierInfo); _syncSessionContext.ChangeApplierInfo = newChangeApplierInfo; }
public override void ProcessChangeBatch(ConflictResolutionPolicy resolutionPolicy, ChangeBatch sourceChanges, object changeDataRetriever, SyncCallbacks syncCallbacks, SyncSessionStatistics sessionStatistics) { ItemsChangeInfo localVersions = null; try { localVersions = Proxy.GetChanges(Path, sourceChanges, _filters); } catch (Exception ex) { throw ex; } // Now we call the change applier // The change applier will compare the local and remote versions, apply // non-conflicting changes, and will also detect conflicts and react as specified ForgottenKnowledge = new ForgottenKnowledge(IdFormats, SyncKnowledge); NotifyingChangeApplier changeApplier = new NotifyingChangeApplier(IdFormats); changeApplier.ApplyChanges(resolutionPolicy, sourceChanges, changeDataRetriever as IChangeDataRetriever, RemoteSyncDetails.GenerateChanges(localVersions), SyncKnowledge.Clone(), ForgottenKnowledge, this, SyncSessionContext, syncCallbacks); }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - public override void ProcessChangeBatch(ConflictResolutionPolicy resolutionPolicy, ChangeBatch sourceChanges, ForgottenKnowledge sourceForgottenKnowledge, object changeDataRetriever, SyncCallbacks syncCallback, SyncSessionStatistics sessionStatistics) { throw new NotImplementedException(); }
public override void ProcessChangeBatch(ConflictResolutionPolicy resolutionPolicy, ChangeBatch sourceChanges, object changeDataRetriever, SyncCallbacks syncCallback, SyncSessionStatistics sessionStatistics) { _metadataStore.BeginTransaction(); IEnumerable <ItemChange> localChanges = _metadataStore.Metadata.GetLocalVersions(sourceChanges); NotifyingChangeApplier changeApplier = new NotifyingChangeApplier(_idFormats); changeApplier.ApplyChanges(resolutionPolicy, sourceChanges, changeDataRetriever as IChangeDataRetriever, localChanges, _metadataStore.Metadata.GetKnowledge(), _metadataStore.Metadata.GetForgottenKnowledge(), _changeApplier, _currentSessionContext, syncCallback); _metadataStore.CommitTransaction(); }
public override void ProcessChangeBatch(ConflictResolutionPolicy resolutionPolicy, ChangeBatch sourceChanges, object changeDataRetriever, SyncCallbacks syncCallbacks, SyncSessionStatistics sessionStatistics) { DbSyncContext context = changeDataRetriever as DbSyncContext; if (context != null && context.IsDataBatched) { string fileName = new FileInfo(context.BatchFileName).Name; //Retrieve the remote peer id from the MadeWithKnowledge.ReplicaId. MadeWithKnowledge is the local knowledge of the peer //that is enumerating the changes. string peerId = context.MadeWithKnowledge.ReplicaId.ToString(); //Check to see if service already has this file if (!this.proxy.HasUploadedBatchFile(fileName, peerId)) { //Upload this file to remote service FileStream stream = new FileStream(context.BatchFileName, FileMode.Open, FileAccess.Read); byte[] contents = new byte[stream.Length]; using (stream) { stream.Read(contents, 0, contents.Length); } this.proxy.UploadBatchFile(fileName, contents, peerId); } context.BatchFileName = fileName; } SyncSessionStatistics stats = this.proxy.ApplyChanges(resolutionPolicy, sourceChanges, changeDataRetriever); sessionStatistics.ChangesApplied += stats.ChangesApplied; sessionStatistics.ChangesFailed += stats.ChangesFailed; }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - public override void ProcessFullEnumerationChangeBatch(ConflictResolutionPolicy resolutionPolicy, SyncId destinationVersionEnumerationRangeLowerBound, SyncId destinationVersionEnumerationRangeUpperBound, ChangeBatch sourceChanges, ForgottenKnowledge sourceForgottenKnowledge, object changeDataRetriever, SyncCallbacks syncCallback, SyncSessionStatistics sessionStatistics) { throw new NotImplementedException(); }
/// <inheritdoc /> public override void ProcessFullEnumerationChangeBatch(ConflictResolutionPolicy resolutionPolicy, FullEnumerationChangeBatch sourceChanges, object changeDataRetriever, SyncCallbacks syncCallbacks, SyncSessionStatistics sessionStatistics) { // anyone know how to implement ??? throw new NotImplementedException(); }
/// <summary> /// Upload mechanism /// </summary> /// <param name="resolutionPolicy"></param> /// <param name="sourceChanges">Local File Changes</param> /// <param name="changeDataRetriever"></param> /// <param name="syncCallback"></param> /// <param name="sessionStatistics"></param> public override void ProcessChangeBatch(ConflictResolutionPolicy resolutionPolicy, ChangeBatch sourceChanges, object changeDataRetriever, SyncCallbacks syncCallback, SyncSessionStatistics sessionStatistics) { myForgottenKnowledge = new ForgottenKnowledge(IdFormats, myKnowledge); NotifyingChangeApplier changeApplier = new NotifyingChangeApplier(IdFormats); changeApplier.ApplyChanges(resolutionPolicy, sourceChanges, (IChangeDataRetriever)changeDataRetriever, myKnowledge.Clone(), myForgottenKnowledge, this, currentSessionContext, syncCallback); }
public override void ProcessChangeBatch(ConflictResolutionPolicy resolutionPolicy, ChangeBatch sourceChanges, object changeDataRetriever, SyncCallbacks syncCallbacks, SyncSessionStatistics sessionStatistics) { IEnumerable <ItemChange> localVersions = _sync.GetChanges(sourceChanges); // Now we call the change applier // The change applier will compare the local and remote versions, apply // non-conflicting changes, and will also detect conflicts and react as specified ForgottenKnowledge destinationForgottenKnowledge = new ForgottenKnowledge(_sync.IdFormats, _sync.SyncKnowledge); NotifyingChangeApplier changeApplier = new NotifyingChangeApplier(_sync.IdFormats); changeApplier.ApplyChanges(resolutionPolicy, sourceChanges, changeDataRetriever as IChangeDataRetriever, localVersions, _sync.SyncKnowledge.Clone(), destinationForgottenKnowledge, this, SyncSessionContext, syncCallbacks); }
public override void ProcessFullEnumerationChangeBatch(ConflictResolutionPolicy resolutionPolicy, FullEnumerationChangeBatch sourceChanges, object changeDataRetriever, SyncCallbacks syncCallback, SyncSessionStatistics sessionStatistics) { throw new NotImplementedException("The method or operation is not implemented."); }