N-tier architecture

From OpenPetra Wiki
Jump to navigation Jump to search

Client/Server Architecture

There are several options how to design a client/server architecture.

  • It depends on what environment you are using (bandwidth, datalink speed, etc) and on your requirements (supported operating systems etc).
  • On the other hand you want to try to keep the logic in one place (the server), so that several types of clients can connect the one server.
  • Also access to the database should go all through the server, so that you don't need to create a database user for each of your users, and access permissions are handled by the server.

Several types of clients:

  • Standalone: this is for single user systems; they don't need to know that a server is started in the background.
  • Fat client, Rich client: this is in our case a Winforms application, that connects to a server. The client can handle the logic, but perhaps we want to keep it still simple on the client. Updates/Patches to the client need to be run semi automatically.
  • Slim Client: this could be a web client; it requires no installation effort.
    • Rich Internet applications (RIAs) look like desktop applications, but run in the web browser

Another topic is the server itself:

  • for our .net remoting setup, we have an Appdomain for each client, ie. all the dlls are loaded for every connected client
    • this helps with server crashes: if one client crashes, the other clients can continue with work
    • on the other hand, this uses a lot of memory
  • for the SOAP/Web service setup of the server, there should be much better scalability
  • how much should the server keep track of the state of the client? stateful vs stateless

Glue between Server and Client

different ways of accessing data on the server

  • UIConnectors: only used for screens; keep an object on the server for each screen
    • advantage: server knows about the client (stateful); minimum data transfer, diffs are enough.
  • LogicConnectors: keeps an object on the server side; needed for progress bar; eg. Report Calculation
  • ServerLookup: used for static methods; no object is held on the server (stateless); eg. Verify Partner in ExperimentingClient; UserDefaults uses ServerLookups internally
    • WebConnector: very similar to ServerLookup (stateless); easy generation of interface and instantiator, and winforms
  • Cacheable: also static methods; they are not called by the developer, but by the Cachemanager on the server and the client side, when you are accessing a cached table

code generation

  • the code for interfaces and instantiators is generated
  • first edit file csharp/ICT/Petra/Definitions/NamespaceHierarchy.xml (TODO?: change to yml for easier readability)
  • then run nant generateGlue for the first time
  • to add new modules (on the level of MFinance, MCommon, etc), edit the NamespaceHierarchy.xml file, and also search for REMOTINGURL_IDENTIFIER_MCOMMON in ICT/Petra/Server/app/Main/ClientManager.cs and ICT/Petra/Server/app/Main/ClientAppDomainConnector.cs and create similar lines of code for the new module
  • then you can create a UIConnector .cs file; the constructor will be added to the Instantiator and to the interface the next time you run nant generateGlue
    • a method that should not be added to the interface, should either be private, or have comment [NO-REMOTING] (with 3 slashes)
  • you can also add a method to the instantiator, and put its codeblock in a ManualCode region; next time you generateGlue, the method will be added to the interface
  • Web connector methods are the easiest, they will be added to the interface and the instantiator, and even the winforms: just make sure the namespace exists in the NamespaceHierarchy.xml, and then add your method to the Webconnector class; run nant generateGlue, it will create the interface and instantiator for you, and even nant generateWinforms will add functions to edit windows etc

todo

  • Todo: something special about UIConnectors; extra things are generated for UIConnectors
  • the others are implemented manually at the moment


  • TODO: progress bar; need different threads; keep the connection; prevent the object from being garbage collected
    • need extra object on server for progress and cancel option (eg FReportingGenerator.AsyncExecProgress)
    • keep the main object (eg. FReportingGenerator) alive by registering it
  • Table Maintance: use UIConnector

Data Processing in an n-tier architecture

  • example 1: create a new partner: new partner key is generated, will never be reused, even if the new partner is never saved to the database
  • example 2: create a new GL batch; it is important to have consecutive batch numbers; cancel batch if it is not needed anymore; batch is stored with status "cancelled"
  • example 3: AP Document is created with negative AP number, proper AP number is only assigned on submitting changes
  • options: create new row on server, or on client
  • options: for complex screens with several tabs, store the whole Typed Data Set, or each tab on its own?
  • names that the generateWinforms is looking for in the server: Create<TableName>, Find<TableName>, Save<TableName>, Save<TypedDataSet>

Encrypted Connection between Server and Client

There is no encryption required for the development setup and for the standalone setup.

If you run the server on your local network, or even on the Internet, you should setup a secure connection between client and server.

You will need to create a private/public key pair and install it on the server. You can use the GenerateEncryptionKey.exe from the csharp\ICT\PetraTools\_bin\Debug directory.

You should publish the public key of the server so that the clients can download the public key. It is recommended to publish that key on a certified https website, so that the identity of the website is reliable. When downloading from https with a self signed certificate, the connection will fail. Such a certificate can be bought for even less than 20 Euros a year.

You need to modify the following configuration files:

  • setup\petra0300\remoteclientWin\PetraClientRemote.config
    • activate the commented line <provider type="Ict.Petra.Shared.RemotingSinks.Encryption.EncryptionClientSinkProvider, Ict.Petra.Shared.RemotingSinks" HttpsPublicKeyXml="https://PETRAHOST/publickey.xml"/> by removing the
    • change the value for HttpsPublicKeyXml to point at a certified source
  • setup\petra0300\linuxserver\PetraServerConsole-<YourDatabase>.config
    • activate the commented line <provider type="Ict.Petra.Shared.RemotingSinks.Encryption.EncryptionServerSinkProvider, Ict.Petra.Shared.RemotingSinks"/> by removing the
    • Server.ChannelEncryption.PrivateKeyfile

This happens when the client connects to the server:

  1. The client downloads the public key from the certified website. If the website is bogus, or someone pretends to be that website, then the certificate will not be valid, and the download will fail.
  2. The client creates a new symmetric key for each session. This symmetric key is sent once per session to the server, but it is encrypted using the public key of the server, so only the server can decrypt it using its private key.
  3. During a session, all data sent by the client and the server is encrypted with the symmetric key. This is less demanding for the CPU than using Public/Private key algorithms. Since only the client and the server know the symmetric key, and it is only used for one session, all the data is transported securely between server and client.