Categorie: configuration Bijgewerkt: 2026-05-19 packages versiebeheer OTAP uct configuratie

Package Manager

De Package Manager is het versiebeheer- en distributiemechanisme voor alle UCT-aanpassingen. Pakketten worden gebruikt om configuratiewijzigingen te transporteren tussen Ultimo-omgevingen in een OTAP-straat (Ontwikkeling, Test, Acceptatie, Productie).

Gerelateerd: uct-overzicht, screens, workflows/workflow-engine


Locatie in UCTbewerken

UCT > Package Manager


Schermindelingbewerken

Navigatieboom (links)bewerken

Categorieën: Entities, Workflows, Business Rules, System Configuration, Agenda Integration, Development.

Pakkettenlijst (midden)bewerken

Kolom Beschrijving
Name Bestandsnaam (vaak met datumprefix)
Valid Of het pakket geldig/gevalideerd is
Title Korte beschrijving van het pakketdoel
Description Uitgebreidere beschrijving
Revision Revisienummer
Merged Of het pakket is samengevoegd met de omgeving
Custom code Of het pakket aangepaste code bevat
Date Aanmaak-/uploaddatum

Detailpaneel (rechts)bewerken


Werkwijzebewerken

Pakket aanmakenbewerken

  1. Maak configuratiewijzigingen in de UCT (O-omgeving)
  2. Exporteer de wijzigingen als pakket via Package Manager
  3. Geef het pakket een beschrijvende naam en titel

Pakket importerenbewerken

  1. Upload het pakket naar de doelomgeving (T/A/P)
  2. Controleer de Ultimo Revision Base — deze moet overeenkomen met de doelomgeving
  3. Importeer en controleer de Merged-status

Praktische tipsbewerken

Valkuil: Importeer nooit een pakket rechtstreeks naar productie zonder eerst te testen in acceptatie. De OTAP-straat bestaat niet voor niets.



Stap-voor-stap: Pakket aanmaken en opnemenbewerken

1. Nieuw pakket aanmakenbewerken

  1. Open Package Manager via het UCT-hoofdmenu
  2. Klik Add (Ctrl+Alt+N) in de toolbar boven de pakkettenlijst
  3. Klik Edit (Ctrl+Alt+E) in het detailpaneel
  4. Vul de velden in:
    • Title — Beschrijvende naam (bijv. "JobScreenAanpassing_KlantX")
    • Customer reference — Referentie van de klant
    • Ultimo reference — Referentie van Ultimo
    • Remarks — Aanvullende opmerkingen
  5. Klik Save (Ctrl+Alt+S)

2. Opname starten (recording)bewerken

  1. Selecteer het pakket in de lijst
  2. Klik Start recording — het rode opname-icoon verschijnt rechtsboven in de navigatiebalk
  3. De pakketregel krijgt een rode balk aan de linkerzijde en vetgedrukte tekst
  4. Voer nu configuratiewijzigingen uit in de UCT

Acties die automatisch worden opgenomen:

Bestanden die handmatig worden toegevoegd:

Let op: Nieuwe workflows of wijzigingen aan bestaande workflows worden NIET automatisch opgenomen. Je moet de workflow-bestanden apart overdragen of ze publiceren naar het pakket.

3. Opname pauzeren/hervattenbewerken

4. Opname stoppenbewerken

  1. Open de Package Manager
  2. Selecteer het opnamepakket
  3. Klik Stop recording
  4. Als bestanden out-of-sync zijn verschijnt een dialoog; klik Synchronise om bij te werken

5. Bestanden in het pakket controlerenbewerken


Stap-voor-stap: Pakket transporterenbewerken

Downloadenbewerken

  1. Selecteer het pakket in de Package Manager
  2. Klik Download (Ctrl+Alt+D) — het .up-bestand wordt gedownload
  3. Bewaar het bestand op een veilige locatie

Let op: Wijzig nooit de extensie (.up) van het pakketbestand.

Uploadenbewerken

  1. Open de Package Manager in de doelomgeving
  2. Klik Upload (Ctrl+Alt+U)
  3. Klik Select en kies het .up-bestand
  4. Klik OK — het pakket verschijnt in de lijst

Stap-voor-stap: Pakket validerenbewerken

  1. Selecteer het pakket (moet een opname bevatten en Revertible zijn)
  2. Klik Validate in het detailpaneel
  3. Bij succes: melding "validation succeeded without conflicts"
  4. Bij conflicten: waarschuwing met de specifieke issues

Tip: Valideer altijd voor het toepassen. Conflicten kunnen optreden bij afwijkende databasestructuren of ontbrekende afhankelijkheden.


Stap-voor-stap: Pakket toepassen (Apply)bewerken

  1. Selecteer het pakket
  2. Klik Apply in het detailpaneel
  3. Bij succes: bevestigingsdialoog
  4. Bij fouten: foutmelding met details
  5. Na toepassen wordt de knop Revert beschikbaar

Stap-voor-stap: Pakket terugdraaien (Revert)bewerken

  1. Selecteer het toegepaste pakket
  2. Klik Revert in het detailpaneel
  3. Alle acties worden ongedaan gemaakt

Waarschuwing: Als het pakket de bestanden applicationelement.appel en applicationstructure.appstru bevat, wordt de AET naar de factory default teruggezet!


Pakketten samenvoegen (Merge)bewerken

  1. Selecteer meerdere pakketten (Ctrl+klik)
  2. Klik Merge selected packages
  3. Controleer de volgorde (de selectievolgorde bepaalt de mergevolgorde)
  4. Klik OK

Het samengevoegde pakket bevat de acties van alle bronpakketten in de opgegeven volgorde.


Pakketbestandenbewerken

Elk pakket bestaat uit twee bestanden in de map FileServiceData/Packages:

Extensie Beschrijving
.up Pakketinhoud die kan worden toegepast
.rup Rollback-bestand voor het terugdraaien

Het .rup-bestand wordt aangemaakt bij opname of bij het toepassen van een geupload pakket.


Technische structuur van een .up-bestandbewerken

Een .up-bestand is een standaard ZIP-archief met de volgende structuur:

PackageDefinition.xml
FileServiceData/
  Mobile/TechnicalService/Menu/UserContent_Menu.mnm
  Mobile/TechnicalService/Screens/UserContent_Job.scm
  Workflows/UserContent_MyWorkflow_Pre.wfl
  ...

PackageDefinition.xmlbewerken

Het manifestbestand dat de package beschrijft. Moet beginnen met een UTF-8 BOM (EF BB BF), anders weigert Ultimo de import met de fout: "Invalid BOM for package definition".

Minimaal voorbeeld (alleen bestanden transporteren):

<Package Id="UNIEKE-ID" Customer="Klantnaam" OriginLocation="https://env.ultimo.net" OriginDTAP="Development" CreateDate="2026-04-14 13:00:00Z" UserId="gebruiker" EmployeeDescription="omschrijving" Title="pakkettitel" Owner="EIGENAAR">
  <Section Id="1000" Description="Beschrijving" CreateDate="2026-04-14T13:00:00" />
</Package>

De PackageDefinition kan ook acties bevatten, zoals gebruikerswijzigingen of parametersettings:

<Section Id="1000" Description="Default" CreateDate="2026-04-14T13:00:00">
  <User BlockNumber="1" Action="Update" Id="USERID">
    <Authorization Action="Remove" Id="GROEPID" />
  </User>
  <Parameters BlockNumber="2" Scope="Group:GROEP">
    <Parameter Action="Set" Id="Ultimo.GoPlus" Value="True" />
  </Parameters>
</Section>

Beperkingenbewerken

Beperking Waarde Foutmelding
Bestandsnaam .up Max 34 tekens "Input string too long for column 'pacfilename'"
BOM op PackageDefinition.xml UTF-8 BOM verplicht "Invalid BOM for package definition"
Hash-attribuut op <Workflow> Verplicht, SHA1 over content zonder BOM en zonder Hash-attribuut "Workflow '' was edited with an unauthorized tool"

FileServiceData mapstructuurbewerken

Bestanden in FileServiceData/ worden bij import naar de Ultimo File Service geschreven. De mapnamen gebruiken PascalCase:

Pad Inhoud
Mobile/<App>/Menu/ Go menu-bestanden (.mnm)
Mobile/<App>/Screens/ Go schermbestanden (.scm)
Mobile/<App>/Dataset/ Go datasets (.lsm)
Mobile/<App>/Entity/ Go entity templates (.ety)
Workflows/ Workflow-bestanden (.wfl)

Waarbij <App> bijvoorbeeld TechnicalService, SelfService, InformationTechnology of Default is.

Workflow hash-attribuutbewerken

Elke .wfl in een package moet op de <Workflow>-root een Hash="..."-attribuut bevatten met een SHA1 over de eigen content. Klopt dit niet, dan weigert Ultimo het bestand zowel bij import als bij openen in de Workflow Designer met:

WorkflowException (0x10005013): Workflow_RunDesigner ... Workflow '<naam>' was edited with an unauthorized tool

Algoritme (reverse-engineered, round-trip geverifieerd op 2026-05-19):

PowerShell-implementatie:

function Get-WorkflowHash {
    param([string]$Path)
    $bytes = [System.IO.File]::ReadAllBytes($Path)
    if ($bytes.Length -ge 3 -and $bytes[0] -eq 0xEF -and $bytes[1] -eq 0xBB -and $bytes[2] -eq 0xBF) {
        $bytes = $bytes[3..($bytes.Length - 1)]
    }
    $content        = [System.Text.Encoding]::UTF8.GetString($bytes)
    $contentNoHash  = [regex]::Replace($content, 'Hash="[^"]*"\s+', '', 1)
    $sha1           = [System.Security.Cryptography.SHA1]::Create()
    $hashBytes      = $sha1.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($contentNoHash))
    return ($hashBytes | ForEach-Object { $_.ToString("X2") }) -join ""
}

Werkwijze voor een nieuwe of buiten-Ultimo bewerkte .wfl:

  1. Schrijf het bestand met <Workflow Hash="" Version="..." ...> (lege placeholder; spatie erna behouden zodat de regex blijft kloppen na injectie).
  2. Bereken de hash met de functie hierboven.
  3. Vervang Hash="" door Hash="<computed>".
  4. Schrijf terug met UTF-8 BOM en CRLF line-endings (consistent met de Workflow Designer-output).
  5. Round-trip-test: hash opnieuw berekenen → moet exact gelijk zijn aan het opgeslagen Hash-attribuut. Slaagt deze niet, dan staat de spatie na het Hash-attribuut waarschijnlijk verkeerd, of zit er een BOM-byte mee in de hash-input.

Wanneer is dit nodig? Workflows die je via de Workflow Designer in UCT publiceert krijgen automatisch een geldige hash — daar hoef je niets te doen. Het algoritme hierboven is alleen relevant wanneer je workflow-XML buiten Ultimo om aanmaakt of bewerkt (bv. via scripting, templating of het samenstellen van een .up-package zonder UCT in de loop).


PackageDefinition.xmlbewerken

Het manifestbestand dat de package beschrijft. Moet beginnen met een UTF-8 BOM (EF BB BF), anders weigert Ultimo de import met de fout: "Invalid BOM for package definition".

Minimaal voorbeeld (alleen bestanden transporteren):

<Package Id="UNIEKE-ID" Customer="Klantnaam" OriginLocation="https://env.ultimo.net" OriginDTAP="Development" CreateDate="2026-04-14 13:00:00Z" UserId="gebruiker" EmployeeDescription="omschrijving" Title="pakkettitel" Owner="EIGENAAR">
  <Section Id="1000" Description="Beschrijving" CreateDate="2026-04-14T13:00:00" />
</Package>

De PackageDefinition kan ook acties bevatten, zoals gebruikerswijzigingen of parametersettings:

<Section Id="1000" Description="Default" CreateDate="2026-04-14T13:00:00">
  <User BlockNumber="1" Action="Update" Id="USERID">
    <Authorization Action="Remove" Id="GROEPID" />
  </User>
  <Parameters BlockNumber="2" Scope="Group:GROEP">
    <Parameter Action="Set" Id="Ultimo.GoPlus" Value="True" />
  </Parameters>
</Section>

Beperkingenbewerken

Beperking Waarde Foutmelding
Bestandsnaam .up Max 34 tekens "Input string too long for column 'pacfilename'"
BOM op PackageDefinition.xml UTF-8 BOM verplicht "Invalid BOM for package definition"

FileServiceData mapstructuurbewerken

Bestanden in FileServiceData/ worden bij import naar de Ultimo File Service geschreven. De mapnamen gebruiken PascalCase:

Pad Inhoud
Mobile/<App>/Menu/ Go menu-bestanden (.mnm)
Mobile/<App>/Screens/ Go schermbestanden (.scm)
Mobile/<App>/Dataset/ Go datasets (.lsm)
Mobile/<App>/Entity/ Go entity templates (.ety)
Workflows/ Workflow-bestanden (.wfl)

Waarbij <App> bijvoorbeeld TechnicalService, SelfService, InformationTechnology of Default is.


ApiKey-permissies in PackageDefinition.xmlbewerken

Een <ApiKey>-block in PackageDefinition.xml configureert REST-API-rechten zonder ze handmatig in UCT te hoeven prikken. Onderliggende <Resource>-blokken sturen de ApiKeyEntityPermission-records aan, en geneste <Property>-elementen de ApiKeyPropertyPermission-records.

Voorbeeldbewerken

<ApiKey Action="Insert" Id="ESKMAIL" UserId="US0000004" CompanyId="000001"
        Status="2" DailyRateLimit="0" DataProvider=""
        Description="Eska Inkoop Mail Agent"
        CreateDate="2026-04-28T12:00:00" ExpiryDate="2099-01-01"
        IsCustom="True" Multilingual="True">
  <Resource EntityName="Purchase" AuthorizationLevel="Read">
    <Property PropertyName="Description" />
    <Property PropertyName="Vendor" />
    <Property PropertyName="DeliveryDate" />
  </Resource>
  <Resource EntityName="PurchaseLine" AuthorizationLevel="Update">
    <Property PropertyName="Article" />
    <Property PropertyName="DeliveryDate" />
    <Property PropertyName="_ConfirmedRecieptDate" />
  </Resource>
</ApiKey>

AuthorizationLevel — geldige waardenbewerken

Waarde Betekenis
Read Alleen lezen (GET)
Add Read + records aanmaken (POST)
Update Add + records wijzigen (PATCH/PUT)
Delete Update + records verwijderen (DELETE)

Let op: View en Modify werken niet — geven "Requested value 'View' was not found" / "Requested value 'Modify' was not found". Gebruik Read resp. Update.

Implicit properties — NIET listenbewerken

Sommige properties krijg je automatisch met de Resource-permissie en mogen niet expliciet in een <Property>-element staan, anders faalt de import met "Cannot find property with the name 'X' in entity 'Y'".

Implicit Voorbeeld
Id (single primary key) Purchase.Id, Vendor.Id, Article.Id
Id.X (composite-key sub-properties) PurchaseLine.Id.LineId, PurchaseLine.Id.Purchase, ReceiptLine.Id.LineId, ReceiptLine.Id.Receipt

Composite-key Ids verschijnen in lookup_entity() als losse properties (Id.LineId, Id.Purchase), maar in package-XML gelden ze als deel van de primary key — dus listen van Purchase op PurchaseLine of Receipt op ReceiptLine faalt.

Tenant-afhankelijke propertiesbewerken

Niet elke property die lookup_entity() toont bestaat ook in elke tenant. Deze zijn afhankelijk van UCT-instellingen op tabel-niveau:

Property Voorwaarde
RecordChangeDate "Track changes" voor die tabel staat aan
RecordCreateDate Idem (vrijwel altijd aan, maar verifieer)

Bij een tenant waar dit uitstaat: foutmelding "Cannot find property with the name 'RecordChangeDate' in entity 'X'". Verwijder het property-element of zet change-tracking aan in UCT.

ApiKey Id moet uniek zijn per tenantbewerken

Het Id-attribuut op <ApiKey Action="Insert"> moet uniek zijn binnen de doelomgeving. Bij een conflict (vaak met de standaard 0001): "Section 1000 | Block #1 - ApiKey '0001' already exists". Kies een beschrijvende prefix zoals ESKMAIL of ITSM01 om botsing te voorkomen.

Workflow- en filter-permissiesbewerken

Naast <Resource> kent het ApiKey-block ook:

Pakketindicatorenbewerken

Kolom Beschrijving
Auto Automatisch aangemaakt (geen actieve opname) of handmatig opgenomen
Revertible Kan worden teruggedraaid (vinkje)
State Recording-status: Started, Paused, Stopped
Current user Gebruiker die momenteel opneemt

Tip: Je kunt een opname van een andere gebruiker overnemen door Start recording te klikken op hun pakket en "Yes" te bevestigen.


Brondatabewerken

Dit artikel is consultant-synthese. Voor ground-truth data over specifieke Ultimo-objecten gebruik de onderstaande tools.


Zie ookbewerken