예제 #1
0
파일: Client.cs 프로젝트: GodLesZ/svn-dump
		/// <summary>
		/// Registers an IEndpointPushHandler for the specified endpoint to handle pushing messages.
		/// </summary>
		/// <param name="handler">The IEndpointPushHandler to register.</param>
		/// <param name="endpointId">The endpoint identity to register for.</param>
		public void RegisterEndpointPushHandler(IEndpointPushHandler handler, string endpointId) {
			if (_endpointPushHandlers == null) {
				lock (this.SyncRoot) {
					if (_endpointPushHandlers == null)
						_endpointPushHandlers = new CopyOnWriteDictionary(1);
				}
			}
			if (_endpointPushHandlers.ContainsKey(endpointId)) {
				MessageException me = new MessageException();
				me.FaultCode = EndpointPushHandlerAlreadyRegistered.ToString();
				throw me;
			}
			_endpointPushHandlers.Add(endpointId, handler);
		}
예제 #2
0
		public override object Invoke(IMessage message) {
			object result = null;
			RemotingMessage remotingMessage = message as RemotingMessage;
			string operation = remotingMessage.operation;
			string className = this.DestinationDefinition.Properties.Source;
			//This property is provided for backwards compatibility. The best practice, however, is to not expose the underlying source of a 
			//RemoteObject destination on the client and only one source to a destination.
			if (remotingMessage.source != null && remotingMessage.source != string.Empty) {
				if (className == "*")
					className = remotingMessage.source;
				if (className != remotingMessage.source) {
					string msg = __Res.GetString(__Res.Type_MismatchMissingSource, remotingMessage.source, this.DestinationDefinition.Properties.Source as string);
					throw new MessageException(msg, new TypeLoadException(msg));
				}
			}

			if (className == null)
				throw new TypeInitializationException("null", null);

			//Service mapping obsolete for Flex Remoting
			/*
			if (FluorineConfiguration.Instance.ServiceMap != null)
			{
				string method = remotingMessage.operation;
				if (FluorineConfiguration.Instance.ServiceMap.Contains(className))
				{
					string serviceLocation = FluorineConfiguration.Instance.ServiceMap.GetServiceLocation(className);
					method = FluorineConfiguration.Instance.ServiceMap.GetMethod(className, method);
					if (log != null && log.IsDebugEnabled)
						log.Debug(__Res.GetString(__Res.Service_Mapping, className + "." + remotingMessage.operation, serviceLocation + "." + method));

					className = serviceLocation;
					remotingMessage.operation = method;
				}
			}
			*/
			//Cache check
			string source = className + "." + operation;
			IList parameterList = remotingMessage.body as IList;
			string key = GodLesZ.Library.Amf.Configuration.CacheMap.GenerateCacheKey(source, parameterList);
			if (FluorineConfiguration.Instance.CacheMap.ContainsValue(key)) {
				result = GodLesZ.Library.Amf.Configuration.FluorineConfiguration.Instance.CacheMap.Get(key);
				if (result != null) {
					if (log != null && log.IsDebugEnabled)
						log.Debug(__Res.GetString(__Res.Cache_HitKey, operation, key));
					return result;
				}
			}

			FactoryInstance factoryInstance = this.Destination.GetFactoryInstance();
			factoryInstance.Source = className;
			object instance = factoryInstance.Lookup();

			if (instance != null) {
				try {
					Type type = instance.GetType();
					bool isAccessible = TypeHelper.GetTypeIsAccessible(type);
					if (!isAccessible) {
						string msg = __Res.GetString(__Res.Type_InitError, type.FullName);
						throw new MessageException(msg, new TypeLoadException(msg));
					}

					MethodInfo mi = MethodHandler.GetMethod(type, operation, parameterList);
					if (mi != null) {
						try {
							//Messagebroker checked xml configured security, check attributes too
							object[] roleAttributes = mi.GetCustomAttributes(typeof(RoleAttribute), true);
							if (roleAttributes != null && roleAttributes.Length == 1) {
								RoleAttribute roleAttribute = roleAttributes[0] as RoleAttribute;
								string[] roles = roleAttribute.Roles.Split(',');

								bool authorized = this.Destination.Service.GetMessageBroker().LoginManager.DoAuthorization(roles);
								if (!authorized)
									throw new UnauthorizedAccessException(__Res.GetString(__Res.Security_AccessNotAllowed));
							}

							ParameterInfo[] parameterInfos = mi.GetParameters();
							object[] args = new object[parameterInfos.Length];
							parameterList.CopyTo(args, 0);
							TypeHelper.NarrowValues(args, parameterInfos);
							InvocationHandler invocationHandler = new InvocationHandler(mi);
							result = invocationHandler.Invoke(instance, args);
						} catch (TargetInvocationException exception) {
							MessageException messageException = null;
							if (exception.InnerException is MessageException)
								messageException = exception.InnerException as MessageException;//User code throws MessageException
							else
								messageException = new MessageException(exception.InnerException);

							if (log.IsDebugEnabled)
								log.Debug(__Res.GetString(__Res.Invocation_Failed, mi.Name, messageException.Message));
							return messageException.GetErrorMessage();
							//Do not throw here, we do not want to log user code exceptions.
							//throw messageException;
						}

					} else
						throw new MessageException(new MissingMethodException(className, operation));
				} catch (MessageException) {
					throw;
				} catch (Exception exception) {
					MessageException messageException = new MessageException(exception);
					throw messageException;
				} finally {
					factoryInstance.OnOperationComplete(instance);
				}
			} else
				throw new MessageException(new TypeInitializationException(className, null));

			if (FluorineConfiguration.Instance.CacheMap != null && FluorineConfiguration.Instance.CacheMap.ContainsCacheDescriptor(source)) {
				//The result should be cached
				CacheableObject cacheableObject = new CacheableObject(source, key, result);
				FluorineConfiguration.Instance.CacheMap.Add(cacheableObject.Source, cacheableObject.CacheKey, cacheableObject);
				result = cacheableObject;
			}
			return result;
		}
예제 #3
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;
			}
		}
예제 #4
0
		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;
		}