Is it possible to enumerate Rundeck input variables in script? - rundeck

Example usecase: Enumerate input options from Rundeck inputs by as script as an array to cycle through.
Dynamically read all user provided input options from Rundeck
I understand that inputs can be referenced by #option.inputname#
My question: Is there a input array that can be referenced in order to cycle through inputs?
Example language: Powershell
$Inputs = #options#
foreach($Input in $Inputs)
{
Write-Host $Input
}
The question is not to cycle through an array for one input but instead collect all inputs as an array.
Job Eg:
defaultTab: nodes
description: ''
executionEnabled: true
group: Test/Example
id: e6c16942-baf0-4255-9c05-87bc11f66f6f
loglevel: INFO
name: StackOverflow-Example
nodeFilterEditable: false
options:
name: User
name: city
name: location
name: telephone
scheduleEnabled: true
sequence:
commands:
script: getopts
keepgoing: false
strategy: node-first
uuid: e6c16942-baf0-4255-9c05-87bc11f66f6f
Can options as an array be collected by commandline ? I know this is possible via Rundecks API but my use case will be to achieve this in-script :-)
Do not believe that this is possible.

Sure, in this way (my example is under Bash):
echo "starting"
for i in #option.opt1#
do
echo "Welcome $i times"
done
I leave the job definition with an editable option by any user:
<joblist>
<job>
<context>
<options preserveOrder='true'>
<option name='opt1' value='1 2 3 4 5' />
</options>
</context>
<defaultTab>nodes</defaultTab>
<description></description>
<executionEnabled>true</executionEnabled>
<id>298a3027-ede0-47f0-be88-308647839b82</id>
<loglevel>INFO</loglevel>
<name>JobEnumerate</name>
<nodeFilterEditable>false</nodeFilterEditable>
<scheduleEnabled>true</scheduleEnabled>
<sequence keepgoing='false' strategy='node-first'>
<command>
<script><![CDATA[echo "starting"
for i in #option.opt1#
do
echo "Welcome $i times"
done]]></script>
<scriptargs />
</command>
</sequence>
<uuid>298a3027-ede0-47f0-be88-308647839b82</uuid>
</job>
</joblist>
And the result here.

Related

Service is failing with no exception thrown

I am somewhat new at developing in the VS C# environment and have come across the following issue. I have developed a C# service (BrassSS) that interfaces to an MS Access database and has been running since February 2018. The service is meant to perform a nightly backup at 4:00am, send reminder emails at 7 am, and status emails at 10,2, and 6 daily. This has all been running fine for years until about a week ago when a customer calls me that reminder emails were not working. BrassSS keeps a log which I checked and noticed that the service is now dying just a few milliseconds later when I attempt to open the database to send reminder emails at 7:00am. This had never happened so I have been trying to scour the internet with my limited knowledge and struggling with this. Note that I have a 'mirror' image of the service that I run as a console app (BrassConsoleApp), which also fails at the same location. I finally made it to the Event Viewer (two log entries shown below) and it would seem that an unhandled exception is occurring.
I don't know if this helps, and may only add to the confusion, but in the last month I have switched MS Access from 2007 to 2016. Having said that, note that at 4:00am, when the backup kicks in, the exact same code you see below to open the database, runs with no issue.
So at 7:00am, the timer elapses and I need to open the database, here is my code:
class DBif
{
const string cstClassName = "DBif";
private OleDbConnection conDB;
private string strPathToBEFile;
public bool openDB(string strFullPathToDB) {
// Connects to the DB
this.strPathToBEFile = strFullPathToDB;
try {
if (this.conDB != null) {
this.conDB.Close();
}
Logs.addEvent("Info", cstClassName, "openDB", "Attempt to Open DB: " + strPathToBEFile); //debug
string connectionString = "Provider=Microsoft.ACE.OLEDB.16.0;Data Source=" + strPathToBEFile + ";Jet OLEDB:Database Password=" + "----------" + ";";
Logs.addEvent("Info", cstClassName, "openDB", "Connection string: " + strPathToBEFile); //debug
this.conDB = new OleDbConnection(connectionString);
Logs.addEvent("Info", cstClassName, "openDB", "conDB successfull " + strPathToBEFile); //debug
this.conDB.Open(); ***<---- I place a breakpoint here, step over it, and the app FAILS WITH NO EXCEPTION***
Logs.addEvent("Info", cstClassName, "openDB", "DB Opened successfully: " + strPathToBEFile); //debug
return true;
} catch (Exception ex) {
Logs.addEvent("CRITICAL", cstClassName, "openConnection", "Error trying to Open database: " + ex.Message);
return false;
}
}
.....
}
I am hoping that some expert can shed some light into this and help me get to the root cause.
This is the Event Viewer log entry showing an ERROR when the app fails;
Log Name: Application
Source: Application Error
Date: 2021-Jun-10 4:30:01 PM
Event ID: 1000
Task Category: (100)
Level: Error
Keywords: Classic
User: N/A
Computer: Dell5759
Description:
Faulting application name: BrassConsoleApp.exe, version: 1.0.0.0, time stamp: 0x60c2722d
Faulting module name: mso20win32client.dll, version: 0.0.0.0, time stamp: 0x60a155a8
Exception code: 0xc000041d
Fault offset: 0x001d3a12
Faulting process id: 0x49a8
Faulting application start time: 0x01d75e34f0fb2b15
Faulting application path: D:\BitCrafters\Dev\Brass\Next\BrassConsoleApp\bin\Debug\BrassConsoleApp.exe
Faulting module path: C:\Program Files (x86)\Common Files\Microsoft Shared\Office16\mso20win32client.dll
Report Id: b2318536-61c1-4958-85c0-a6803c4bbd3b
Faulting package full name:
Faulting package-relative application ID:
Event Xml:
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<Provider Name="Application Error" />
<EventID Qualifiers="0">1000</EventID>
<Version>0</Version>
<Level>2</Level>
<Task>100</Task>
<Opcode>0</Opcode>
<Keywords>0x80000000000000</Keywords>
<TimeCreated SystemTime="2021-06-10T20:30:01.9117979Z" />
<EventRecordID>200410</EventRecordID>
<Correlation />
<Execution ProcessID="0" ThreadID="0" />
<Channel>Application</Channel>
<Computer>Dell5759</Computer>
<Security />
</System>
<EventData>
<Data>BrassConsoleApp.exe</Data>
<Data>1.0.0.0</Data>
<Data>60c2722d</Data>
<Data>mso20win32client.dll</Data>
<Data>0.0.0.0</Data>
<Data>60a155a8</Data>
<Data>c000041d</Data>
<Data>001d3a12</Data>
<Data>49a8</Data>
<Data>01d75e34f0fb2b15</Data>
<Data>D:\BitCrafters\Dev\Brass\Next\BrassConsoleApp\bin\Debug\BrassConsoleApp.exe</Data>
<Data>C:\Program Files (x86)\Common Files\Microsoft Shared\Office16\mso20win32client.dll</Data>
<Data>b2318536-61c1-4958-85c0-a6803c4bbd3b</Data>
<Data>
</Data>
<Data>
</Data>
</EventData>
</Event>
SECOND EVENT VIEWER INFO LOG ENTRY JUST AFTER THE ONE ABOVE ---------------------------------------------------
Log Name: Application
Source: Windows Error Reporting
Date: 2021-Jun-10 4:30:04 PM
Event ID: 1001
Task Category: None
Level: Information
Keywords: Classic
User: N/A
Computer: Dell5759
Description:
Fault bucket 1496835596276001519, type 1
Event Name: APPCRASH
Response: Not available
Cab Id: 0
Problem signature:
P1: BrassConsoleApp.exe
P2: 1.0.0.0
P3: 60c2722d
P4: mso20win32client.dll
P5: 0.0.0.0
P6: 60a155a8
P7: c000041d
P8: 001d3a12
P9:
P10:
Attached files:
\\?\C:\TMP\{348A1C8B-8F9A-4947-A735-1A6662FAB73B} - OProcSessId.dat
\\?\C:\ProgramData\Microsoft\Windows\WER\Temp\WERBA96.tmp.dmp
\\?\C:\ProgramData\Microsoft\Windows\WER\Temp\WERBD95.tmp.WERInternalMetadata.xml
\\?\C:\ProgramData\Microsoft\Windows\WER\Temp\WERBDC5.tmp.xml
\\?\C:\ProgramData\Microsoft\Windows\WER\Temp\WERBDD3.tmp.csv
\\?\C:\ProgramData\Microsoft\Windows\WER\Temp\WERBE22.tmp.txt
These files may be available here:
\\?\C:\ProgramData\Microsoft\Windows\WER\ReportArchive\AppCrash_BrassConsoleApp._a65121a9886cf85d89cc2caea488de84ebbc6379_15a45da1_128d96b7-c591-43c7-8393-71b1b078c790
Analysis symbol:
Rechecking for solution: 0
Report Id: b2318536-61c1-4958-85c0-a6803c4bbd3b
Report Status: 268435456
Hashed bucket: e03e080836cae1e184c5d40b5330eaef
Cab Guid: 0
Event Xml:
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<Provider Name="Windows Error Reporting" />
<EventID Qualifiers="0">1001</EventID>
<Version>0</Version>
<Level>4</Level>
<Task>0</Task>
<Opcode>0</Opcode>
<Keywords>0x80000000000000</Keywords>
<TimeCreated SystemTime="2021-06-10T20:30:04.9119743Z" />
<EventRecordID>200411</EventRecordID>
<Correlation />
<Execution ProcessID="0" ThreadID="0" />
<Channel>Application</Channel>
<Computer>Dell5759</Computer>
<Security />
</System>
<EventData>
<Data>1496835596276001519</Data>
<Data>1</Data>
<Data>APPCRASH</Data>
<Data>Not available</Data>
<Data>0</Data>
<Data>BrassConsoleApp.exe</Data>
<Data>1.0.0.0</Data>
<Data>60c2722d</Data>
<Data>mso20win32client.dll</Data>
<Data>0.0.0.0</Data>
<Data>60a155a8</Data>
<Data>c000041d</Data>
<Data>001d3a12</Data>
<Data>
</Data>
<Data>
</Data>
<Data>
\\?\C:\TMP\{348A1C8B-8F9A-4947-A735-1A6662FAB73B} - OProcSessId.dat
\\?\C:\ProgramData\Microsoft\Windows\WER\Temp\WERBA96.tmp.dmp
\\?\C:\ProgramData\Microsoft\Windows\WER\Temp\WERBD95.tmp.WERInternalMetadata.xml
\\?\C:\ProgramData\Microsoft\Windows\WER\Temp\WERBDC5.tmp.xml
\\?\C:\ProgramData\Microsoft\Windows\WER\Temp\WERBDD3.tmp.csv
\\?\C:\ProgramData\Microsoft\Windows\WER\Temp\WERBE22.tmp.txt</Data>
<Data>\\?\C:\ProgramData\Microsoft\Windows\WER\ReportArchive\AppCrash_BrassConsoleApp._a65121a9886cf85d89cc2caea488de84ebbc6379_15a45da1_128d96b7-c591-43c7-8393-71b1b078c790</Data>
<Data>
</Data>
<Data>0</Data>
<Data>b2318536-61c1-4958-85c0-a6803c4bbd3b</Data>
<Data>268435456</Data>
<Data>e03e080836cae1e184c5d40b5330eaef</Data>
<Data>0</Data>
</EventData>
</Event>
Any help would be appreciated!
Thanks
After trying multiple approaches and dealing with this for over a week, I have decided to restructure my Service by replacing 3 timers with one. The single timer checks the time of day and calls the appropriate process.
I put this question up with the hope that someone would have the knowledge to decipher the Event Log entries. Since I did not get any response, I needed to move on with a solution.
Thank you for those of you that have taken a look and please disregard my original question as I have moved on.

GitLab CI - How to verify that Unity3D Tests actually passed

Here is my gitlab-ci.yml:
variables:
GIT_STRATEGY: fetch
GIT_CLONE_PATH: $CI_BUILDS_DIR
GIT_DEPTH: 10
GIT_CLEAN_FLAGS: none
stages:
- test
- build
unit-test:
script: "C:\\'Program Files'\\Unity\\Hub\\Editor\\'2019.4.3f1'\\Editor\\Unity.exe \
-runTests \
-batchmode \
-projectPath . \
-logFile ./log.txt \
-testResults ./unit-tests.xml"
stage: test
tags:
- unity
unity-build:
stage: build
script: echo 'Building...'
tags:
- unity
Here is the output of the pipeline:
Running with gitlab-runner 13.1.1 (6fbc7474)
on Desktop ryBW4ftU
Preparing the "shell" executor
00:00
Using Shell executor...
Preparing environment
00:01
Running on DESKTOP-G62KPLQ...
Getting source from Git repository
00:06
Fetching changes with git depth set to 10...
Reinitialized existing Git repository in X:/ScarsOFHonor_CI/.git/
Checking out 8ca0d362 as master...
Encountered 2 file(s) that should have been pointers, but weren't:
ProjectSettings/EditorSettings.asset
ProjectSettings/XRSettings.asset
git-lfs/2.4.2 (GitHub; windows amd64; go 1.8.3; git 6f4b2e98)
Skipping Git submodules setup
Executing "step_script" stage of the job script
01:18
$ C:\'Program Files'\Unity\Hub\Editor\'2019.4.3f1'\Editor\Unity.exe -runTests -batchmode -projectPath . -logFile ./log.txt -testResults ./unit-tests.xml
. is not a valid directory name. Please make sure there are no unallowed characters in the name.
(Filename: C:\buildslave\unity\build\Runtime/Utilities/FileVFS.cpp Line: 218)
. is not a valid directory name. Please make sure there are no unallowed characters in the name.
(Filename: C:\buildslave\unity\build\Runtime/Utilities/FileVFS.cpp Line: 218)
Job succeeded
As you can see pipeline passed with success. However that should not be true. I intentionally created an pushed a failing test.
See the content of unit-tests.xml:
<?xml version="1.0" encoding="utf-8"?>
<test-run id="2" testcasecount="1" result="Failed(Child)" total="1" passed="0" failed="1" inconclusive="0" skipped="0" asserts="0" engine-version="3.5.0.0" clr-version="4.0.30319.42000" start-time="2020-07-17 11:40:32Z" end-time="2020-07-17 11:40:32Z" duration="0.105692">
<test-suite type="TestSuite" id="1007" name="ScarsOFHonor" fullname="ScarsOFHonor" runstate="Runnable" testcasecount="1" result="Failed" site="Child" start-time="2020-07-17 11:40:32Z" end-time="2020-07-17 11:40:32Z" duration="0.105692" total="1" passed="0" failed="1" inconclusive="0" skipped="0" asserts="0">
<properties />
<failure>
<message><![CDATA[One or more child tests had errors]]></message>
</failure>
<test-suite type="Assembly" id="1010" name="EditMode.dll" fullname="X:/ScarsOFHonor_CI/Library/ScriptAssemblies/EditMode.dll" runstate="Runnable" testcasecount="1" result="Failed" site="Child" start-time="2020-07-17 11:40:32Z" end-time="2020-07-17 11:40:32Z" duration="0.079181" total="1" passed="0" failed="1" inconclusive="0" skipped="0" asserts="0">
<properties>
<property name="_PID" value="27144" />
<property name="_APPDOMAIN" value="Unity Child Domain" />
<property name="platform" value="EditMode" />
</properties>
<failure>
<message><![CDATA[One or more child tests had errors]]></message>
</failure>
<test-suite type="TestSuite" id="1011" name="Tests" fullname="Tests" runstate="Runnable" testcasecount="1" result="Failed" site="Child" start-time="2020-07-17 11:40:32Z" end-time="2020-07-17 11:40:32Z" duration="0.076239" total="1" passed="0" failed="1" inconclusive="0" skipped="0" asserts="0">
<properties />
<failure>
<message><![CDATA[One or more child tests had errors]]></message>
</failure>
<test-suite type="TestFixture" id="1008" name="DummyTest" fullname="Tests.DummyTest" classname="Tests.DummyTest" runstate="Runnable" testcasecount="1" result="Failed" site="Child" start-time="2020-07-17 11:40:32Z" end-time="2020-07-17 11:40:32Z" duration="0.067615" total="1" passed="0" failed="1" inconclusive="0" skipped="0" asserts="0">
<properties />
<failure>
<message><![CDATA[One or more child tests had errors]]></message>
</failure>
<test-case id="1009" name="DummyTestSimplePasses" fullname="Tests.DummyTest.DummyTestSimplePasses" methodname="DummyTestSimplePasses" classname="Tests.DummyTest" runstate="Runnable" seed="785721540" result="Failed" start-time="2020-07-17 11:40:32Z" end-time="2020-07-17 11:40:32Z" duration="0.032807" asserts="0">
<properties />
<failure>
<message><![CDATA[ Expected: 1
But was: 2
]]></message>
<stack-trace><![CDATA[at Tests.DummyTest.DummyTestSimplePasses () [0x00001] in X:\ScarsOFHonor_CI\Assets\Tests\EditMode\DummyTest.cs:15
]]></stack-trace>
</failure>
</test-case>
</test-suite>
</test-suite>
</test-suite>
</test-suite>
</test-run>
As you can see there is a failing test. Why then my pipeline passes ?
Is there any way I can print my results in the pipeline itself and mark the pipeline as failed when actually I have failing test?
Hm a bit (actually extremely :D ) dirty but you could simply check if the result file contains the word <failure> using find like e.g.
find "<failure>" ./unit-tests.xml > nul && exit 1 || exit 0
> nul don't print to the console
so if the word <failure> was found it exits with failure (1) otherwise with success (0)
Not a yml expert but I think you could e.g. add it to
script: "C:\\'Program Files'\\Unity\\Hub\\Editor\\'2019.4.3f1'\\Editor\\Unity.exe -runTests -batchmode -projectPath . -logFile ./log.txt -testResults ./unit-tests.xml && find '<failure>' ./unit-tests.xml > nul && exit 1 || exit 0"

Modify the Outlook CustomUI XML by powershell

friends. I want to check every of my company users' outlook customUI configuration file. Delete 2 UI buttons if any. I am trying to do it by powershell. But failed to do so. Any advice for my script?
Below is the XML content of olkexpplorer.officeUI. I need to check & delete the items in blockquotes in case they are existed in the configuration file.
<mso:customUI xmlns:x1="Microsoft.Forefront.SpamReporterAddin.Connect" xmlns:mso="http://schemas.microsoft.com/office/2009/07/customui">
<mso:ribbon>
<mso:qat />
<mso:tabs>
<mso:tab idQ="mso:TabMail">
<mso:group id="mso_c1.45620CF" label="Phishing Report" imageMso="TrustCenter" autoScale="true"
<mso:control idQ="x1:ExplorerPhishReportMenuButton" imageMso="TrustCenter" visible="true"/>
</mso:group>
> <mso:group id="mso_c2.14817EBA" label="Junk" autoScale="true">
> <mso:control idQ="x1:ExplorerSpamReportMenuButton" visible="true" />
> <mso:control idQ="x1:ExplorerPhishReportMenuButton" imageMso="GreenBall" visible="true" />
> </mso:group>
</mso:tab>
</mso:tabs>
</mso:ribbon>
</mso:customUI>
Here is my script
$input = [xml](Get-Content -Path “$path_to_office\olkexplorer.officeUI”)
$deletenames="mso_c2.14817EBA"
($input.customUI.ChildNodes |Where-object { $deletenames -contains $_.Name}) | ForEach-
Object{[void]$_.ParentNode.RemoveChild($_)}
$input.save(“$path_to_office\new.officeUI”)
First of all, it is not clear how the ribbon XML looks like after running your code:
$input.save(“$path_to_office\new.officeUI”)
Anyway, you can do any modifications until the ribbon XML is loaded by the host application. At runtime, you may consider using callbacks where they are available and call the IRIbbonUI.Invalidate or IRibbonUI.InvalidateControl methods to get your custom UI invalidated and callbacks triggered. Here is what MSDN states:
For each of the callbacks the add-in implements, the responses are cached. For example, if an add-in writer implements the getImage callback procedure for a button, the function is called once, the image loads, and then if the image needs to be updated, the cached image is used instead of recalling the procedure. This process remains in-place until the add-in signals that the cached values are invalid by using the Invalidate method, at which time, the callback procedure is again called and the return response is cached. The add-in can then force an immediate update of the UI by calling the Refresh method.
The problem with your approach is that ChildNodes() only returns the immediate child nodes and not all child nodes (and using $input as a variable name is not considered a good practice anyway because its a reserved variable name).
So instead of ChildNodes() I would access the child node directly like so
$input.customUI.ribbon.tabs.tab.group | where-object { $DeleteNames -contains $_.id}
I would prefer the System.Xml.Linq classes like XDocument and XElement over the [xml] type alias because they make dealing with Xml inside a PowerShell script a little more convenient.
if this is the input xml:
$XmlCode = #'
<mso:customUI xmlns:mso="http://schemas.microsoft.com/office/2009/07/customui">
<mso:ribbon>
<mso:qat><mso:sharedControls>
<mso:control idQ="mso:FileNewDefault" visible="false"/>
<mso:control idQ="mso:FileOpen" visible="false"/>
<mso:control idQ="mso:FileSave" visible="true"/>
<mso:control idQ="mso:FileSendAsAttachment" visible="false"/>
<mso:control idQ="mso:FilePrintQuick" visible="false"/>
<mso:control idQ="mso:SpellingAndGrammar" visible="false"
insertBeforeQ="mso:PrintPreviewAndPrint"/>
<mso:control idQ="mso:Undo" visible="true"
insertBeforeQ="mso:PrintPreviewAndPrint"/>
<mso:control idQ="mso:RedoOrRepeat" visible="true"
insertBeforeQ="mso:PrintPreviewAndPrint"/>
<mso:control idQ="mso:TableDrawTable" visible="false"
insertBeforeQ="mso:PrintPreviewAndPrint"/>
<mso:control idQ="mso:FileOpenRecentFile" visible="false"
insertBeforeQ="mso:PrintPreviewAndPrint"/>
<mso:control idQ="mso:FontDialog" visible="true"
insertBeforeQ="mso:PrintPreviewAndPrint"/>
<mso:control idQ="mso:FontSizeDecreaseWord" visible="true"
insertBeforeQ="mso:PrintPreviewAndPrint"/>
<mso:control idQ="mso:FontSize" visible="true"
insertBeforeQ="mso:PrintPreviewAndPrint"/>
<mso:control idQ="mso:PageSetupDialog" visible="true"
insertBeforeQ="mso:PrintPreviewAndPrint"/>
<mso:control idQ="mso:PrintPreviewAndPrint" visible="true"/>
</mso:sharedControls>
</mso:qat>
</mso:ribbon>
</mso:customUI>
'#
the following Powershell commands would remove all mso:control nodes with visible="false":
using namespace System.Xml.Linq
Add-Type -Assembly System.Xml.Linq
$xmlCode = "<<as shown above>>"
$xRoot = [XDocument]::Parse($xmlCode)
$msoNs = [XNamespace]::get("http://schemas.microsoft.com/office/2009/07/customui")
$DeleteNodes = $xRoot.Descendants($msoNs + "control").where{$_.Attribute("visible").Value -eq "false"}
$DeleteNodes.ForEach{$_.Remove()}
$xRoot.ToString()
# Save the new xml
$XmlPath = [System.IO.Path]::GetTempFileName()
$xRoot.Save($XmlPath)
XDocument has a Load() method for loading a xml file directly so there is no need to use the Parse() method (I was using for the sake of this example).
The only small drawback comparing to [xml] is that you have to consider namespaces.

DMN 1.2: Referencing ItemDefinitions from another ItemDefinition results in an error

I load this DMN file (dmnFile):
<definitions name="MyDecision" id="def_12f8a48f-3978-0e29-4251-a66b6e6459bc"
xmlns:ns="http://sample.dmn" namespace="http://sample.dmn"
xmlns:feel="http://www.omg.org/spec/FEEL/20140401" exporter="ex" exporterVersion="12"
xmlns="http://www.omg.org/spec/DMN/20180521/MODEL/">
<itemDefinition name="MyItemDefinition" id="_850f24d9-57a3-131f-2194-ca15bb049a7a">
<itemComponent name="myNumber" id="_29d92e98-3c97-67a3-22f1-d342622424f7">
<typeRef>NumberDefinition</typeRef>
</itemComponent>
</itemDefinition>
<itemDefinition name="NumberDefinition" id="_e6972775-7973-b755-8714-9eff9d61e48e">
<typeRef>number</typeRef>
</itemDefinition>
<inputData name="MyInput" id="_d6395e05-d35c-d667-f227-398d93a97759">
<variable name="MyInput" id="_121ab3bc-b4e2-a6bb-51be-ef8fcc6623a6" typeRef="MyItemDefinition" />
</inputData>
<decision name="MyDecision" id="_12f8a48f-3978-0e29-4251-a66b6e6459bc">
<variable name="MyDecision" id="_098e9619-fa0c-3796-b3da-c4d018a79009" typeRef="boolean" />
<informationRequirement>
<requiredInput href="#_d6395e05-d35c-d667-f227-398d93a97759" />
</informationRequirement>
<context id="_6dcdac84-b03f-badd-a2d7-78c668ece883">
<contextEntry>
<variable name="containsMyNumber" id="_f6078cbe-54e6-d682-b3b7-8ffc638e4846" typeRef="boolean" />
<literalExpression id="_a022013e-4f0c-cfb3-1792-673a9e69be33">
<text>if list contains([0,1,2,3], MyInput.myNumber) then true else false</text>
</literalExpression>
</contextEntry>
<contextEntry>
<literalExpression id="_19c3853c-c63b-a8ac-0608-639ea685f321">
<text>containsMyNumber</text>
</literalExpression>
</contextEntry>
</context>
</decision>
</definitions>
like this:
KieServices ks = KieServices.Factory.get();
KieContainer kieContainer = KieHelper.getKieContainer(ks.newReleaseId("org.kie", "dmn-test-" + UUID.randomUUID(), "1.2"), ks.getResources().newFileSystemResource(dmnFile));
and I get an exception with the following error message:
[Message [id=1, kieBase=defaultKieBase, level=ERROR, path=C:/Users/AppData/Local/Temp/tmpBA10.tmp.dmn, line=4, column=-1
text=DMN: Unable to resolve type reference '{http://www.omg.org/spec/DMN/20180521/MODEL/}NumberDefinition' on node 'MyItemDefinition' (resource: C:/Users/AppData/Local/Temp/tmpBA10.tmp.dmn, DMN id: _29d92e98-3c97-67a3-22f1-d342622424f7, The listed type definition was not found) ]]
Type reference with prefix ("ns:NumberDefinition") results in the following error message:
[Message [id=1, kieBase=defaultKieBase, level=ERROR, path=C:/Users/AppData/Local/Temp/tmpBA10.tmp.dmn, line=4, column=-1
text=DMN: Unable to resolve type reference '{http://www.omg.org/spec/DMN/20180521/MODEL/}ns:NumberDefinition' on node 'MyItemDefinition' (resource: C:/Users/AppData/Local/Temp/tmpBA10.tmp.dmn, DMN id: _29d92e98-3c97-67a3-22f1-d342622424f7, The listed type definition was not found) ]]
What do I do wrong?
When using DMN 1.1 (xmlns="http://www.omg.org/spec/DMN/20151101/dmn.xsd") and type references as QNames (with prefixes) I get the expected result.
Since DMNv1.2, the idiomatic way to reference is ns.<itemDef>.
In your original DMN xml file this happens on line 7 and 14.
In summary the file in the idiomatic DMNv1.2 form should be:
<definitions name="MyDecision" id="def_12f8a48f-3978-0e29-4251-a66b6e6459bc"
xmlns:ns="http://sample.dmn" namespace="http://sample.dmn"
xmlns:feel="http://www.omg.org/spec/FEEL/20140401" exporter="ex" exporterVersion="12"
xmlns="http://www.omg.org/spec/DMN/20180521/MODEL/">
<itemDefinition name="MyItemDefinition" id="_850f24d9-57a3-131f-2194-ca15bb049a7a">
<itemComponent name="myNumber" id="_29d92e98-3c97-67a3-22f1-d342622424f7">
<typeRef>ns.NumberDefinition</typeRef>
</itemComponent>
</itemDefinition>
<itemDefinition name="NumberDefinition" id="_e6972775-7973-b755-8714-9eff9d61e48e">
<typeRef>number</typeRef>
</itemDefinition>
<inputData name="MyInput" id="_d6395e05-d35c-d667-f227-398d93a97759">
<variable name="MyInput" id="_121ab3bc-b4e2-a6bb-51be-ef8fcc6623a6" typeRef="ns.MyItemDefinition" />
</inputData>
<decision name="MyDecision" id="_12f8a48f-3978-0e29-4251-a66b6e6459bc">
<variable name="MyDecision" id="_098e9619-fa0c-3796-b3da-c4d018a79009" typeRef="boolean" />
<informationRequirement>
<requiredInput href="#_d6395e05-d35c-d667-f227-398d93a97759" />
</informationRequirement>
<context id="_6dcdac84-b03f-badd-a2d7-78c668ece883">
<contextEntry>
<variable name="containsMyNumber" id="_f6078cbe-54e6-d682-b3b7-8ffc638e4846" typeRef="boolean" />
<literalExpression id="_a022013e-4f0c-cfb3-1792-673a9e69be33">
<text>if list contains([0,1,2,3], MyInput.myNumber) then true else false</text>
</literalExpression>
</contextEntry>
<contextEntry>
<literalExpression id="_19c3853c-c63b-a8ac-0608-639ea685f321">
<text>containsMyNumber</text>
</literalExpression>
</contextEntry>
</context>
</decision>
</definitions>
That said, with your report we uncovered a bug when the DMN xml file is using the DMN namespace as the default namespace, which we are addressing with
DROOLS-4797.
Thank you for the report !
There is a way to avoid being forced to use ns.<itemDef> and simply use <itemDef>, and that is by setting the default namespace in the DMN xml to be the model's namespace, and just prefixing the DMN xml element with the namespace prefix targeting the DMN namespace.
In other words, the file can make use of <itemDef> reference without having to ns. prefix them:
<semantic:definitions name="MyDecision" id="def_12f8a48f-3978-0e29-4251-a66b6e6459bc"
xmlns="http://sample.dmn" namespace="http://sample.dmn"
xmlns:feel="http://www.omg.org/spec/FEEL/20140401" exporter="ex" exporterVersion="12"
xmlns:semantic="http://www.omg.org/spec/DMN/20180521/MODEL/">
<semantic:itemDefinition name="MyItemDefinition" id="_850f24d9-57a3-131f-2194-ca15bb049a7a">
<semantic:itemComponent name="myNumber" id="_29d92e98-3c97-67a3-22f1-d342622424f7">
<semantic:typeRef>NumberDefinition</semantic:typeRef>
</semantic:itemComponent>
</semantic:itemDefinition>
<semantic:itemDefinition name="NumberDefinition" id="_e6972775-7973-b755-8714-9eff9d61e48e">
<semantic:typeRef>number</semantic:typeRef>
</semantic:itemDefinition>
<semantic:inputData name="MyInput" id="_d6395e05-d35c-d667-f227-398d93a97759">
<semantic:variable name="MyInput" id="_121ab3bc-b4e2-a6bb-51be-ef8fcc6623a6" typeRef="MyItemDefinition" />
</semantic:inputData>
<semantic:decision name="MyDecision" id="_12f8a48f-3978-0e29-4251-a66b6e6459bc">
<semantic:variable name="MyDecision" id="_098e9619-fa0c-3796-b3da-c4d018a79009" typeRef="boolean" />
<semantic:informationRequirement>
<semantic:requiredInput href="#_d6395e05-d35c-d667-f227-398d93a97759" />
</semantic:informationRequirement>
<semantic:context id="_6dcdac84-b03f-badd-a2d7-78c668ece883">
<semantic:contextEntry>
<semantic:variable name="containsMyNumber" id="_f6078cbe-54e6-d682-b3b7-8ffc638e4846" typeRef="boolean" />
<semantic:literalExpression id="_a022013e-4f0c-cfb3-1792-673a9e69be33">
<semantic:text>if list contains([0,1,2,3], MyInput.myNumber) then true else false</semantic:text>
</semantic:literalExpression>
</semantic:contextEntry>
<semantic:contextEntry>
<semantic:literalExpression id="_19c3853c-c63b-a8ac-0608-639ea685f321">
<semantic:text>containsMyNumber</semantic:text>
</semantic:literalExpression>
</semantic:contextEntry>
</semantic:context>
</semantic:decision>
</semantic:definitions>
In this other variant, the default namespace in the xml is the DMN model's namespace, so any itemDef reference does not need any prefix.
Because the default namespace in the xml is the DMN model's namespace, the xml element need to be prefixed with the namespace prefix targeting now the DMN namespace.
Hope this clarifies and provide an insightful explanation!

Adding suffix to a list with foreach

I am including a .properties file, which has a list of properties:
configuration.files = file1, file2
configuration.files.file1.source = config/filename1
configuration.files.file2.source = config/filename2
Now I need the paths for each file changed to something like this:
vendor/project/config/filename1
vendor/project/config/filename2
To achieve that, I tried to foreach this list and prepend that suffix and overriding the existing property:
<foreach list="${configuration.files}" target="_prepend-vendor-path" param="file" >
<property name="configuration.files.${file}.source" value="/vendor/project/${configuration.files.${file}.source}" override="true"/>
</foreach>
<target name="_prepend-vendor-path" >
<echo msg="${configuration.files.${file}.source}" />
</target>
This doesn't work and I can't figure out why. Is it even possible to use target names like ${suffix}.name ? If not, how could I achive my goal here?
I just did some workaround for this, writing out the properties and their values to a file and readin them after the loop has finished with override = true:
<target name="_prepend-vendor-path" >
<exec dir="${project.basedir}" command="echo configuration.files.${file}.source = /vendor/project/${configuration.files.${file}.source} >> ${project.temp.config}" passthru="true" checkreturn="true" />
</target>
and after the foreach simply:
<property file="${project.temp.config}" override="true"/>
For some reason the properties won't be overridden in the foreach and I just can't figgure out why, but this little trick made it for me.
You can suffix your property values from your file with the property task using a filterchain and a regular expression replacement:
<?xml version="1.0"?>
<project name="Phing Build Tests" default="append-custom-path" basedir=".">
<target name="append-custom-path">
<property file="prop.properties">
<filterchain>
<replaceregexp>
<regexp pattern="^(.*)" replace="vendor/project/$1"/>
</replaceregexp>
</filterchain>
</property>
<echo>${configuration.files.file1.source}</echo>
<echo>${configuration.files.file2.source}</echo>
</target>
</project>