/// <summary> /// constructor /// </summary> public TClientDomainManager(String AClientID, TClientServerConnectionType AClientServerConnectionType, TClientManagerCallForwarder AClientManagerRef, ISystemDefaultsCache ASystemDefaultsCacheRef, ICacheableTablesManager ACacheableTablesManagerRef, IPrincipal AUserInfo) : base(AClientID, AClientServerConnectionType, AClientManagerRef, "007") { }
/// <summary> /// Loads the ClientDomain DLL into the Client's AppDomain, instantiates the /// main Class (TClientDomainManager) and initialises the AppDomain by calling /// several functions of that Class. /// /// </summary> /// <param name="AClientID">ClientID as assigned by the ClientManager</param> /// <param name="AClientServerConnectionType">Tells in which way the Client connected /// to the PetraServer</param> /// <param name="AClientManagerRef">A reference to the ClientManager object /// (Note: .NET Remoting will be working behind the scenes since calls to /// this Object will cross AppDomains!)</param> /// <param name="ASystemDefaultsCacheRef">A reference to the SystemDefaultsCache object /// (Note: .NET Remoting will be working behind the scenes since calls to /// this Object will cross AppDomains!)</param> /// <param name="ACacheableTablesManagerRef"></param> /// <param name="AUserInfo">An instantiated PetraPrincipal Object, containing User /// information</param> /// <param name="AServerSettings">A copy of the ServerSettings</param> /// <param name="ARemotingURLPollClientTasks">The .NET Remoting URL of the /// TPollClientTasks Class which the Client needs to calls to retrieve /// ClientTasks.</param> /// <param name="ARemotedPollClientTasksObject"></param> public void LoadDomainManagerAssembly(Int32 AClientID, TClientServerConnectionType AClientServerConnectionType, TClientManagerCallForwarder AClientManagerRef, object ASystemDefaultsCacheRef, object ACacheableTablesManagerRef, IPrincipal AUserInfo, TSrvSetting AServerSettings, out String ARemotingURLPollClientTasks, out ICrossDomainService ARemotedPollClientTasksObject) { // Console.WriteLine('TRemoteLoader.LoadDomainManagerAssembly in AppDomain: ' + AppDomain.CurrentDomain.ToString); Assembly LoadedAssembly = Assembly.Load(CLIENTDOMAIN_DLLNAME); FRemoteClientDomainManagerClass = LoadedAssembly.GetType(CLIENTDOMAIN_CLASSNAME); FRemoteClientDomainManagerObject = Activator.CreateInstance(FRemoteClientDomainManagerClass, (BindingFlags.Public | BindingFlags.Instance | BindingFlags.CreateInstance), null, new Object[] { AClientID.ToString(), AClientServerConnectionType, AClientManagerRef, ASystemDefaultsCacheRef, ACacheableTablesManagerRef, AUserInfo }, null); FRemoteClientDomainManagerClass.InvokeMember("InitAppDomain", (BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod), null, FRemoteClientDomainManagerObject, new Object[] { AServerSettings }); // Create and remote the TPollClientTasks Class ARemotingURLPollClientTasks = Convert.ToString(FRemoteClientDomainManagerClass.InvokeMember("GetPollClientTasksURL", (BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod), null, FRemoteClientDomainManagerObject, null, null)); ARemotedPollClientTasksObject = (ICrossDomainService)FRemoteClientDomainManagerClass.InvokeMember("GetRemotedPollClientTasksObject", (BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod), null, FRemoteClientDomainManagerObject, null, null); // Establish (separate) DataBase connection for the AppDomain Convert.ToString(FRemoteClientDomainManagerClass.InvokeMember("EstablishDBConnection", (BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod), null, FRemoteClientDomainManagerObject, null, null)); // Perform any other initialisation required by the AppDomain FRemoteClientDomainManagerClass.InvokeMember("PostAppDomainSetupInitialisation", (BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod), null, FRemoteClientDomainManagerObject, null, null); // LoadClientDomainManager.ClientTaskAdd('USERMESSAGE','This is just for testing purposes!', 'blabla_1', 'blabla_2', 'blabla_3', 'blabla_4', 1); }
/// <summary> /// Loads the ClientDomain DLL into the Client's AppDomain, instantiates the /// main Class (TClientDomainManager) and initialises the AppDomain by calling /// several functions of that Class. /// /// </summary> /// <param name="AClientID">ClientID as assigned by the ClientManager</param> /// <param name="AClientServerConnectionType">Tells in which way the Client connected /// to the PetraServer</param> /// <param name="AClientManagerRef">A reference to the ClientManager object /// (Note: .NET Remoting will be working behind the scenes since calls to /// this Object will cross AppDomains!)</param> /// <param name="ASystemDefaultsCacheRef">A reference to the SystemDefaultsCache object /// (Note: .NET Remoting will be working behind the scenes since calls to /// this Object will cross AppDomains!)</param> /// <param name="ACacheableTablesManagerRef"></param> /// <param name="AUserInfo">An instantiated PetraPrincipal Object, containing User /// information</param> /// <param name="ARemotingURLPollClientTasks">the .NET Remoting URL of the /// TPollClientTasks Class which the Client needs to calls to retrieve /// ClientTasks.</param> /// <returns>void</returns> public void LoadDomainManagerAssembly(Int32 AClientID, TClientServerConnectionType AClientServerConnectionType, TClientManagerCallForwarder AClientManagerRef, object ASystemDefaultsCacheRef, object ACacheableTablesManagerRef, IPrincipal AUserInfo, out String ARemotingURLPollClientTasks) { ICrossDomainService RemoteObject; FRemoteLoader.LoadDomainManagerAssembly(AClientID, AClientServerConnectionType, AClientManagerRef, ASystemDefaultsCacheRef, ACacheableTablesManagerRef, AUserInfo, TSrvSetting.ServerSettings, out ARemotingURLPollClientTasks, out RemoteObject); // register the remote url at the CrossDomainMarshaller TCrossDomainMarshaller.AddService(AClientID.ToString(), ARemotingURLPollClientTasks, RemoteObject); // Load the CallForwinding DLL into the Client's AppDomain FRemoteLoader.LoadCallForwardingAssembly(); // IMPORTANT: If the following code is uncommented, the ClientDomain DLL that is loaded only in the Client's AppDomain might get loaded into the Default AppDomain that's what we don't want!!! // Use this therefore only to find out what DLL's are loaded in the Client's AppDomain!!!!!! if (TLogging.DL >= 10) { TLogging.Log( "Loaded Assemblies in AppDomain " + AppDomain.CurrentDomain.FriendlyName + ": (after instantiation of TClientDomainManager)", TLoggingType.ToConsole | TLoggingType.ToLogfile); foreach (Assembly tmpAssembly in AppDomain.CurrentDomain.GetAssemblies()) { TLogging.Log(tmpAssembly.FullName, TLoggingType.ToConsole | TLoggingType.ToLogfile); } } }
/// <summary> /// Sets up .NET Remoting Lifetime Services and TCP Channel for this AppDomain. /// /// @comment WARNING: If you need to change the parameters of the Constructor, /// you also need to change the parameters in the .NET Reflection call in /// TClientAppDomainConnection! /// /// </summary> /// <param name="AClientID">ClientID as assigned by the ClientManager</param> /// <param name="AClientServerConnectionType">Tells in which way the Client connected /// to the PetraServer</param> /// <param name="AClientManagerRef">A reference to the ClientManager object /// (Note: .NET Remoting will be working behind the scenes since calls to /// this Object will cross AppDomains!)</param> /// <param name="ASystemDefaultsCacheRef">A reference to the SystemDefaultsCache object /// (Note: .NET Remoting will be working behind the scenes since calls to /// this Object will cross AppDomains!)</param> /// <param name="ACacheableTablesManagerRef"></param> /// <param name="AUserInfo">An instantiated PetraPrincipal Object, containing User /// information /// </param> public TClientDomainManager(String AClientID, TClientServerConnectionType AClientServerConnectionType, TClientManagerCallForwarder AClientManagerRef, TSystemDefaultsCache ASystemDefaultsCacheRef, TCacheableTablesManager ACacheableTablesManagerRef, IPrincipal AUserInfo) : base(AClientID, AClientServerConnectionType, AClientManagerRef, ((TPetraPrincipal)AUserInfo).UserID) { TCacheableTablesManager.GCacheableTablesManager = ACacheableTablesManagerRef; TSystemDefaultsCache.GSystemDefaultsCache = ASystemDefaultsCacheRef; TLanguageCulture.Init(); UserInfo.GUserInfo = (TPetraPrincipal)AUserInfo; DomainManager.GSiteKey = TSystemDefaultsCache.GSystemDefaultsCache.GetInt64Default(SharedConstants.SYSDEFAULT_SITEKEY); if (DomainManager.GSiteKey <= 0) { // this is for connecting to legacy database format // we cannot add SiteKey to SystemDefaults, because Petra 2.3 would have a conflict since it adds it on startup already to the in-memory defaults, but not to the database // see also https://sourceforge.net/apps/mantisbt/openpetraorg/view.php?id=114 DomainManager.GSiteKey = TSystemDefaultsCache.GSystemDefaultsCache.GetInt64Default("SiteKeyPetra2"); } if (DomainManager.GSiteKey <= 0) { // this can happen either with a legacy Petra 2.x database or with a fresh OpenPetra database without any ledger yet Console.WriteLine("there is no SiteKey or SiteKeyPetra2 record in s_system_defaults"); DomainManager.GSiteKey = 99000000; } }
/// <summary> /// Initialises variables. /// /// </summary> /// <returns>void</returns> public TClientManager() { FClientManagerCallForwarder = new TClientManagerCallForwarder(this); UClientObjects = SortedList.Synchronized(new SortedList()); // Console.WriteLine('UClientObjects.IsSynchronized: ' + UClientObjects.IsSynchronized.ToString); FStartTime = DateTime.Now; UConnectClientMonitor = new System.Object(); UClientManagerObj = this; }
/// <summary> /// Sets up .NET Remoting Lifetime Services and TCP Channel for this AppDomain. /// /// @comment WARNING: If you need to change the parameters of the Constructor, /// you also need to change the parameters in the .NET Reflection call in /// TClientAppDomainConnection! /// /// </summary> /// <param name="AClientID">ClientID as assigned by the ClientManager</param> /// <param name="AClientServerConnectionType">Tells in which way the Client connected /// to the PetraServer</param> /// <param name="AClientManagerRef">A reference to the ClientManager object /// (Note: .NET Remoting will be working behind the scenes since calls to /// this Object will cross AppDomains!)</param> /// <param name="AUserID"></param> /// <returns>void</returns> public TClientDomainManagerBase(String AClientID, TClientServerConnectionType AClientServerConnectionType, TClientManagerCallForwarder AClientManagerRef, string AUserID) { new TAppSettingsManager(false); FUserID = AUserID; // Console.WriteLine('TClientDomainManager.Create in AppDomain: ' + Thread.GetDomain().FriendlyName); DomainManagerBase.GClientID = Convert.ToInt16(AClientID); DomainManagerBase.UClientManagerCallForwarderRef = AClientManagerRef; FClientServerConnectionType = AClientServerConnectionType; FClientTasksManager = new TClientTasksManager(); FTearDownAppDomainMonitor = new System.Object(); Random random = new Random(); FRandomAppDomainTearDownToken = random.Next(Int32.MinValue, Int32.MaxValue).ToString(); // // Set up .NET Remoting Lifetime Services and TCP Channel for this AppDomain. // Note: .NET Remoting needs to be set up separately for each AppDomain, and settings in // the .NET (Remoting) Configuration File are valid only for the Default AppDomain. // try { // The following settings equal to a config file's // <lifetime leaseTime="10MS" renewOnCallTime="10MS" leaseManagerPollTime = "5MS" /> // setting. // Please note that this breaks remoting on mono, but these settings help on MS .NET // to find any remoted objects whose lifetime was inadvertedly not configured, and // therefore live only very short and calls to them break... // LifetimeServices.LeaseTime := TimeSpan.FromMilliseconds(10); // LifetimeServices.RenewOnCallTime := TimeSpan.FromMilliseconds(10); // LifetimeServices.LeaseManagerPollTime := TimeSpan.FromMilliseconds(5); // More sensible settings for Lifetime Services // TODO 1 ochristiank cRemoting : .NET Remoting LifetimeSettings should be flexible instead hardcoded in the future! try { LifetimeServices.LeaseTime = TimeSpan.FromSeconds(60); LifetimeServices.RenewOnCallTime = TimeSpan.FromSeconds(60); LifetimeServices.LeaseManagerPollTime = TimeSpan.FromSeconds(5); } catch (RemotingException) { // ignore System.Runtime.Remoting.RemotingException : 'LeaseTime' can only be set once within an AppDomain. // this happens in the Server NUnit test, when running several tests, therefore reconnecting with the same AppDomain. } } catch (Exception e) { TLogging.Log(e.ToString()); throw; } if (TLogging.DL >= 4) { Console.WriteLine("Application domain: " + Thread.GetDomain().FriendlyName); Console.WriteLine(" for User: " + FUserID); } }
/// <summary> /// Loads the ClientDomain DLL into the Client's AppDomain, instantiates the /// main Class (TClientDomainManager) and initialises the AppDomain by calling /// several functions of that Class. /// /// </summary> /// <param name="AClientID">ClientID as assigned by the ClientManager</param> /// <param name="AClientServerConnectionType">Tells in which way the Client connected /// to the PetraServer</param> /// <param name="AClientManagerRef">A reference to the ClientManager object /// (Note: .NET Remoting will be working behind the scenes since calls to /// this Object will cross AppDomains!)</param> /// <param name="ASystemDefaultsCacheRef">A reference to the SystemDefaultsCache object /// (Note: .NET Remoting will be working behind the scenes since calls to /// this Object will cross AppDomains!)</param> /// <param name="ACacheableTablesManagerRef"></param> /// <param name="AUserInfo">An instantiated PetraPrincipal Object, containing User /// information</param> /// <param name="ARemotingURLPollClientTasks">the .NET Remoting URL of the /// TPollClientTasks Class which the Client needs to calls to retrieve /// ClientTasks.</param> /// <returns>void</returns> public void LoadDomainManagerAssembly(Int32 AClientID, TClientServerConnectionType AClientServerConnectionType, TClientManagerCallForwarder AClientManagerRef, object ASystemDefaultsCacheRef, object ACacheableTablesManagerRef, IPrincipal AUserInfo, out String ARemotingURLPollClientTasks) { ICrossDomainService RemoteObject; FRemoteLoader.LoadDomainManagerAssembly(AClientID, AClientServerConnectionType, AClientManagerRef, ASystemDefaultsCacheRef, ACacheableTablesManagerRef, AUserInfo, TSrvSetting.ServerSettings, out ARemotingURLPollClientTasks, out RemoteObject); // register the remote url at the CrossDomainMarshaller TCrossDomainMarshaller.AddService(AClientID.ToString(), ARemotingURLPollClientTasks, RemoteObject); // Load the CallForwinding DLL into the Client's AppDomain FRemoteLoader.LoadCallForwardingAssembly(); // IMPORTANT: If the following code is uncommented, the ClientDomain DLL that is loaded only in the Client's AppDomain might get loaded into the Default AppDomain that's what we don't want!!! // Use this therefore only to find out what DLL's are loaded in the Client's AppDomain!!!!!! if (TLogging.DL >= 10) { TLogging.Log( "Loaded Assemblies in AppDomain " + AppDomain.CurrentDomain.FriendlyName + ": (after instantiation of TClientDomainManager)", TLoggingType.ToConsole | TLoggingType.ToLogfile); foreach (Assembly tmpAssembly in AppDomain.CurrentDomain.GetAssemblies()) { TLogging.Log(tmpAssembly.FullName, TLoggingType.ToConsole | TLoggingType.ToLogfile); } } }
/// <summary> /// Loads the ClientDomain DLL into the Client's AppDomain, instantiates the /// main Class (TClientDomainManager) and initialises the AppDomain by calling /// several functions of that Class. /// /// </summary> /// <param name="AClientID">ClientID as assigned by the ClientManager</param> /// <param name="AClientServerConnectionType">Tells in which way the Client connected /// to the PetraServer</param> /// <param name="AClientManagerRef">A reference to the ClientManager object /// (Note: .NET Remoting will be working behind the scenes since calls to /// this Object will cross AppDomains!)</param> /// <param name="ASystemDefaultsCacheRef">A reference to the SystemDefaultsCache object /// (Note: .NET Remoting will be working behind the scenes since calls to /// this Object will cross AppDomains!)</param> /// <param name="ACacheableTablesManagerRef"></param> /// <param name="AUserInfo">An instantiated PetraPrincipal Object, containing User /// information</param> /// <param name="AServerSettings">A copy of the ServerSettings</param> /// <param name="ARemotingURLPollClientTasks">The .NET Remoting URL of the /// TPollClientTasks Class which the Client needs to calls to retrieve /// ClientTasks.</param> /// <param name="ARemotedPollClientTasksObject"></param> public void LoadDomainManagerAssembly(Int32 AClientID, TClientServerConnectionType AClientServerConnectionType, TClientManagerCallForwarder AClientManagerRef, object ASystemDefaultsCacheRef, object ACacheableTablesManagerRef, IPrincipal AUserInfo, TSrvSetting AServerSettings, out String ARemotingURLPollClientTasks, out ICrossDomainService ARemotedPollClientTasksObject) { // Console.WriteLine('TRemoteLoader.LoadDomainManagerAssembly in AppDomain: ' + AppDomain.CurrentDomain.ToString); Assembly LoadedAssembly = Assembly.Load(CLIENTDOMAIN_DLLNAME); FRemoteClientDomainManagerClass = LoadedAssembly.GetType(CLIENTDOMAIN_CLASSNAME); FRemoteClientDomainManagerObject = Activator.CreateInstance(FRemoteClientDomainManagerClass, (BindingFlags.Public | BindingFlags.Instance | BindingFlags.CreateInstance), null, new Object[] { AClientID.ToString(), AClientServerConnectionType, AClientManagerRef, ASystemDefaultsCacheRef, ACacheableTablesManagerRef, AUserInfo }, null); FRemoteClientDomainManagerClass.InvokeMember("InitAppDomain", (BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod), null, FRemoteClientDomainManagerObject, new Object[] { AServerSettings }); // Create and remote the TPollClientTasks Class ARemotingURLPollClientTasks = Convert.ToString(FRemoteClientDomainManagerClass.InvokeMember("GetPollClientTasksURL", (BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod), null, FRemoteClientDomainManagerObject, null, null)); ARemotedPollClientTasksObject = (ICrossDomainService)FRemoteClientDomainManagerClass.InvokeMember("GetRemotedPollClientTasksObject", (BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod), null, FRemoteClientDomainManagerObject, null, null); // Establish (separate) DataBase connection for the AppDomain Convert.ToString(FRemoteClientDomainManagerClass.InvokeMember("EstablishDBConnection", (BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod), null, FRemoteClientDomainManagerObject, null, null)); // Perform any other initialisation required by the AppDomain FRemoteClientDomainManagerClass.InvokeMember("PostAppDomainSetupInitialisation", (BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod), null, FRemoteClientDomainManagerObject, null, null); // LoadClientDomainManager.ClientTaskAdd('USERMESSAGE','This is just for testing purposes!', 'blabla_1', 'blabla_2', 'blabla_3', 'blabla_4', 1); }
/// <summary> /// Sets up .NET Remoting Lifetime Services and TCP Channel for this AppDomain. /// /// @comment WARNING: If you need to change the parameters of the Constructor, /// you also need to change the parameters in the .NET Reflection call in /// TClientAppDomainConnection! /// /// </summary> /// <param name="AClientID">ClientID as assigned by the ClientManager</param> /// <param name="AClientServerConnectionType">Tells in which way the Client connected /// to the PetraServer</param> /// <param name="AClientManagerRef">A reference to the ClientManager object /// (Note: .NET Remoting will be working behind the scenes since calls to /// this Object will cross AppDomains!)</param> /// <param name="AUserID"></param> /// <returns>void</returns> public TClientDomainManagerBase(String AClientID, TClientServerConnectionType AClientServerConnectionType, TClientManagerCallForwarder AClientManagerRef, string AUserID) { new TAppSettingsManager(false); FUserID = AUserID; // Console.WriteLine('TClientDomainManager.Create in AppDomain: ' + Thread.GetDomain().FriendlyName); DomainManagerBase.GClientID = Convert.ToInt16(AClientID); DomainManagerBase.UClientManagerCallForwarderRef = AClientManagerRef; FClientServerConnectionType = AClientServerConnectionType; FClientTasksManager = new TClientTasksManager(); FTearDownAppDomainMonitor = new System.Object(); Random random = new Random(); FRandomAppDomainTearDownToken = random.Next(Int32.MinValue, Int32.MaxValue).ToString(); // // Set up .NET Remoting Lifetime Services and TCP Channel for this AppDomain. // Note: .NET Remoting needs to be set up separately for each AppDomain, and settings in // the .NET (Remoting) Configuration File are valid only for the Default AppDomain. // try { // The following settings equal to a config file's // <lifetime leaseTime="10MS" renewOnCallTime="10MS" leaseManagerPollTime = "5MS" /> // setting. // Please note that this breaks remoting on mono, but these settings help on MS .NET // to find any remoted objects whose lifetime was inadvertedly not configured, and // therefore live only very short and calls to them break... // LifetimeServices.LeaseTime := TimeSpan.FromMilliseconds(10); // LifetimeServices.RenewOnCallTime := TimeSpan.FromMilliseconds(10); // LifetimeServices.LeaseManagerPollTime := TimeSpan.FromMilliseconds(5); // More sensible settings for Lifetime Services // TODO 1 ochristiank cRemoting : .NET Remoting LifetimeSettings should be flexible instead hardcoded in the future! try { LifetimeServices.LeaseTime = TimeSpan.FromSeconds(60); LifetimeServices.RenewOnCallTime = TimeSpan.FromSeconds(60); LifetimeServices.LeaseManagerPollTime = TimeSpan.FromSeconds(5); } catch (RemotingException) { // ignore System.Runtime.Remoting.RemotingException : 'LeaseTime' can only be set once within an AppDomain. // this happens in the Server NUnit test, when running several tests, therefore reconnecting with the same AppDomain. } } catch (Exception e) { TLogging.Log(e.ToString()); throw; } if (TLogging.DL >= 4) { Console.WriteLine("Application domain: " + Thread.GetDomain().FriendlyName); Console.WriteLine(" for User: " + FUserID); } }