private UpdateCollectionMessage CreateUpdateCollectionMessage(DataMessage dataMessage, Sequence sequence, Identity identity, int position, int updateMode) { UpdateCollectionMessage updateCollectionMessage = new UpdateCollectionMessage(); // The unique identifier for the collection that was updated. For a collection filled with the // DataService.fill() method this contains an Array of the parameters specified. updateCollectionMessage.collectionId = sequence.Parameters; updateCollectionMessage.destination = dataMessage.destination; updateCollectionMessage.replace = false; updateCollectionMessage.updateMode = updateMode; updateCollectionMessage.messageId = "srv:" + Guid.NewGuid().ToString("D") + ":0"; updateCollectionMessage.correlationId = dataMessage.correlationId; UpdateCollectionRange updateCollectionRange = new UpdateCollectionRange(); // An Array of identity objects that represent which items were either deleted or inserted in the // associated collection starting at the position indicated by the position property updateCollectionRange.identities = new object[1]; //(updateCollectionRange.identities as IList).Add( identity ); (updateCollectionRange.identities as object[])[0] = identity; updateCollectionRange.updateType = UpdateCollectionRange.InsertIntoCollection; updateCollectionRange.position = position; //ArrayList body = new ArrayList(); //body.Add(updateCollectionRange); object[] body = new object[1]; body[0] = updateCollectionRange; updateCollectionMessage.body = body; return updateCollectionMessage; }
public void ReleaseCollectionOperation(DataMessage dataMessage) { lock(_objLock) { int sequenceId = (int)dataMessage.headers[DataMessage.SequenceIdHeader]; if( log != null && log.IsDebugEnabled ) log.Debug(__Res.GetString(__Res.SequenceManager_ReleaseCollection, sequenceId, dataMessage.clientId)); Sequence sequence = GetSequence(sequenceId); IList parameters = dataMessage.body as IList; RemoveSubscriberFromSequence(dataMessage.clientId as string, sequence); } }
public void ReleaseItemOperation(DataMessage dataMessage) { //TODO int sequenceId = (int)dataMessage.headers[DataMessage.SequenceIdHeader]; Sequence sequence = GetSequence(sequenceId); }
private IList Fill(DataMessage dataMessage) { IList result = null; IAssembler assembler = GetAssembler(); if( assembler != null ) { IList parameters = dataMessage.body as IList; if(log != null && log.IsDebugEnabled) log.Debug(assembler.GetType().FullName + " Fill"); result = assembler.Fill(parameters); return result; } return null; }
public SequencedMessage GetPageItems(DataMessage dataMessage) { int sequenceId = (int)dataMessage.headers[DataMessage.SequenceIdHeader]; Sequence sequence = GetSequence(sequenceId); if (sequence != null) { IList DSids = dataMessage.headers["DSids"] as IList; //ArrayList items = new ArrayList(DSids.Count); SequencedMessage sequencedMessage = new SequencedMessage(); object[] items = new object[DSids.Count]; lock (_objLock) { for (int i = 0; i < DSids.Count; i++) { Identity identity = new Identity(DSids[i] as IDictionary); ItemWrapper itemWrapper = GetItem(identity); //items.Add(item); items[i] = itemWrapper.Instance; } sequencedMessage.destination = dataMessage.destination; sequencedMessage.sequenceId = sequence.Id; sequencedMessage.sequenceSize = sequence.Size; sequencedMessage.sequenceProxies = null; sequencedMessage.body = items; } return sequencedMessage; } else { DataServiceException dse = new DataServiceException(string.Format("Sequence {0} in destination {1} was not found", sequenceId, dataMessage.destination)); throw dse; } }
private void ProcessRefreshFills() { for (int i = 0; _refreshFills != null && i < _refreshFills.Count; i++) { RefreshFillData refreshFill = _refreshFills[i] as RefreshFillData; DataDestination dataDestination = _dataService.GetDestination(refreshFill.Destination) as DataDestination; if (dataDestination == null) throw new FluorineException(__Res.GetString(__Res.Destination_NotFound, refreshFill.Destination)); ICollection sequences = dataDestination.SequenceManager.GetSequences(refreshFill.Parameters); if (sequences != null) { lock (dataDestination.SequenceManager.SyncRoot) { foreach (Sequence sequence in sequences) { DataMessage dataMessage = new DataMessage(); dataMessage.operation = DataMessage.FillOperation; if (sequence.Parameters != null) dataMessage.body = sequence.Parameters; else dataMessage.body = new object[0]; if (_clientId != null) dataMessage.clientId = _clientId; else dataMessage.clientId = "srv:" + Guid.NewGuid().ToString("D"); IList result = dataDestination.ServiceAdapter.Invoke(dataMessage) as IList; if (result.Count > 0) { Sequence sequenceTmp = dataDestination.SequenceManager.CreateSequence(dataMessage.clientId as string, result, sequence.Parameters, this); } } } } } }
/// <summary> /// This version of the deleteItem method does not provide for conflict detection if the item has been modified before the delete occurs; it is deleted. /// </summary> /// <param name="destination">Name of the destination containing the item to be deleted.</param> /// <param name="identity">A Hashtable containing entries for each of the id properties for this item (the key is the id property name, the value is its value).</param> public void DeleteItemWithId(string destination, Hashtable identity) { DataMessage dataMessage = new DataMessage(); DataDestination dataDestination = _dataService.GetDestination(destination) as DataDestination; dataMessage.operation = DataMessage.DeleteOperation; dataMessage.body = null; dataMessage.destination = destination; if (_clientId != null) dataMessage.clientId = _clientId; else dataMessage.clientId = "srv:" + Guid.NewGuid().ToString("D"); dataMessage.identity = identity; dataMessage.messageId = "srv:" + Guid.NewGuid().ToString("D") + ":" + _idCounter.ToString(); System.Threading.Interlocked.Increment(ref _idCounter); ArrayList messages = new ArrayList(1); messages.Add(dataMessage); MessageBatch messageBatch = new MessageBatch(dataMessage, messages); AddProcessedMessageBatch(messageBatch); }
public AcknowledgeMessage ManageSequence(DataMessage dataMessage, IList items) { return ManageSequence(dataMessage, items, null); }
public AcknowledgeMessage ManageSequence(DataMessage dataMessage, IList items, DataServiceTransaction dataServiceTransaction) { AcknowledgeMessage acknowledgeMessage = null; switch(dataMessage.operation) { case DataMessage.FillOperation: { Sequence sequence = CreateSequence(dataMessage.clientId as string, items, dataMessage.body as IList, dataServiceTransaction); acknowledgeMessage = GetSequencedMessage(dataMessage, sequence); } break; case DataMessage.GetOperation: case DataMessage.GetSequenceIdOperation: { Sequence sequence = CreateSequence(dataMessage.clientId as string, items, null, dataServiceTransaction); acknowledgeMessage = GetSequencedMessage(dataMessage, sequence); } break; default: { if( log != null && log.IsErrorEnabled ) log.Error(__Res.GetString(__Res.SequenceManager_Unknown, dataMessage.operation)); } break; } return acknowledgeMessage; }
private IMessage Delete(DataMessage dataMessage) { IAssembler assembler = GetAssembler(); if( assembler != null ) { if(log != null && log.IsDebugEnabled) log.Debug(assembler.GetType().FullName + " Delete"); assembler.DeleteItem(dataMessage.body); } return dataMessage; }
private IList Batch(DataMessage dataMessage) { ArrayList result = new ArrayList(); IList messageBatch = dataMessage.body as IList; for(int i = 0; i < messageBatch.Count; i++) { IMessage message = messageBatch[i] as IMessage; try { if( message is UpdateCollectionMessage ) { result.Add(UpdateCollection(message as UpdateCollectionMessage, messageBatch)); } else { object obj = Invoke(message); result.Add(obj); } } catch(DataSyncException dataSyncException) { DataErrorMessage dataErrorMessage = dataSyncException.GetErrorMessage() as DataErrorMessage; dataErrorMessage.cause = message as DataMessage; dataErrorMessage.correlationId = message.messageId; dataErrorMessage.destination = message.destination; result.Add(dataErrorMessage); } catch(Exception exception) { MessageException messageException = new MessageException(exception); ErrorMessage errorMessage = messageException.GetErrorMessage(); errorMessage.correlationId = message.messageId; errorMessage.destination = message.destination; result.Add(errorMessage); } } return result; }
private IMessage Create(DataMessage dataMessage) { IAssembler assembler = GetAssembler(); if( assembler != null ) { if(log != null && log.IsDebugEnabled) log.Debug(assembler.GetType().FullName + " CreateItem"); assembler.CreateItem(dataMessage.body); Identity identity = Identity.GetIdentity(dataMessage.body, this.Destination as DataDestination); dataMessage.identity = identity; } return dataMessage; }
private IMessage Update(DataMessage dataMessage) { IList parameters = dataMessage.body as IList; IList changeObject = parameters[0] as IList; if(changeObject == null || changeObject.Count == 0) return dataMessage; IAssembler assembler = GetAssembler(); if( assembler != null ) { if(log != null && log.IsDebugEnabled) log.Debug(assembler.GetType().FullName + " Update"); assembler.UpdateItem(parameters[2], parameters[1], parameters[0] as IList); } return dataMessage; }
private object GetItem(DataMessage dataMessage) { object result = null; IAssembler assembler = GetAssembler(); if( assembler != null ) { if(log != null && log.IsDebugEnabled) log.Debug(assembler.GetType().FullName + " GetItem"); result = assembler.GetItem(dataMessage.identity); return result; } return null; }
public PagedMessage GetPagedMessage(DataMessage dataMessage, Sequence sequence) { int pageSize = (int)dataMessage.headers[DataMessage.PageSizeHeader]; int pageIndex = 0; if (dataMessage.headers.ContainsKey(DataMessage.PageIndexHeader)) pageIndex = (int)dataMessage.headers[DataMessage.PageIndexHeader]; pageIndex = Math.Max(0, pageIndex);//negative pageIndex??? int pageCount = (int)Math.Ceiling((double)sequence.Size / pageSize); int pageStart = pageIndex * pageSize; int pageEnd = Math.Min(pageStart + pageSize, sequence.Size); PagedMessage pagedMessage = new PagedMessage(); pagedMessage.pageIndex = pageIndex; pagedMessage.pageCount = pageCount; pagedMessage.sequenceSize = sequence.Size; pagedMessage.sequenceId = sequence.Id; object[] pagedResult = new object[pageEnd - pageStart]; lock (_objLock) { for (int i = pageStart; i < pageEnd; i++) { Identity identity = sequence[i]; //pagedResult.Add( _itemIdToItemHash[identity] ); if (_itemIdToItemHash.Contains(identity)) pagedResult[i - pageStart] = (_itemIdToItemHash[identity] as ItemWrapper).Instance; } } pagedMessage.body = pagedResult; pagedMessage.destination = dataMessage.destination; pagedMessage.dataMessage = dataMessage; return pagedMessage; }
void SyncSequenceChanges(DataMessage dataMessage, DataServiceTransaction dataServiceTransaction) { lock(_objLock) { ArrayList sequenceList = new ArrayList(_sequenceIdToSequenceHash.Values.Count); sequenceList.AddRange(_sequenceIdToSequenceHash.Values);//Hashtable may be changed here foreach (Sequence sequence in sequenceList) { switch(dataMessage.operation) { case DataMessage.CreateOperation: case DataMessage.CreateAndSequenceOperation: RefreshSequence(sequence, dataMessage, dataMessage.body, dataServiceTransaction); break; case DataMessage.DeleteOperation: { //RefreshSequence(sequence, dataMessage, dataMessage.body, dataServiceTransaction); Identity identity = Identity.GetIdentity(dataMessage.body, _dataDestination); int index = sequence.IndexOf(identity); if( index != -1 ) RemoveIdentityFromSequence(sequence, identity, dataServiceTransaction); } break; case DataMessage.UpdateOperation: RefreshSequence(sequence, dataMessage, (dataMessage.body as IList)[2], dataServiceTransaction); break; } } } }
public PagedMessage GetPage(DataMessage dataMessage) { int sequenceId = (int)dataMessage.headers[DataMessage.SequenceIdHeader]; Sequence sequence = GetSequence(sequenceId); if (sequence != null) return GetPagedMessage(dataMessage, sequence); else { DataServiceException dse = new DataServiceException(string.Format("Sequence {0} in destination {1} was not found", sequenceId, dataMessage.destination)); throw dse; } }
public Sequence RefreshSequence(Sequence sequence, DataMessage dataMessage, object item, DataServiceTransaction dataServiceTransaction) { if (sequence.Parameters == null) return sequence; DotNetAdapter dotNetAdapter = _dataDestination.ServiceAdapter as DotNetAdapter; if( dotNetAdapter != null ) { bool isCreate = (dataMessage.operation == DataMessage.CreateOperation || dataMessage.operation == DataMessage.CreateAndSequenceOperation); int fill = dotNetAdapter.RefreshFill( sequence.Parameters, item, isCreate ); switch(fill) { case Assembler.ExecuteFill: { IList parameters = sequence.Parameters; //if (parameters == null) // parameters = new object[0]; DataMessage fillDataMessage = new DataMessage(); fillDataMessage.clientId = dataMessage.clientId; fillDataMessage.operation = DataMessage.FillOperation; fillDataMessage.body = parameters != null ? parameters : new object[0]; IList result = _dataDestination.ServiceAdapter.Invoke(fillDataMessage) as IList; return CreateSequence(dataMessage.clientId as string, result, parameters, dataServiceTransaction); } case Assembler.AppendToFill: { Identity identity = Identity.GetIdentity(item, _dataDestination); if( !sequence.Contains(identity) ) AddIdentityToSequence(sequence, identity, dataServiceTransaction); _itemIdToItemHash[identity] = new ItemWrapper(item); } break; case Assembler.RemoveFromFill: { Identity identity = Identity.GetIdentity(item, _dataDestination); if( sequence.Contains(identity) ) RemoveIdentityFromSequence(sequence, identity, dataServiceTransaction); } break; case Assembler.DoNotExecuteFill: break; } } return sequence; }
/// <summary> /// Send an update event to clients subscribed to this message. Note that this method does not send /// the change to the adapter/assembler - it assumes that the changes have already been applied /// or are being applied. It only updates the clients with the new version of this data. /// /// You must supply a destination parameter and a new version of the object. If you supply a /// non-null previous version, this object is used to detect conflicts on the client in case /// the client's version of the data does not match the previous version. You may also supply /// a list of property names that have changed as a hint to the client to indicate which properties /// should be checked for conflicts and updated. If you supply null for the changes, all /// properties on the client are updated. These property names do not accept any kind of dot /// notation to specify that a property of a property has changed. Only top level property /// names are allowed. /// </summary> /// <param name="destination">Name of the Data Management Services destination that is managing the item you want to update.</param> /// <param name="newVersion">New version of the item to update. The identity of the item is used to determine which item to update.</param> /// <param name="previousVersion">If not null, this contains a version of the item you intend to update. The client can detect a conflict if its version does not match the previousVersion. If you specify the value as null, a conflict is only detected if the client has pending changes for the item being updated.</param> /// <param name="changes">Array of property names which are to be updated. You can provide a null value to indicate that all property values may have changed.</param> public void UpdateItem(string destination, object newVersion, object previousVersion, string[] changes) { DataMessage dataMessage = new DataMessage(); DataDestination dataDestination = _dataService.GetDestination(destination) as DataDestination; object[] body = new object[3]; body[0] = changes; body[2] = newVersion; body[1] = previousVersion; dataMessage.operation = DataMessage.UpdateOperation; dataMessage.body = body; dataMessage.destination = destination; if (_clientId != null) dataMessage.clientId = _clientId; else dataMessage.clientId = "srv:" + Guid.NewGuid().ToString("D"); dataMessage.identity = Identity.GetIdentity(newVersion, dataDestination); dataMessage.messageId = "srv:" + Guid.NewGuid().ToString("D") + ":" + _idCounter.ToString(); System.Threading.Interlocked.Increment(ref _idCounter); ArrayList messages = new ArrayList(1); messages.Add(dataMessage); MessageBatch messageBatch = new MessageBatch(dataMessage, messages); _processedMessageBatches.Add(messageBatch); }
public SequencedMessage GetSequencedMessage(DataMessage dataMessage, Sequence sequence) { if( dataMessage.headers != null && dataMessage.headers.ContainsKey(DataMessage.PageSizeHeader) ) { return GetPagedMessage(dataMessage, sequence); } else { SequencedMessage sequencedMessage = new SequencedMessage(); sequencedMessage.destination = dataMessage.destination; sequencedMessage.sequenceId = sequence.Id; sequencedMessage.sequenceSize = sequence.Size; //object[] body = new object[result.Count]; //result.CopyTo(body, 0); object[] body = new object[sequence.Count]; lock(_objLock) { for(int i = 0; i < sequence.Count; i++) { ItemWrapper itemWrapper = GetItem(sequence[i]) as ItemWrapper; if( itemWrapper != null ) body[i] = itemWrapper.Instance; } } sequencedMessage.body = body; sequencedMessage.sequenceProxies = null; sequencedMessage.dataMessage = dataMessage; sequencedMessage.messageId = dataMessage.messageId; sequencedMessage.clientId = dataMessage.clientId; sequencedMessage.correlationId = dataMessage.messageId; //dataMessage.identity = new Hashtable(0); return sequencedMessage; } }
private MessageBatch ServiceBatch(IMessage message, ArrayList messages) { //Send a DataMessage.BatchedOperation to the specific adapter DataMessage dataMessage = messages[0] as DataMessage; DataMessage adapterDataMessage = null; if( messages.Count == 1 && dataMessage.operation == DataMessage.BatchedOperation ) adapterDataMessage = dataMessage; else { adapterDataMessage = new DataMessage(); adapterDataMessage.destination = dataMessage.destination; adapterDataMessage.operation = DataMessage.BatchedOperation; adapterDataMessage.body = messages; adapterDataMessage.headers = message.headers; adapterDataMessage.clientId = message.clientId; } DataDestination dataDestination = GetDestination(dataMessage) as DataDestination; IList result = dataDestination.ServiceAdapter.Invoke(adapterDataMessage) as IList; MessageBatch messageBatch = new MessageBatch(adapterDataMessage, result); return messageBatch; }
public MessageBatch(DataMessage incomingMessage, IList messages) { _incomingMessage = incomingMessage; _messages = messages; }