/// <summary> /// Process the incoming request and forms a formatted outgoing response. /// </summary> /// <param name="incomingRequest">Incoming request</param> /// <returns>Message instance containing the outgoing response</returns> public Message ProcessRequest(Request incomingRequest) { _baseUri = _serviceHost.ServiceBaseUri; _responseSerializationFormat = incomingRequest.ResponseSerializationFormat; _incomingEntities = incomingRequest.EntityList; _idToTempIdMapping = incomingRequest.IdToTempIdMapping; // Check and invoke request interceptor this.PrepareAndProcessRequestInterceptor(); IAsymmetricProviderService providerService = new SqlSyncProviderService(_configuration, Convert.ToString(incomingRequest.CommandParams[CommandParamType.ScopeName]), incomingRequest.ProviderParams, base._operationContext); // Set a callback for the ApplyClientChangeFailed delegate. ((SqlSyncProviderService)providerService).ApplyClientChangeFailed = ClientChangeFailedToApply; // Loop over client input and pull all inserts to a different collection. _incomingNewInsertEntities = _incomingEntities.Where(e => string.IsNullOrEmpty(e.ServiceMetadata.Id)).ToList(); _applyChangesResponse = providerService.ApplyChanges(incomingRequest.SyncBlob, incomingRequest.EntityList); // Give the inserts permanent Ids AssignRealIdsForClientInserts(_incomingNewInsertEntities); // Process the rejected entities if any this.ProcessRejectedEntities((SqlSyncProviderService)providerService); // Check and fire response interceptor this.PrepareAndProcessResponseInterceptor(providerService); var oDataWriter = GetSyncWriterWithContents(); return base.CreateResponseMessage(incomingRequest.ResponseSerializationFormat, oDataWriter); }
/// <summary> /// This function loops the rejected entites and sends back a SyncError for each entity. For each entity it does the following /// 1. Retrieve the current version in server. /// 1.a If its null then it copies the primary key to a new object and marks it as tombstone. /// 2. Adds the SyncError to existing list of SyncErrors. /// </summary> /// <param name="sqlProvider"></param> private void ProcessRejectedEntities(SqlSyncProviderService sqlProvider) { if (this._rejectedEntities == null || this._rejectedEntities.Count == 0) { return; } try { List<IOfflineEntity> serverVersions = sqlProvider.GetCurrentServerVersionForEntities(this._rejectedEntities.Keys); if (serverVersions.Count != this._rejectedEntities.Count) { // Ensure we get a server version for each entity we passed throw new InvalidOperationException("Did not get server versions for all rejected entities."); } for (int i = 0; i < this._rejectedEntities.Keys.Count; i++) { IOfflineEntity server = serverVersions[i]; IOfflineEntity client = this._rejectedEntities.Keys.ElementAt(i); if (server == null) { // This means the server didnt contain a version for the entity. Need to send a tombstone back then // create a new object and copy the values over ConstructorInfo constructorInfo = client.GetType().GetConstructor(Type.EmptyTypes); server = (IOfflineEntity)constructorInfo.Invoke(null); // Copy the primary key values over foreach (PropertyInfo info in ReflectionUtility.GetPrimaryKeysPropertyInfoMapping(client.GetType())) { info.SetValue(server, info.GetValue(client, null), null); } server.ServiceMetadata.IsTombstone = true; } SyncError error = new SyncError() { ErrorEntity = client, LiveEntity = server, Description = this._rejectedEntities[client] }; _applyChangesResponse.Errors.Add(error); } } catch (Exception e) { throw new InvalidOperationException("Error in reading server row values. " + e.Message); } }
/// <summary> /// Process the incoming request and forms a formatted outgoing response. /// </summary> /// <param name="incomingRequest">Incoming request</param> /// <returns>Message instance containing the outgoing response</returns> public Message ProcessRequest(Request incomingRequest) { _baseUri = _serviceHost.ServiceBaseUri; _responseSerializationFormat = incomingRequest.ResponseSerializationFormat; // Check and fire request interceptor. if (_configuration.HasRequestInterceptors(this._scopeName, SyncOperations.Download)) { // Init the SyncOperationContext this.InitRequestOperationContext(); // Fire the request Interceptors if any base.ProcessRequestInterceptors(); } SqlSyncProviderService providerService = new SqlSyncProviderService(_configuration, Convert.ToString(incomingRequest.CommandParams[CommandParamType.ScopeName]), incomingRequest.ProviderParams, base._operationContext); _getChangesResponse = providerService.GetChanges(incomingRequest.SyncBlob); // Check and fire response interceptor. this.PrepareAndProcessResponseInterceptors(); var oDataWriter = GetSyncWriterWithContents(); return base.CreateResponseMessage(incomingRequest.ResponseSerializationFormat, oDataWriter); }