Komponenten Architektur & verteilte Entwicklung
mit CIM DATABASE / CONTACT Elements
compiled by darmarIT
Hit ‚?‘ to see keyboard shortcuts
Voraussetzungen + repair Schema & Konfiguration
Updates & Konflikte + cdbpkg & SCM big picture
Transport: Code & Config Merge-Schaubild
Hersteller-Pakete in site-packages
Änderungen nur durch Hersteller-Updates
Beispiel: keine eignen Änderungen an cs.
Paketen
Kunden-Paket cust.plm
darf nicht im Python-Pfad (site-packages
) liegen.
Ebene 3 – cust.
pflegt der Customer
Ebene 2 – tpm.
pflegt der Third Party Maker
Ebene 1 – cs.
pflegt die Contact Software GmbH
Dependency-Direction: 3 darf 2 oder auch 1 anpassen
cust.
–> tpm
–> cs.
Namensräume sind was anderes als Pakete. Ein Namensraum beinhaltet
i.d.R. mehrere Pakete – z.B. die Pakete cs.base
und cs.vp
im
Namensraum cs
. Die CDB-Module in einem Paket gehören aber alle zum
Namensraum des Pakets – z.B. das CDB-Modul cs.calender
aus dem
Paket cs.base
. Der Hersteller pflegt seinen Namensraum und schnürrt
die Pakete.
Quellcode in cust.
Anpassung z.B. durch Verbung aus cs.
und tpm.
oder Signalhandler
die in cs.
und tpm.
registriert werden.
Konfiguration aus cs.
und tpm.
die der Customer ändern muss
z.B. Anpassungen an Masken & Tabellen aus cs.
und tpm.
Die Anpassungen einer Kundeninstallation werden in einem Paket verwaltet
– z.B. Paket cust.plm
im Namensraum cust
. Die Anpassungen
beschränken sich aber nicht auf diesen Namensraum, man wird auch
Konfigurationen in der DB aus cs
und tpm
anpassen wollen.
Master + Historie für jedes CDB-Modul, wird aus der DB aufgebaut, von
cdbpkg
verwaltet und wird nicht im SCM-System versioniert!
CADDOK_BASE
+---app_conf
+---cs
| ...
| \---erp
| +---current
| +---history
| \---master
+ ...
\---cust.plm
Die Details sind für uns unwichtig, wir müssen nur wissen, dass es diesen
Ordner gibt und das die cdbpkg
Tools ihn für so eine Art micro
Versionsverwaltung nutzen.
CDB-Paket mit zwei CDB-Modulen cust.plm
und cust.foo
\---cust.plm # CDB-Paket
+---cust.plm.egg-info
| setup.py # schauen wir uns gleich an
| # ansonsten keine weiteren Dateien
\---cust # Python Namespace 'from cust import foo'
| __init__.py # ist ein Python (kein CDB) Paket
| # ansonsten keine weiteren Dateien
+---plm # Modul 'plm' nicht zwingend erforderlich
\---foo # Modul 'foo' schauen wir uns gleich an
CDB-Paketname ist cust.plm
. Die CDB-Module sind Python-Pakete deren
Namespace cust.*
ist. Typische Namen von CDB-Modulen: cust.foo
oder
cust.bar
. Ein cust.plm
kann, muss es aber nicht geben.
\---cust.plm # CDB-Paket
+---cust.plm.egg-info
| setup.py # schauen wir uns gleich an
| # ansonsten keine weiteren Dateien
\---cust # Python Namespace 'from cust import foo'
| __init__.py # ist ein Python (kein CDB) Paket
| # ansonsten keine weiteren Dateien
+---plm # Modul 'plm' nicht zwingend erforderlich
\---foo # Modul 'foo' schauen wir uns gleich an
Wenn im Namespace cust
mehrere CDB-Module rumliegen – hier
z.B. cust.foo
und cust.plm
– dann müssen diese auch in der
Paket-Konfig in CDB als Module existieren, Anderes darf hier nicht
rumliegen! Vergleiche cs.base
Paket, das n-CDB-Module vereint. Häufig
ist das Customizing ein CDB-Paket cust.plm
in dem nur ein Modul
cust.plm
exisitert.
from cdb.comparch.pkgtools import setup
setup(
name = "cust.plm" # package name
, version = "1.0.0" # package version
# list of required packages
, install_requires = [
'cs.platform', 'cs.base', 'cs.workflow' ..]
# relative path for each documentation
, docsets = []
# list of contained modules (cdb_modules.txt)
, cdb_modules = ['cust.plm', 'cust.foo', ..]
# list of services (class names cdb_services.txt)
cdb_services = []
],
Die install_requires
muss vollständig sein! setup.py gehört zu
Python, für CDB wurde es um cdb_
Eigenschaften erweitert.
\--foo # CDB 10.x
| module_metadata.json
| content_metadata.json # in 15.x unter ./configuration
| schema.json # in 15.x unter ./configuration
+---patches # in 15.x unter ./configuration
+---configuration
\---resources
\--foo # CDB 15.x
| module_metadata.json
+---configuration
\---resources
Die Struktur hat sich in CDB ELEMENTS leicht geändert, vom Prinzip her
bleibt es gleich; Konfig Schlonz liegt im Modul und wird im SCM versioniert.
Ab CDB 15.x nur noch configuration
, wir reden ab jetzt nur noch von
configuration
.
\--configuration
| content_metadata.json # Checksumme
| schema.json # DB Schema
+---content #
| | ausgaben.json # eigene Meldungstexte
| | browsers.json # eigene Auswahlbrowser
| \---blobs # eigene BLOBs
| 6eccde35-1fa8-... # --> z.B. Report-Template
\---patches # Anpassungen andere Module
+---cs.pcs.projects # --> cs.pcs.projects
| | patches.json # patch Konfiguration
| \---blobs # patch blobs
| 12eeddaa-17fa-... #
+---cs.pcs.cheklists # --> cs.pcs.checklists
| patches.json # patch Konfiguration
Konfigurationen werden als JSON Dateien zum Modul hinterlegt. Hier zu
erkennen: cust.foo
hat Meldungstexte, Auswahlbrowser und einen BLOB.
Desweiteren scheint es die Module projects
und checklists
des
cs.pcs
Pakets anzupasssen.
Instanz & DB müssen immer zueinander passen.
DB Schema muss im Data-Dictionary vollständig den Modulen zugeordnet sein.
Referenzielle Integrität der Konfiguration muss gewährleistet sein.
Konflikte müssen aufgelöst werden!
Diese Voraussetzungen müssen erfüllt werden, sonst gibt es Probleme beim Transport von Änderungen innerhalb der Komponenten Architektur. D.h. ohne diese Voraussetzungen ist eine verteilte Entwicklung nicht oder nur mit Fehlern möglich.
$ cdbpkg schema_coverage
tmp/cdbpkg_schema_coverage-views.csv
tmp/cdbpkg_schema_coverage-tables.csv
tmp/cdbpkg_schema_coverage-columns.csv
Mit Option -f
reparieren, aber vorher Komponentenarchitektur lesen!!!
Komandozeile gibt guten Überblick über alles
$ cdbpkg check
...
cs.tools.batchoperations
------------------------
masken: name=cdbbop_operation/owner=public/attribut=button_ex...
error: Referenced object does not exist
reference: Icons
foreign keys: {u'string1': u'foofoo'}
...
Reparieren einfacher im CDB-Client / je Modul :
Kontextmenü Modulkonfigurationsüberprüfung
Konflikte im SCM-System ermitteln & auflösen
Konflikte in CDB ermitteln & auflösen .. CDB 10.x unter Protokolle .. CDB 15.x Modul / Entwicklerübersicht
Konflikte in Schema & Konfiguration kann CDB nur erkennen, wenn das DB Schema im Data Dictionary ist und die Konfigurationen den Modulen zugeordnet sind – siehe Voraussetzungen
configuration
+ Source-Code sind EINSÄndert sich daran was, ist das ein Update – Voraussetzungen
pull
eines Patches aus dem SCM-System in das working directory
aktualisiert configuration
und Source-Code (das Update). cdbpkg
sync
spielt Änderung in DB ein
Konfliktpotential hat also nicht nur ein Update der Anwendungspakete. Jede Änderung die man sich in seine Instanz holt ist ein Update mit Konfliktpotential .. eigentlich logisch: Neu seit CDB 10 ist nur, dass der DB Content jetzt mit dazu gehört.
Nach Abschluss einer Konfiguration: cdbpkg build
, danach git
commit
+ cdbpkg commit
. Die commits von SCM und CDB sollten immer
synchron angewendet werden.
\---cust.plm # CDB-Paket
...
\---cust # Python Namespace 'from cust import foo'
... # Python Pakete ...
\--foo # Python Paket 'foo'
| module_metadata.json
+---configuration
\---resources
Source-Code: sind die Python Pakete wie z.B. foo
. Diese werden mit
dem SCM gemerged.
Konfiguration: ist im Ordner configuration
. Der Ordner muss mit
cdbpkg diff
und cdbpkg patch
gemerged werden.
Typisches Schaubild für einen Feature-Branch, der in den master Branch
gemerged wird. Der master Branch kann z.B. QS oder PROD sein. Egal
ob man eine Kopie anlegt oder dazu ein SCM-System nutzt, es gibt immer einen
Branch-Point und einen Merge-Point. Die Änderungen in der DB können nur mit
cdbpkg
gemerged werden.
Diff zur Kopie des Branch-Point (Abzweigung) bilden:
$ cdbpkg diff cust.plm -p ./branch-point-copy -d ./patch_folder
Merge-Point: Patch in DB des PROD
-Systems einspielen:
$ cdbpkg patch ./patch_folder/patch_cust.fo_xx_yyyy
Konflikte in CDB auflösen, anschließend commiten
$ cdbpkg build cust.plm # DB export
# git add --all . # SCM-Commit
$ git commit -m "merged branch 'foo'" # ..
$ cdbpkg commit cust.plm # CDB-Commit
Transport des Source-Code über SCM-System.
Paket cust.plm
wird im SCM-System versioniert. Besteht aus
Source-Code + configuration
Abgleich zw. DB & configuration
machen die cdbpkg
-Tools
cdbpkg
-Tools und SCM-System müssen synchron verlaufen (siehe
Merge-Schaubild)
Einfach mal ins SCM committen ist vorbei! wer das pull
‚t hat
u.U. ein bisect Problem
prinzipell geht jedes, populär sind SVN & git
Verglichen mit SVN ist git beim Branchen und verteiltem Arbeiten wesentlich
stärker. Z.B. diverse Protokolle zum Transport: file://
,
http://
, ssh://
usw. / s.a. git URLs, git-send-email
nicht zu vergessen: SVN ist tot.
Wir verwenden hier git / siehe auch get git started
(prod)$ cd cust.plm
(prod)$ git init
(prod)$ git add --all .
(prod)$ git commit -m 'cust.plm initial'
Ggf. letzte Änderungen beenden und festschreiben
(prod)$ cdbpkg build cust.plm
(prod)$ git add --all .
(prod)$ git commit -m "add 'cust.foo' to package 'cust.plm'"
(prod)$ cdbpkg commit cust.plm
SCM-Systeme wie git verfügen über ausgereifte Merge Strategien zum Mergen von Source-Code (build-in).
Merge der CDB-Konfiguration benötigt besondere Strategie.
Diese Strategie bedarf cdbpkg
Tools, welche die Semantik der
Konfiguration kennen und Checksummen neu berechnen können.
git unterstützt alternative Merge Strategien, mittels Git Attributen kann die Strategie individuell gewählt werden.
Um configuration
nicht zu mergen; Strategie ours
.
# location: cust.plm/.gitattributes
# CDB 15.x
cust/*/configuration merge=ours
Dummy handler true
für ours
registrieren
$ git config --local merge.ours.driver true
In CDB 10.x müssen noch patches
, schema.json
,
module_metadata.json
und content_metadata.json
analog gesetzt
werden (.gitattributes)
Lieferantenanbindung erfolgt an einem Branch-Point (foo
). Die
Auslieferung an den Lieferanten ist ein Clone. Siehe auch
Releasemanagement und CONTACT Elements.
Initial gibt es den master
branch, darin existiert bereits Modul cust.foo
im Paket cust.plm
. In dem Modul soll nun noch die Klasse Foo
konfiguriert & implementiert werden.
$ git branch -v
* master 268a44e add 'cust.foo' to package 'cust.plm'
feature branch ‚foo‘ anlegen
$ git branch -v
foo 268a44e add 'cust.foo' to package 'cust.plm'
* master 268a44e add 'cust.foo' to package 'cust.plm'
Siehe auch Releasemanagement und CONTACT Elements.
Der Übergabepunkt einer Beauftragung ist der Branch-Point (foo
). Er muss
dem Auftragnehmer übergeben werden.
(dev)$ git clone file:///path/to/prod/cust.plm.git/
(dev)$ cd cust.plm
(dev)$ git checkout foo
Zu Branch 'foo' gewechselt
Für einen Spiegel beim Auftragnehmer – ggf. auch mit Nutzdaten – sind
i.d.R. weitere Maßnahmen erforderlich. Meist wird initial die komplette
Instanz ausgeliefert (z.B. ZIP des CADDOK_BASE
am Branchpoint plus
DB-Dump aber ohne Storage).
Auftragnehmer muss (Teil-) Spiegel-System einrichten.
Abhängig von den benötigten CDB- und Third-Party- Diensten (z.B. SAP) und externen Anwendungen kann ein vollständiger* Spiegel z.T. sehr Aufwändig bis unmöglich sein.
Stand aus Branch foo
in den lokalen Spiegel einspielen
(dev)$ cdbpkg sync
(dev)$ cdbpkg import_blobs # falls DB-Dump verwendet wurde
(dev)$ cdbpkg commit cust.plm
Ein import_blobs
ist i.d.R. erforderlich, wenn der Spiegel aus einem
DB-Dump aufgebaut wurde (und der storage des Spiegels noch leer* ist).
Das commit
sollte nicht unbedingt erforderlich sein, stellt aber in
jedem Fall sicher, dass ab jetzt lokale Änderungen aufgezeichnet
werden.
Die Aufgabe wird in zwei Teil-Aufgaben aufgeteilt. Als erstes richtet der Entwickler das DB-Schema für das ‚foo‘ feature ein.
In der Entwickler-Übersicht den Dev-Build anstoßen. Doppel-Klick auf ‚Dev Patches‘ zeigt die lokalen Änderungen.
Schema soll erster Commit ins SCM werden
(dev)$ cdbpkg build cust.plm
(dev)$ git add --all .
(dev)$ git commit -m "configured 'foo' schema"
Dieser Teil-Änderung ist nun im SCM-System. Alle weiteren lokalen Änderungen sollen relativ zu dem Stand jetzt aufgezeichnet werden.
(dev)$ cdbpkg commit cust.plm
In der Entwickler-Übersicht ist der Eintrag ‚Dev Patches‘ für die lokalen Änderungen nun verschwunden.
Entwickler erstellt cust.plm/cust/foo/__init___.py
#!/usr/bin/env python
# -*- coding: utf-8; mode: python -*-
from cdb.objects import Object
class Foo(Object):
__maps_to__ = "foo"
__classname__ = "Foo"
und registriert den Voll qualifizierten Python Namen (FQN).
Änderungen sind abgeschlossen, zweiten Commit vorbereiten ..
(dev)$ cdbpkg build cust.plm
In der Entwickler-Übersicht ist wieder der Eintrag ‚Dev Patches‘ zu sehen. Doppel-Klick darauf zeigt die lokalen Änderungen.
(dev)$ git add --all .
(dev)$ git commit -m "implemented class 'Foo'"
(dev)$ cdbpkg commit cust.plm
Umsetzung der Anforderung ist nun vollständig im SCM-System (Source-Code und Konfiguration) und kann ausgeliefert werden.
Auslieferung erfolgt in den Übergabepunkt; Branch foo
des Auftraggebers.
$ git push origin foo
...
[PATCH 1/2] configured 'foo' schema
[PATCH 2/2] implemented class 'Foo'
Die Transportwege für die Übernahme und Auslieferung einer Beauftragung können mit git individuell gewählt werden (SVN schränkt sehr ein). Hier wurde ein online Szenario beschrieben, die zur Verfügung stehenden Protokolle wurden schon erwähnt.
git ist – wie kein anders SCM-System – für dezentral und offline ausgelegt. Lösungen für offline Szenarien sind z.B. git-send-email oder git-bundle .. um nur zwei zu nennen.
Es muss einen reproduzierbaren Übergabepunkt (Gesammtzustand des Systems) geben. Hierfür eignet sich ein Branch.
Es muss ein Spiegel beim Lieferant aufgebaut werden. I.d.R. wird man nie alle Dienste und Funktionen auf dem Spiegel einrichten (zu Aufwendig).
Lieferant plant die Implementierung, setzt sie um, testet sie und liefert sie wieder an den Übergabepunkt aus.
Bisher nicht betrachtet, wie bekommt der Auftrageber die Änderung in seinen
master
? Dazu siehe auch Releasemanagement und CONTACT Elements.
Der Merge des Branch foo
enspricht genau dem Merge-Schaubild. Es gibt den Branch-Point und im Merge-Point sollen die
Änderungen aus Source-Code (git merge
) und Konfiguration (cdbpkg
) im
master
Branch zusammengeführt werden.
Für den diff
wird der Working-tree des Branch-Points benötigt.
$ git worktree add /tmp/foo-start 268a44e
$ git worktree list
/path/to/cust.plm 3e3838e [foo]
/tmp/foo-start 268a44e (detached HEAD)
Der Branch-Point 268a44e
wurde aus dem Log entnommen. Die Kopie des
Branch-Points liegt nun unter /tmp/foo-start
.
Branch foo
wird ausgecheckt, jetzt diff zum Branch-Point ermitteln
$ git checkout foo
$ cdbpkg diff cust.plm -p /tmp/foo-start -d /tmp
Writing changes to directory /tmp/patch_cust.fo_xx_yyyy
11 changes on cust.foo
1 changes on cust.plm
Der Patch liegt jetzt bereit unter …
$ dir /tmp/patch_cust.fo_xx_yyyy
Die Vorbereitungen sind damit abgeschlossen, der eigentliche Merge
(SCM-Merge + cdbpkg patch
) kann nun beginnen.
SCM-Merge für Source-Code & cdbpkg patch
für Konfiguration
$ cd cust.plm
$ git checkout master
$ git merge foo # SCM-Merge
$ cdbpkg patch /tmp/patch_cust.fo_xx_yyyy # CDB-Merge
Konflikte in CDB auflösen, anschließend commiten
$ cdbpkg build cust.plm
$ git add --all .
$ git commit -m "merged branch 'foo'"
$ cdbpkg commit cust.plm
Konflikte in Sourcen werden vom SCM-System erkannt. Außnahme ist
configuration
siehe Merge Strategie.
Konflikte in Konfiguration werden von CDB erkannt. Letztere werden über
das Protokoll eingesehen und mit anderen Warnungen in CDB behandelt.
Source-Code wird vom SCM-System gemerged.
configuration
benötigt andere Merge Strategie
Um Konfig-Änderungen zu mergen, muss der Start-Punkt reproduzierbar sein. Hierfür eignen sich die Branch-Points.
Der master
war exemplarisch, i.d.R. wird man für den master min. zwei
Branches haben: QS
und PROD
Der Transport zw. QS
und PROD
ist wieder vergleichbar, nur mit anderem
Branch-Point und Merge-Point.
Für die Umsetzung eines Features (einer Anforderung) gibt es den
Feature-Branch. Im Merge-Point werden die Änderungen aus Source-Code (git
merge
) und Konfiguration (cdbpkg
) im master
Branch zusammengeführt
werden.
CIM DATABASE (CDB) und CONTACT Elements sind Produktenamen der Contact Software GmbH.