====== Overview about mercaware ====== ===== Introduction ===== mercaware is an ERP system running under Linux, consisting out of a [[#java_applet|Java applet]], the [[#application_server|application server]], the [[#business_logic_source_code|business logic]], a PostgreSQL database and [[#development_tools|development tools]]. An end user starts on its client computer the [[#java_applet|Java applet]] which performs a TCP connection to the mercaware [[#application_server|application server]]. The [[#application_server|application server]] connects to the PostgreSQL database containing all data records and also accesses the [[#binary_business_logic|binary parts of the business logic]]. The graphical user interface is completely defined via the [[#business_logic_source_code|business logic]] and only vector information, labels etc. are transferred via the TCP connection to the [[#java_applet|Java applet]]. Each user interaction (click on a button, typing text into an input field) results in data transferred over the TCP connection to the [[#application_server|application server]]. The [[#binary_business_logic|binary parts of the business logic]] are created using the [[#development_tools|development tools]] from the [[#business_logic_source_code|source code parts of the business logic]]. The [[#business_logic_source_code|business logic]] contains every logic of mercaware: Any button, input field, layout link between screens, masks, register cards. It also defines the whole database structure and the connection between the user-visible frontend parts and the database fields. Additionally the functionality itself (compute a value for a field, save something into the database, raise an error) is also part. Database changes resulting from [[#business_logic_source_code|business logic source code]] changes can be applied to the PostgreSQL database using a command line tool. The development of the [[#business_logic_source_code|business logic source code]] is splitted into socalled mask definitions (short: maskdef) and formulars. As mentioned before, the mask definitions care about the graphical and database layout, the definition/programming language however can not be compared with any existing language. The formulars add the logic and are called by the mask definitions (different actions and triggers), the programming language here can be compared to C, but without pointers, without the need to allocate/free memory and with limited string handling abilities like in modern high languages. There are additionally application specific functions to get input values from masks, to trigger actions on the database etc. The whole formulars are functional, not procedural, manual linking is not required. From a mercaware developer perspective, the mask definitions and formulars are compiled using GNU make together own compilers, which use in the end bison, flex and gcc (and also take care about linking etc. on system level). The [[#business_logic_source_code|business logic source code]] is organized into socalled modules, e.g. ''mod_base''. These modules are stackable, the order is defined in the ''modules.in'' file. Stackable means, module B can extend module A on mask definition and formular level. Extend hereby also means to add new buttons, input fields, masks, register cards, etc. as well as formulars and include files - including hiding, removing or disabling elements from previous modules. The ''mod_base'' module is kind of special, because it contains values that need to stay in sync with the application server for login, session handling and other built-in functionalities. ===== Visual ===== {{:nazar:software:mercaware-overview.png}} ===== Textual ===== ==== Java applet ==== === Java RIA === * Java Rich Internet Application (as per Oracle documentation definition) * Can be started as * "Java applet" in browser * "Web Start" application using JNLP * Connects to [[#mxsd]] via TCP * Protocol between Java applet and [[#mxsd]] is * proprietary * undocumented (except in source code) * binary (?) * optionally encrypted (similar concept like STARTTLS, but //not// STARTTLS) * Very sensitive to timeouts, disconnects, interrupts (does not support reconnecting during short outages) * Connection outages leads to Java applet dying * Overall behaviour feels RPC-like, but is not any common/standard/classical RPC protocol === mercaware/mercawarefonts/mercawareall.jar === * Compiled using Oracle Java or OpenJDK from ''*.java'' code * Does //not// need to be changed on any [[#business_logic_source_code|business logic]] changes * Shares some hardcoded values with [[#application_server|application server]] ==== Application server ==== === mxsd === * "Starting daemon" * Gets started by the SysV initscript * Starts n preforked [[#mxd|mxd]] processes, where n is by default 3 * Preforking concept is similar like Apache HTTPd prefork * Listens on TCP port 5000X, where X is the number of the instance * Requires a running [[#mxlicd]] process === mxd === * "Worker daemon" * Gets started (preforked) by [[#mxsd|mxsd]] * Run-time core component * Reads the [[#Binary_business_logic|binary business logic]] * Connects to the PostgreSQL database server via socket or TCP (configurable via libiodbc) * Connects to [[#mxnd|mxnd]] if needed * Connects to [[#mxlicd|mxlicd]] via TCP * Requires a running [[#mxlicd]] process * Generates PostScript/PDF if formular is a print formular === mxnd === * "Numbering daemon" * Gets started by the SysV initscript * User-editable unique identifiers for reach data record (e.g. ''DEBNR_DEB_DEB'') are * either taken from an application specific PostgreSQL sequence table (''stab'' and/or ''esstab'') * or gathered via the ''mxnd'' process * Exact involvement and usage of ''mxnd'' is not known * IDs supplied by ''mxnd'' are //not// the database sequence/primary key (that part is handled via auto-increment in PostgreSQL) === mxvd === * Meaning of "v" is unknown * Gets started by the SysV initscript * Trigger to [[#mxd]] process to call actions within the business logic * Watches the ''incoming'' directory of ''mod_documents'' ([[#business_logic_source_code|business logic module]]) for new incoming documents to trigger actions * Configurable action triggers (also for external events via TCP) via ''mxinputconf'' configuration file === mxlicd === * License daemon * Gets started by the SysV initscript * Listens on TCP port 43619 * Reads the ''mxlicense'' file which contains information about * License serial number * Licensed modules (ID of [[#business_logic_source_code|business logic module]]) * Licensee (customer) number * Licensee (customer) name * License validity period * Number of licensed users (per licensed module) * Secret key for verification * If ''mxlicd'' process dies, all [[#mxd]] and [[#mxsd]] process die, too ==== Development tools ==== === mmdbc === * Mask definition compiler * Called via ''Makefile''s (GNU make) to create a ''mxmask.obj'' per module and one global [[#mxmask.msk|mxmask.msk]] over all modules * Compiler is internally built on top of bison, flex and gcc * Connects to [[#mxlicd|mxlicd]], aborts if license does not support developing, if developer count is reached or if license daemon is unreachable === srdbc === * Formular compiler * Called via ''Makefile''s (GNU make) to compile a ''*.sr'' (binary) for each ''*.ssr'' (source code) * Compiler is internally built on top of bison, flex and gcc * Connects to [[#mxlicd|mxlicd]], aborts if license does not support developing, if developer count is reached or if license daemon is unreachable === reltool === * Applies structual database changes * Reads the [[#mxmask.msk|mxmask.msk]] file for the database layout/definition resulting from the business logic source code * Takes a SQL structure dump (with create table etc.) to read the current database layout/definition * Outputs SQL statements to change the current database layout/definition to the new database layout/definition * Database layout/definition means tables, fields names, field types, field lengths, relations and constraints (e.g. not null, primary, foreign key constraints), indexes * New default values or possible update statements to migrate existing data from the old to the new database layout/definition are separately outputted ==== Business logic source code ==== === mod_ === * Organized in modules with schema ''mod_'', e.g. ''mod_base'' * Filesystem structure of a module: * ''mod_base/'' * ''mod_base/maskdef/'' * ''mod_base/maskdef/passwd.def'' (mask definition file, source code) * ''mod_base/maskdef/passwd.ded'' (mask definition file, after preprocessor run) * ''mod_base/maskdef/layout_base.deh'' (include file, similar like a C include) * ''mod_base/maskdef/mxmask.obj'' (mask definitions of all ''*.ded'', binary file) * ''mod_base/maskdef/mxlang.mod_base'' (mapping between IDs and texts including translations for masks) * ''mod_base/formular/define.ssh'' (include file, similar like a C include) * ''mod_base/formular/passwd1.ssr'' (formular file, source code) * ''mod_base/formular/passwd1.ssd'' (formular file, after preprocessor run) * ''mod_base/formular/passwd1.sr'' (formular file, binary file) * ''mod_base/formular/mxform.mod_base'' (mapping between IDs and texts including translations for print formulars/documents) * ''mod_base/formular/mxerrs.mod_base'' (mapping between IDs and texts including translations for formulars for error/success/warning messages) * Mixing mask definition and formular includes (or files from these two parts in general) is not possible * Pure business logic source code does not contain any generated or compiled files, such as ''*.ded'', ''*.obj'', ''*.ssd'' or ''*.sr'' * Modules are stackable * Module B can extend module A on mask definition and formular level * Add new buttons, input fields, masks, register cards, etc. as * Formulars and include files * Including hiding, removing or disabling elements from previous modules * The ''mod_base'' module is kind of special, because it contains values that need to stay in sync with the application server for login, session handling and other built-in functionalities * Ordering/priority of modules is defined via ''modules.in'' file === .def === * Mask definition file * Defines any button, input field, dropdown (and it's position) including layout and colors * Defines the link between different masks * Defines also register cards ("ribbons") * Reference formular files to finally run user-visible actions (e.g. "Create bill" or "Print bill") * Definition/programming language can not be compared with any existing language === .ssr === * Formular/action file * Programming language can be compared to C, but * without pointers * without the need to allocate/free memory * with limited string handling abilities like in modern high languages * Application specific functions to get * input values from masks * trigger actions on the database * Code is functional, not procedural * Can only return success or failure via ''int main(void)'' function * Each formscript (single formular or a bundle of formulars) is run in a database transaction to allow commit/rollback (handled by the [[#mxd|mxd]] depending on return code * A formular can be a socalled "print formular" as well, then the result is (additionally to "regular" function calls) a PostScript or PDF file (depends on the user choice) that's passed to the end user ==== Binary business logic ==== === mxmask.msk === * Final compilation result of [[#mmdbc|mmdbc]] * Contains structure and layout of all masks including the database definition * Read by [[#reltool|reltool]] and [[#mxd|mxd]] * Differences between ''mxmask.msk'' and PostgreSQL databases (e.g. forgotten call of [[#reltool|reltool]]) lead to dying [[#mxd]] and [[#mxsd]] * Binary is dependent to * [[#development_tools|development tools]] version/features * hardware architecture (?) === .sr === * Final compilation result of [[#srdbc]] * Called by end user at [[#java_applet|Java applet]] as e.g. "Create bill" or "Print bill", internally executed by [[#mxd]] * Binary is dependent to * [[#development_tools|development tools]] version/features * hardware architecture (x86 vs. x64) * Not an ELF binary * Missing ''*.sr'' during run-time leads to failure when trying to call the functionality via [[#java_applet|Java applet]]