Konfigurationsskripte

Konfigurationsskripte dienen der Einrichtung des Systems. Durch diese werden Default-Konfigurationen vorgenommen. Daher werden diese nur einmal pro Systemstrukturelement oder pro System ausgeführt. Zur Konfiguration gehört beispielsweise das Anlegen von Default-Stammdaten oder anderer höherwertiger Default-Konfigurationen für Ausführungsrechte.

Da Bausteine "persistente" Caches haben (können), ist es hier sinnvoll, diese Konfigurationen per Service durchzuführen, damit diese per Events sich im System verteilen. Daher werden diese Konfiguration häufig nicht über Datenbank-Patches erstellt. Jeder Baustein bringt seine eigenen Konfigurationsskripte mit und bezieht sich auch nur auf die eigene Funktionalität bis auf die Plattformfunktionalität.

Konfigurationsskripte sind normale Powershell-Skripte und

  • können manuell mithilfe des Cmdlets Invoke-CSConfigurationScript [-Name] einzeln oder zusammen aufgerufen werden
  • müssen einer definierten Signatur genügen
  • werden durch die Installation automatisch ausgeführt.

Nachfolgend ist ein exemplarisches Konfigurationsskript zu sehen.

[CmdletBinding()]
Param(
    [Parameter(Mandatory = $True, Position = 0)]
    [string] $sessionToken,
    [Parameter(Mandatory=$True, Position = 1)]
    [string] $namespace
)
$defaultSystemUsage = Select-SystemUsage | Where-Object { $_.IsDefault -eq $true}
if (!$defaultSystemUsage)
{
    $defaultSystemUsage = Select-SystemUsage | Where-Object { $_.IsProductive -eq $true}
}
if (!$defaultSystemUsage)
{
    Write-Error 'Default Verwendungszweck könnte nicht ermittelt werden.'
}
$customDataType = Select-CustomDataType -Name Schleupen.AS.MT.BIB.Buecher.BuchVerlustAbwickelnTask_3.1
if (-not $customDataType)
{
    Write-Error "Es wurde kein passender CustomDataType gefunden!"
}
$systemSessionToken = Request-SessionToken -ViewName Standard -ElementTypeName System -ElementName System -SystemUsages $defaultSystemUsage.Name
New-TaskType -Name "AS.MT.BIB: Buchverlust abwickeln" -DelegationId "S-1-1-0" -CustomDataTypeId $customDataType.Id -SessionToken $systemSessionToken
New-TaskType -Name "AS.MT.BIB: Benutzer kontaktieren" -DelegationId "S-1-1-0" -SessionToken $sessionToken
New-TaskType -Name "AS.MT.BIB: Sachbearbeiter kontaktieren" -DelegationId "S-1-1-0" -SessionToken $sessionToken
New-TaskType -Name "AS.MT.BIB: Buchverlust abwickeln" -DelegationId "S-1-1-0" -CustomDataTypeId $customDataType.Id -EditDialogFlowId "Schleupen.AS.mal.bal.bap.BuchVerlustAbwickelnTaskFlow_3.1" -SessionToken $sessionToken

Hier ist zu erkennen, dass in der Signatur das $sessionToken als Parameter erwartet wird. Ist ein derartiger Parameter vorhanden, so wird das Konfigurationsskript pro Systemstrukturelement ausgeführt (genauer: siehe Konfigurationsskripte mit Systemstrukturbezug). Ist das Konfigurationsskript Parameter-los, so wird es einmal pro System ausgeführt.

In einer Solution werden Konfigurationsskripte abgelegt, durch spezielle Installationspackages definiert und in das System gebracht. Ein Package-Builder erzeugt diesen Pakettyp.

Konfigurationsskripte werden durch das Deployment unter %Programfiles%\Schleupen\ConfigurationScripts abgelegt.

Folgende Regeln müssen bei der Erstellung von Konfigurationsskripten beachtet werden:
  • direkte DB-Zugriffe (z.B. per SQL) sind nicht erlaubt
  • Zuordnungen von DB-Schemata zu Systemstrukturen sind nicht erlaubt
  • Konfigurationsskripte dürfen Systemstrukturelementtypen und DB-Schemata in der Systemstruktur nicht voraussetzen

Ausführungsreihenfolge

Die Ausführungsreihenfolge der Konfigurationsskripte über Bausteine hinweg ist nicht deterministisch. Die Reihenfolge wird implizit durch die Registrierung in der Datenbank vorgegeben. Ergo: Man kann sich nicht auf eine feste Ausführungsreihenfolge verlassen.

Die Ausführungsreihenfolge der Konfigurationsskripte eines Bausteins hingegen ist deterministisch: Durch eine Nummer als Präfix (siehe Abbildung oben) wird die Ablage im Deployment Package festgelegt und somit diese in genau der spezifizierten Weise installiert und somit in dieser Reihenfolge ausgeführt.

Konfigurationsskripte mit einem Bezug zu Systemstrukturelementen

Konfigurationsskripte können, wie oben bereits beschrieben, einen Bezug zu Systemstrukturelementen haben. Als Erkennung hierfür wird geprüft, ob das Konfigurationsskript einen Parameter $sessionToken vom Typ String hat. Konfigurationsskripte bekommen dann einen sogenannten ExecutionScope, der steuert, in welchem Kontext die Skripte ausgeführt werden: Mögliche Werte für den ExecutionScope sind Global und SystemStructureElement.

Mithilfe der Serviceimplementierungsgruppe wird im Falle eines Systemstrukturbezugs über Serviceimplementierungsgruppe gesteuert, auf welchen Systemstrukturknoten die Konfigurationsskripte ausgeführt werden. Konfigurationsskripte sind über den ausliefernden Baustein einer Serviceimplementierungsgruppe zugeordnet.

Bei Ausführung von Invoke-CSConfigurationScript bzw. Complete-CSInstallation werden die Konfigurationsskripte mit allen relevanten SessionTokens entsprechend der Systemstrukturelemente ausgeführt. Relevante SessionTokens für die Ausführung eines Konfigurationsskripts werden wie folgt ermittelt:

  • Falls die Serviceimplementierungsgruppe des Konfigurationsskripts mindestens einem Systemstrukturelement zugeordnet ist, werden SessionTokens für die zugeordnete Systemstrukturelemente (eins pro Verwendungszweck) verwendet
  • Falls die Serviceimplementierungsgruppe des Konfigurationsskripts keinem Systemstrukturelement zugeordnet ist, werden die Systemstrukturelemente ermittelt, an denen ein DatenbankSchema mit gleichnamiger Serviceimplementierungsgruppe zugeordnet ist.
  • Ansonsten wird ein Konfigurationsskript nicht ausgeführt. In diesem Fall muss die Serviceimplementierungsgruppe zugeordnet werden.

Konfigurationsskripte mit direktem Service-Aufruf

Konfigurationsskripte sollten im Standard gekapselt Logik ausführen, indem Cmdlets angebunden werden, die entsprechend idempotent und stabil sind. Es können aber auch Services mithilfe des Cmdlets Get-ServiceClient direkt aufgerufen werden:

[CmdletBinding()]
Param(
  [Parameter(Mandatory=$True, Position = 0)]
  [string] $sessionToken,
  [Parameter(Mandatory=$True, Position = 1)]
  [string] $namespace
)

$buchServiceID = "Schleupen.CS.MT.BIB.Buecher.EntityService_3.2"
$nsBuchService = ($namespace + "_Buch")
$buchService = Get-ServiceClient $buchServiceID  -Namespace $nsBuchService -EnableRetries

try
{
  $request = New-Object "$nsBuchService.CreateRequest"

  $buch_bpmn20 = New-Object "$nsBuchService.BuchContract"
  $buch_bpmn20.Titel = "Praxishandbuch BPMN 2.0"
  $buch_bpmn20.Isbn = "978-3-446-42986-4"
  $buch_bpmn20.Autor = "J. Freund, B. Rücker"
  $buch_bpmn20.Sprache = "Deutsch"
  $buch_bpmn20.Zusammenfassung = "Lernen Sie die Notation der BPMN 2.0 kennen."
  $buch_bpmn20.Genre = [System.Enum]::Parse("$nsBuchService.GenreContract", "Krimi") 
  $buch_bpmn20.Id = "7f6d2187-f462-46b1-ab6d-9d156d575a7d"
  
  $request.SessionToken = $sessionToken
  $request.BuchListe = @($buch_bpmn20)
 
  $buchService.Create($request)
}
finally
{
  $buchService.CloseSafely()
}

Wichtige Hinweise

  • Ab PI.DP Version 3.41.2.7 / Schleupen.CS.CreateConfigurationScriptsPackage Version 3.42.1.11 können und sollten Konfigurationsskripte mit einem $namespace Parameter versehen werden. Dies ist eine Optimierung bzgl. der Systemstruktur, wenn die Skripte in mehreren Knoten ausgeführt werden: Die Typen und der ServiceClient werden dann nur einmal generiert.
  • Um den ServiceClient auch Fehlerfall korrekt zu schließen, sollte die Erweiterungsmethode CloseSafely() im finally-Block verwendet werden.
  • Über die Option -EnableRetries kann eine Retry-fähige Instanz des ServiceClients generiert werden. Dieser wiederholt den Service-Aufruf bei aufgetretenen Fehlern und setzt sich bei Bedarf selbst zurück, falls er sich im Zustand Faulted befindet. Dementsprechend kann ein Retry-fähiger Client auch dann wiederverwendet werden, wenn der Service-Aufruf nach allen Retries nicht erfolgreich war. Ohne die Angabe weiterer Parameter wiederholt ein Retry-fähiger Client einen Service-Aufruf bis zu 10 mal in einem Abstand von 5 Sekunden zwischen einem Fehler und dem nächsten Aufrufversuch. Über die Parameter -RetryCount (Anzahl der Wiederholungen) und -RetryInterval (Zeit zwischen den Wiederholungen in Sekunden) können diese Werte übersteuert werden.
  • Alle über das Cmdlet generierten ServiceClients unterstützen per se den Aufruf von Services, welche die Idempotenz-API aus SB (Schleupen.CS.PI.SB.Idempotency) angeschlossen haben. Diese API stellt sicher, dass sich Service-Operationen in einem gewissen Zeitfenster idempotent verhalten, insofern über einen sog. Idempotenzschlüssel als identisch gekennzeichnete Service-Aufrufe dasselbe Ergebnis liefern und mehrmalige Aufrufe mit gleichem Idempotenzschlüssel trotzdem nur zur einmaligen Ausführung der Operationslogik auf der Serverseite führen.

Beispiel-Package

Die PackageMetadata.xml beschreibt exemplarisch ein ConfigurationScript-Package und hat folgende Gestalt.

<Package xmlns:i="http://www.w3.org/2001/XMLSchema-instance" i:type="ConfigurationScriptPackage" xmlns="urn://Schleupen.CS.PI.DP.Packaging_3.1">
  <Artifact>
    <Id>Schleupen.AS.MT.BIB.ConfigurationScripts_3.1</Id>
    <Version>3.1.212.1</Version>
    <Description>Konfigurationsskripte für Schleupen.AS.MT.BIB</Description>
  </Artifact>
  <Content>
    <ContentElement i:type="FileElement">
      <Name>Schleupen.AS.MT.BIB.AddSchema_1.0.ps1</Name>
      <Folder>.</Folder>
      <TargetFolder>.</TargetFolder>
    </ContentElement>
    <ContentElement i:type="FileElement">
      <Name>Schleupen.AS.MT.BIB.CreateTestData_1.0.ps1</Name>
      <Folder>.</Folder>
      <TargetFolder>.</TargetFolder>
    </ContentElement>   
    <ContentElement i:type="ConfigurationScriptsRegistrationElement">
      <Scripts/>    
      <ScopedScripts>
        <Script>
          <ArtifactId>Schleupen.AS.MT.BIB.AddSchema_1.0</ArtifactId>
          <ExecutionScope>Global</ExecutionScope>
        </Script>
        <Script>
          <ArtifactId>Schleupen.AS.MT.BIB.CreateTestData_1.0</ArtifactId>
          <ExecutionScope>SystemStructureElement</ExecutionScope>
          <HasNamespaceParameter>true</HasNamespaceParameter>
        </Script>
      </ScopedScripts>
      <ServiceImplementationGroup>Bibliotheksverwaltung</ServiceImplementationGroup>
    </ContentElement>
  </Content>
  <DeploymentRoles>
    <DeploymentRole>BusinessProcessServer</DeploymentRole>
  </DeploymentRoles>
  <Purpose>Productive</Purpose>
</Package>

Der ExecutionScope wird anhand des Parameters ermittelt.

Konfigurationsskripte haben die Eigenschaft HasNamespaceParameter, die steuert ob der Parameter $namespace von außen beim Ausführen der Skripte wie im Beispiel oben reingegeben wird. 

Cookie Consent mit Real Cookie Banner