public SyncClient(string synchronizationId, SyncEngine syncEngine, string serverUrl, Dictionary <string, string> httpHeaders) { this.synchronizationId = synchronizationId ?? throw new NullReferenceException(nameof(synchronizationId)); this.syncEngine = syncEngine ?? throw new NullReferenceException(nameof(syncEngine)); this.serverUrl = serverUrl ?? throw new NullReferenceException(nameof(serverUrl)); this.httpHeaders = httpHeaders; }
public static GetChangesParameter FromPayload(JObject payload, SyncEngine syncEngine) { string synchronizationId = payload[nameof(SynchronizationId)].Value <string>(); Dictionary <string, object> customInfo = payload[nameof(CustomInfo)].ToObject <Dictionary <string, object> >(); PayloadAction payloadAction = (PayloadAction)Enum.Parse(typeof(PayloadAction), payload[nameof(PayloadAction)].Value <string>()); GetChangesParameter parameter = new GetChangesParameter(payloadAction, synchronizationId, customInfo); parameter.LastSync = payload[nameof(LastSync)].Value <long>(); parameter.AppliedIds = PayloadHelper.GetAppliedIdsFromPayload(payload[nameof(PayloadAppliedIds)].ToObject <Dictionary <string, List <object> > >(), syncEngine, synchronizationId, customInfo); return(parameter); }
public JObject Process(byte[] syncDataBytes) { if (syncDataBytes == null) { throw new NullReferenceException(nameof(syncDataBytes)); } JObject jsonResult = JsonDefaultResponse(); SyncServerLockObject syncServerLockObject = null; bool lockTaken = false; List <string> log = new List <string>(); SyncEngine.PayloadAction payloadAction = SyncEngine.PayloadAction.Synchronize; SyncEngine.ApplyChangesResult applyChangesResult = null; SyncEngine.GetChangesResult getChangesResult = null; SyncEngine.GetKnowledgeResult getKnowledgeResult = null; SyncEngine.ApplyChangesByKnowledgeResult applyChangesByKnowledgeResult = null; SyncEngine.GetChangesByKnowledgeResult getChangesByKnowledgeResult = null; try { string json = SyncEngine.Decompress(syncDataBytes); JObject payload = JsonConvert.DeserializeObject <JObject>(json); string synchronizationId = payload[nameof(SyncEngine.BaseInfo.SynchronizationId)].Value <string>(); payloadAction = (SyncEngine.PayloadAction)Enum.Parse(typeof(SyncEngine.PayloadAction), payload[nameof(SyncEngine.BaseInfo.PayloadAction)].Value <string>()); lock (serverLock) { if (!serverLockObjects.ContainsKey(synchronizationId)) { SyncServerLockObject newLockObject = new SyncServerLockObject(synchronizationId); serverLockObjects.Add(synchronizationId, newLockObject); } syncServerLockObject = serverLockObjects[synchronizationId]; } Monitor.TryEnter(syncServerLockObject, 0, ref lockTaken); if (!lockTaken) { throw new Exception($"{nameof(SyncServerLockObject.SynchronizationId)}: {syncServerLockObject.SynchronizationId}, Synchronization process is already in progress"); } if (syncEngine.SyncConfiguration.TimeStampStrategy == SyncConfiguration.TimeStampStrategyEnum.GlobalTimeStamp) { if (payloadAction == SyncEngine.PayloadAction.Synchronize) { SyncEngine.ApplyChangesParameter applyChangesParameter = SyncEngine.ApplyChangesParameter.FromPayload(payload); applyChangesParameter.Log = log; syncEngine.ApplyChanges(applyChangesParameter, ref applyChangesResult); } else if (payloadAction == SyncEngine.PayloadAction.SynhronizeReverse) { SyncEngine.GetChangesParameter getChangesParameter = SyncEngine.GetChangesParameter.FromPayload(payload, syncEngine); getChangesParameter.Log = log; syncEngine.GetChanges(getChangesParameter, ref getChangesResult); } else { throw new NotImplementedException(payloadAction.ToString()); } } else if (syncEngine.SyncConfiguration.TimeStampStrategy == SyncConfiguration.TimeStampStrategyEnum.DatabaseTimeStamp) { if (payloadAction == SyncEngine.PayloadAction.Knowledge) { SyncEngine.GetKnowledgeParameter getKnowledgeParameter = SyncEngine.GetKnowledgeParameter.FromPayload(payload); getKnowledgeParameter.Log = log; syncEngine.GetKnowledge(getKnowledgeParameter, ref getKnowledgeResult); } else if (payloadAction == SyncEngine.PayloadAction.Synchronize) { SyncEngine.ApplyChangesByKnowledgeParameter applyChangesByKnowledgeParameter = SyncEngine.ApplyChangesByKnowledgeParameter.FromPayload(payload); applyChangesByKnowledgeParameter.Log = log; syncEngine.ApplyChangesByKnowledge(applyChangesByKnowledgeParameter, ref applyChangesByKnowledgeResult); } else if (payloadAction == SyncEngine.PayloadAction.SynhronizeReverse) { SyncEngine.GetChangesByKnowledgeParameter getChangesByKnowledgeParameter = SyncEngine.GetChangesByKnowledgeParameter.FromPayload(payload); getChangesByKnowledgeParameter.Log = log; syncEngine.GetChangesByKnowledge(getChangesByKnowledgeParameter, ref getChangesByKnowledgeResult); } else { throw new NotImplementedException(payloadAction.ToString()); } } else { throw new NotImplementedException(syncEngine.SyncConfiguration.TimeStampStrategy.ToString()); } } catch (Exception e) { jsonResult["isOK"] = false; jsonResult["errorMessage"] = e.Message; log.Add(e.Message); } finally { if (syncEngine.SyncConfiguration.TimeStampStrategy == SyncConfiguration.TimeStampStrategyEnum.GlobalTimeStamp) { if (payloadAction == SyncEngine.PayloadAction.Synchronize) { if (applyChangesResult != null) { try { jsonResult["payload"] = Convert.ToBase64String(applyChangesResult.GetCompressed()); } catch (Exception e) { string errMsg = $"jsonResult payload in applyChangesResult Error: {e.Message}"; jsonResult["isOK"] = false; jsonResult["errorMessage"] = errMsg; log.Add(errMsg); } } } else if (payloadAction == SyncEngine.PayloadAction.SynhronizeReverse) { if (getChangesResult != null) { try { jsonResult["payload"] = Convert.ToBase64String(getChangesResult.GetCompressed()); } catch (Exception e) { string errMsg = $"jsonResult payload in getChangesResult Error: {e.Message}"; jsonResult["isOK"] = false; jsonResult["errorMessage"] = errMsg; log.Add(errMsg); } } } else { throw new NotImplementedException(payloadAction.ToString()); } } else if (syncEngine.SyncConfiguration.TimeStampStrategy == SyncConfiguration.TimeStampStrategyEnum.DatabaseTimeStamp) { if (payloadAction == SyncEngine.PayloadAction.Knowledge) { if (getKnowledgeResult != null) { try { jsonResult["payload"] = Convert.ToBase64String(getKnowledgeResult.GetCompressed()); } catch (Exception e) { string errMsg = $"jsonResult payload in getKnowledgeResult Error: {e.Message}"; jsonResult["isOK"] = false; jsonResult["errorMessage"] = errMsg; log.Add(errMsg); } } } else if (payloadAction == SyncEngine.PayloadAction.Synchronize) { if (applyChangesByKnowledgeResult != null) { try { jsonResult["payload"] = Convert.ToBase64String(applyChangesByKnowledgeResult.GetCompressed()); } catch (Exception e) { string errMsg = $"jsonResult payload in applyChangesByKnowledgeResult Error: {e.Message}"; jsonResult["isOK"] = false; jsonResult["errorMessage"] = errMsg; log.Add(errMsg); } } } else if (payloadAction == SyncEngine.PayloadAction.SynhronizeReverse) { if (getChangesByKnowledgeResult != null) { try { jsonResult["payload"] = Convert.ToBase64String(getChangesByKnowledgeResult.GetCompressed()); } catch (Exception e) { string errMsg = $"jsonResult payload in getChangesByKnowledgeResult Error: {e.Message}"; jsonResult["isOK"] = false; jsonResult["errorMessage"] = errMsg; log.Add(errMsg); } } } else { throw new NotImplementedException(payloadAction.ToString()); } } else { string errMsg = $"Process finally block Not Implemented Error: {syncEngine.SyncConfiguration.TimeStampStrategy.ToString()}"; jsonResult["isOK"] = false; jsonResult["errorMessage"] = errMsg; log.Add(errMsg); } jsonResult["log"] = JArray.FromObject(log); if (lockTaken) { Monitor.Exit(syncServerLockObject); } } return(jsonResult); }
public SyncServer(SyncEngine syncEngine) { this.syncEngine = syncEngine; }
private async Task <(string errorMessage, JObject payload)> ExecuteOnServer(byte[] compressed, SyncResult syncResult) { JObject payload = null; using (var httpClient = new HttpClient()) { if (httpHeaders != null) { httpHeaders.ToList().ForEach(kvp => { if (httpClient.DefaultRequestHeaders.Contains(kvp.Key)) { httpClient.DefaultRequestHeaders.Remove(kvp.Key); } httpClient.DefaultRequestHeaders.Add(kvp.Key, kvp.Value); }); } using (var multipartFormDataContent = new MultipartFormDataContent()) { ByteArrayContent byteArrayContent = new ByteArrayContent(compressed); multipartFormDataContent.Add(byteArrayContent, "files", "compressed.data"); var response = await httpClient.PostAsync(serverUrl, multipartFormDataContent); if (response.IsSuccessStatusCode) { string responseContent = await response.Content.ReadAsStringAsync(); JObject jObjectResponse = null; try { jObjectResponse = JsonConvert.DeserializeObject <JObject>(responseContent); } catch (Exception eInner) { return($"Unable to parse Response as JObject: {eInner.Message}. Response: {responseContent}", payload); } List <string> serverLog = jObjectResponse["log"].ToObject <List <string> >(); for (int i = 0; i < serverLog.Count; i++) { syncResult.Log.Add($"Server -> {serverLog[i]}"); } if (jObjectResponse.ContainsKey("payload")) { byte[] compressedResponse = Convert.FromBase64String(jObjectResponse["payload"].Value <string>()); string jsonResponse = SyncEngine.Decompress(compressedResponse); payload = JsonConvert.DeserializeObject <JObject>(jsonResponse); } if (jObjectResponse.ContainsKey("errorMessage")) { return($"ServerMessage: {jObjectResponse["errorMessage"].Value<string>()}", payload); } return(null, payload); } else { return($"Response StatusCode: {response.StatusCode}, ReasonPhrase: {response.ReasonPhrase}", payload); } } } }
public SyncClient(string synchronizationId, SyncEngine syncEngine, string serverUrl) : this(synchronizationId, syncEngine, serverUrl, null) { }
public static Dictionary <Type, List <object> > GetAppliedIdsFromPayload(Dictionary <string, List <object> > safeAppliedIds, SyncEngine syncEngine, string synchronizationId, Dictionary <string, object> customInfo) { Dictionary <Type, List <object> > result = new Dictionary <Type, List <object> >(); foreach (var item in safeAppliedIds) { string fullName = UnsafeFullName(item.Key); Type localType = syncEngine.SyncConfiguration.SyncTypes.Where(w => w.FullName == fullName).FirstOrDefault(); if (localType == null) { throw new SyncEngineConstraintException($"Missing localType: {fullName} from AppliedIds"); } if (!result.ContainsKey(localType)) { result[localType] = new List <object>(); } for (int i = 0; i < item.Value.Count; i++) { JValue value = new JValue(item.Value[i]); object localId = syncEngine.TransformIdType(localType, value, null, OperationType.GetChanges, synchronizationId, customInfo); result[localType].Add(localId); } } return(result); }