Example #1
0
        /// <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);
        }
Example #2
0
        /// <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);
        }
Example #3
0
        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);
        }
Example #4
0
        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);
                }
            }
        }
Example #5
0
        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);
        }
Example #6
0
 internal void AddProcessedMessageBatch(MessageBatch messageBatch)
 {
     _processedMessageBatches.Add(messageBatch);
 }
Example #7
0
        /// <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;
            }
        }
		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);
		}
Example #11
0
		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);
				}
			}
		}
Example #12
0
		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;
		}