/// <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); }
/// <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); }
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 void ManageMessageBatch(MessageBatch messageBatch, DataServiceTransaction dataServiceTransaction) { DataMessage dataMessage = messageBatch.IncomingMessage; //Manage existing sequences for (int j = 0; j < messageBatch.Messages.Count; j++) { IMessage message = messageBatch.Messages[j] as IMessage; if (message is UpdateCollectionMessage) { UpdateCollectionMessage updateCollectionMessage = message as UpdateCollectionMessage; //update collections, fix sequences IList fillParameters = updateCollectionMessage.collectionId as IList; Sequence sequence = _dataDestination.SequenceManager.GetSequence(fillParameters); if (sequence != null) { ApplyUpdateCollectionMessage(sequence, updateCollectionMessage); } } } for (int j = 0; j < messageBatch.Messages.Count; j++) { DataMessage dataMessageTmp = messageBatch.Messages[j] as DataMessage; if (dataMessageTmp != null) { switch (dataMessageTmp.operation) { case DataMessage.CreateAndSequenceOperation: { //dataMessage.identity contains identity //dataMessage.body contains the object IList result = new ArrayList(); result.Add(dataMessageTmp.body); //Will generate an UpdateCollectionMessage too (server adding item to collection) Sequence sequence = this.CreateSequence(dataMessageTmp.clientId as string, result, null, dataServiceTransaction); SequencedMessage sequencedMessage = this.GetSequencedMessage(dataMessageTmp, sequence); messageBatch.Messages[j] = sequencedMessage; } break; } } } for (int j = 0; j < messageBatch.Messages.Count; j++) { if (messageBatch.Messages[j] is DataMessage) { DataMessage dataMessageTmp = messageBatch.Messages[j] as DataMessage; SyncSequenceChanges(dataMessageTmp, dataServiceTransaction); } if (messageBatch.Messages[j] is SequencedMessage) { SequencedMessage sequencedMessage = messageBatch.Messages[j] as SequencedMessage; DataMessage dataMessageTmp = sequencedMessage.dataMessage; SyncSequenceChanges(dataMessageTmp, dataServiceTransaction); } } }
private AcknowledgeMessage ExecuteMultiBatchOperation(IMessage message) { //May contain multiple batched, create, update or delete operations that involve //more than one destination, that is, more than one remote adapter AcknowledgeMessage responseMessage = null; DataMessage dataMessage = message as DataMessage; IList messages = dataMessage.body as IList; DataServiceTransaction dataServiceTransaction = DataServiceTransaction.Begin(this); dataServiceTransaction.ClientId = message.clientId as string; //correlate al generated messages dataServiceTransaction.CorrelationId = message.messageId; string currentDestination = null; ArrayList currentMessageBatch = new ArrayList(); for (int i = 0; i < messages.Count; i++) { DataMessage batchMessage = messages[i] as DataMessage; string destination = batchMessage.destination; DataDestination dataDestination = GetDestination(batchMessage) as DataDestination; if (currentDestination != null && destination != currentDestination && currentMessageBatch.Count > 0) { MessageBatch messageBatch = ServiceBatch(message, currentMessageBatch); dataServiceTransaction.AddProcessedMessageBatch(messageBatch); currentMessageBatch = new ArrayList(); } currentMessageBatch.Add(batchMessage); currentDestination = destination; if (batchMessage is UpdateCollectionMessage) { dataServiceTransaction.AddClientUpdateCollection(batchMessage as UpdateCollectionMessage); } } if (currentMessageBatch.Count > 0) { MessageBatch messageBatch = ServiceBatch(message, currentMessageBatch); dataServiceTransaction.AddProcessedMessageBatch(messageBatch); } dataServiceTransaction.Commit(); IList outgoingMessages = dataServiceTransaction.GetOutgoingMessages(); responseMessage = new AcknowledgeMessage(); object[] result = new object[outgoingMessages.Count]; outgoingMessages.CopyTo(result, 0); responseMessage.body = result; //outgoingMessages.ToArray(typeof(object)); return(responseMessage); }
internal void AddProcessedMessageBatch(MessageBatch messageBatch) { _processedMessageBatches.Add(messageBatch); }
/// <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); }
/// <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 void ManageMessageBatch(MessageBatch messageBatch, DataServiceTransaction dataServiceTransaction) { DataMessage dataMessage = messageBatch.IncomingMessage; //Manage existing sequences for(int j = 0; j < messageBatch.Messages.Count; j++) { IMessage message = messageBatch.Messages[j] as IMessage; if( message is UpdateCollectionMessage ) { UpdateCollectionMessage updateCollectionMessage = message as UpdateCollectionMessage; //update collections, fix sequences IList fillParameters = updateCollectionMessage.collectionId as IList; Sequence sequence = _dataDestination.SequenceManager.GetSequence(fillParameters); if( sequence != null ) { ApplyUpdateCollectionMessage(sequence, updateCollectionMessage); } } } for (int j = 0; j < messageBatch.Messages.Count; j++) { DataMessage dataMessageTmp = messageBatch.Messages[j] as DataMessage; if (dataMessageTmp != null) { switch (dataMessageTmp.operation) { case DataMessage.CreateAndSequenceOperation: { //dataMessage.identity contains identity //dataMessage.body contains the object IList result = new ArrayList(); result.Add(dataMessageTmp.body); //Will generate an UpdateCollectionMessage too (server adding item to collection) Sequence sequence = this.CreateSequence(dataMessageTmp.clientId as string, result, null, dataServiceTransaction); SequencedMessage sequencedMessage = this.GetSequencedMessage(dataMessageTmp, sequence); messageBatch.Messages[j] = sequencedMessage; } break; } } } for (int j = 0; j < messageBatch.Messages.Count; j++) { if (messageBatch.Messages[j] is DataMessage) { DataMessage dataMessageTmp = messageBatch.Messages[j] as DataMessage; SyncSequenceChanges(dataMessageTmp, dataServiceTransaction); } if (messageBatch.Messages[j] is SequencedMessage) { SequencedMessage sequencedMessage = messageBatch.Messages[j] as SequencedMessage; DataMessage dataMessageTmp = sequencedMessage.dataMessage; SyncSequenceChanges(dataMessageTmp, dataServiceTransaction); } } }
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; }
internal void AddProcessedMessageBatch(MessageBatch messageBatch) { _processedMessageBatches.Add(messageBatch); }
/// <summary> /// Clients can call this method to commit the transaction. You should only use this method if /// you used the begin method to create the DataServiceTransaction. /// Otherwise, the gateway will commit or rollback the transaction as necessary. /// </summary> public void Commit() { if (_rollbackOnly) { Rollback(); return; } try { ProcessRefreshFills(); _pushMessages = new ArrayList(); for (int i = 0; i < _processedMessageBatches.Count; i++) { MessageBatch messageBatch = _processedMessageBatches[i] as MessageBatch; if (messageBatch.Messages != null && messageBatch.Messages.Count > 0) { DataDestination dataDestination = _dataService.GetDestination(messageBatch.IncomingMessage) as DataDestination; try { dataDestination.SequenceManager.ManageMessageBatch(messageBatch, this); } catch (Exception ex) { MessageException messageException = new MessageException(ex); ErrorMessage errorMessage = messageException.GetErrorMessage(); errorMessage.correlationId = messageBatch.IncomingMessage.messageId; errorMessage.destination = messageBatch.IncomingMessage.destination; messageBatch.Messages.Clear(); messageBatch.Messages.Add(errorMessage); } for (int j = 0; j < messageBatch.Messages.Count; j++) { IMessage message = messageBatch.Messages[j] as IMessage; if (!(message is ErrorMessage)) { _pushMessages.Add(message); } } } _outgoingMessages.AddRange(messageBatch.Messages); } for (int i = 0; i < _pushMessages.Count; i++) { IMessage message = _pushMessages[i] as IMessage; DataMessage dataMessage = message as DataMessage; if (dataMessage != null) { PushMessage(GetSubscribers(message), message); } } foreach (DictionaryEntry entry in _clientUpdateCollectionMessages) { UpdateCollectionMessage updateCollectionMessage = entry.Value as UpdateCollectionMessage; _outgoingMessages.Add(updateCollectionMessage); PushMessage(GetSubscribers(updateCollectionMessage), updateCollectionMessage); } foreach (DictionaryEntry entry in _updateCollectionMessages) { UpdateCollectionMessage updateCollectionMessage = entry.Value as UpdateCollectionMessage; _outgoingMessages.Add(updateCollectionMessage); PushMessage(GetSubscribers(updateCollectionMessage), updateCollectionMessage); } } finally { _transactionState = TransactionState.Committed; } }