Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
1e13262
Draft diagram for new transaction DEV-48
JavierEspina Jul 22, 2025
904c54a
Merge branch 'master' into 457-early-pre-published-alert-pkp-integrat…
JavierEspina Jul 22, 2025
f4cf933
Changed actors names in DEV-48 transaction diagram
JavierEspina Jul 22, 2025
b91ca28
Added Provider selfChecks to DEV-48 transaction diagram
JavierEspina Jul 23, 2025
d73f44a
Started carving out transactions DEV-48 and DEV-49
JavierEspina Jul 25, 2025
5caae1f
Corrected actors in transactions DEV-48 and DEV-49
JavierEspina Jul 25, 2025
bc09b01
First big badge of changes for DAS management
JavierEspina Jul 28, 2025
8964f9d
Updated SDPi-A actor diagram svg
JavierEspina Jul 29, 2025
0c45e12
Attempt to fix PUML diagram rendering issues
JavierEspina Jul 29, 2025
4d01f13
2nd attempt to fix PUML diagram rendering issues
JavierEspina Jul 30, 2025
e7f2970
added referenced standards to DEV-48 and -49
JavierEspina Jul 30, 2025
7a60af2
First inroads into DEV-48 message / operation descriptions
JavierEspina Jul 31, 2025
7ea3ec7
Merge branch 'master' into 457-early-pre-published-alert-pkp-integrat…
JavierEspina Aug 1, 2025
36d192f
Merge branch 'master' into 457-early-pre-published-alert-pkp-integrat…
JavierEspina Sep 1, 2025
5f00859
Harmonized PUML include paths
JavierEspina Sep 1, 2025
3ef96ed
Described set_friendly_consumer_name_response
JavierEspina Sep 13, 2025
7dd9c9e
Described operation_monitored_by_das
JavierEspina Sep 13, 2025
0e4e484
Merge branch 'master' into 457-early-pre-published-alert-pkp-integrat…
JavierEspina Oct 2, 2025
7c7c64e
Corrected step 9 of DEV-48 diagram to be EpisodicAlertReport
JavierEspina Nov 10, 2025
5aaec2f
Corrected some labels in section 2:3.48.4
JavierEspina Nov 10, 2025
736fbb4
Extended MonitoredByDAS description to also cover DAS maintenance
JavierEspina Nov 10, 2025
67a60f9
Merge branch 'master' into 457-early-pre-published-alert-pkp-integrat…
JavierEspina Feb 18, 2026
ad491d4
Merge branch 'master' into 457-early-pre-published-alert-pkp-integrat…
JavierEspina Feb 18, 2026
df86397
recreated some lost changes in the last master merge
JavierEspina Feb 18, 2026
5ef8df1
Fixed merge issues.
PaulMartinsen Feb 19, 2026
393ce3e
Added markup for transactions 48 & 49.
PaulMartinsen Feb 19, 2026
71547bc
attempt to add simple content and markup for DAS option
JavierEspina Feb 19, 2026
d646a66
2nd attempt to add simple content and markup for DAS option
JavierEspina Feb 19, 2026
01e046c
removed A-PKP deprecated operation SetFriendlyConsumerName + other up…
JavierEspina Feb 19, 2026
06f3365
fix build error + re-enable PUML file include
JavierEspina Feb 19, 2026
deadd73
first description of operation ConfirmAlertsTechnicalDelivery
JavierEspina Feb 19, 2026
3ad0a67
fixed roles in DEv-49 + reftext label for DAS option
JavierEspina Feb 20, 2026
8a65e22
label fixes in 2:3.48
JavierEspina Feb 20, 2026
ef1e380
completed DEV-48 message descriptions
JavierEspina Feb 20, 2026
3d901bb
DEV-48 updates to clarify message semantics and some A-PKP mechanisms
JavierEspina Feb 20, 2026
40bf5e2
Merge branch 'master' into 457-early-pre-published-alert-pkp-integrat…
JavierEspina Feb 27, 2026
267927b
First half of DEV-49 description
JavierEspina Feb 27, 2026
a1f668d
Implemented support for multiple actor contributions in transactions.
PaulMartinsen Feb 21, 2026
4489ec6
Merge remote-tracking branch 'origin/457-early-pre-published-alert-pk…
PaulMartinsen Feb 28, 2026
2ba8be1
reverted some changes to DEV-48 (roles that apply to actors)
JavierEspina Mar 3, 2026
1dff31d
Merge branch 'master' into 457-early-pre-published-alert-pkp-integrat…
JavierEspina Mar 4, 2026
474818c
Continued DEV-49 messaging description
JavierEspina Mar 4, 2026
fbf4ebb
clarified the two situations in DEV-49
JavierEspina Mar 4, 2026
8c17a63
completed DEV-49 description
JavierEspina Mar 6, 2026
28d878b
Added changelog entry
JavierEspina Mar 6, 2026
633c82b
Merge branch 'master' into 457-early-pre-published-alert-pkp-integrat…
JavierEspina Mar 31, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1129,6 +1129,11 @@ class SdpiInformationCollector(
}
}

/*
Matches actors with contributions for transactions referenced from profiles using
the syntax in the form:
sdpi_include_transaction::DEV-23[initiator="required", receiver="optional"]
*/
private fun linkActorsToTransactionReferences() {
for (profile in profiles.values) {
linkActorsToTransactionReferences(profile.transactionReferences)
Expand All @@ -1147,10 +1152,15 @@ class SdpiInformationCollector(
for (obl in ref.obligations) {
if (obl.actorId == null) {
val contrib = obl.contribution
val role = transaction.actorRoles?.firstOrNull { it.contribution == contrib }
if (role != null) {
val strActorId = role.actorId
obl.actorId = strActorId
if (transaction.actorRoles != null) {
val matchingRoles = transaction.actorRoles.filter{it.contributions.contains(contrib)}
check(matchingRoles.size <= 1) {
logger.error("More than one actor contributes $contrib. Specify actor in $BLOCK_MACRO_NAME_INCLUDE_TRANSACTION")
}
if (matchingRoles.size == 1) {
val strActorId = matchingRoles[0].actorId
obl.actorId = strActorId
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,26 +55,32 @@ class TransactionActorsProcessor : BlockProcessor(BLOCK_NAME_TRANSACTION_ACTORS)
val roles = mutableListOf<SdpiActorRole>()

var strActor: String? = null
var contribution: Contribution? = null
var contributions = mutableListOf<Contribution>()
val description = mutableListOf<String>()

for (strLine in blockLines) {
if (strLine.startsWith('[')) {
if (strActor != null && contribution != null && description.isNotEmpty()) {
roles.add(SdpiActorRole(strActor, contribution, description.toList()))

// remove trailing blank lines.
while(description.isNotEmpty() && description.last().isEmpty()) {
description.removeLast()
}

if (strActor != null && contributions.isNotEmpty() && description.isNotEmpty()) {
roles.add(SdpiActorRole(strActor, contributions, description.toList()))
}
description.clear()

val result = parseContributorAttributes(strLine)
strActor = result.first
contribution = result.second
contributions = result.second.toMutableList()
} else {
description.add(strLine)
}
}

if (strActor != null && contribution != null && description.isNotEmpty()) {
roles.add(SdpiActorRole(strActor, contribution, description.toList()))
if (strActor != null && contributions.isNotEmpty() && description.isNotEmpty()) {
roles.add(SdpiActorRole(strActor, contributions, description.toList()))
}

return roles
Expand Down Expand Up @@ -104,12 +110,12 @@ class TransactionActorsProcessor : BlockProcessor(BLOCK_NAME_TRANSACTION_ACTORS)

for (actorRole in roles) {
val strActorId = "RefActor:${actorRole.actorId}[]"
val contribution = actorRole.contribution
val contributions = actorRole.contributions
val strDescription = actorRole.description.joinToString("\r\n")

val row = createTableRow(roleTable)
row.cells.add(createTableCell(colActor, strActorId))
row.cells.add(createTableCell(colContribution, contribution.keyword))
row.cells.add(createTableCell(colContribution, contributions.joinToString { it.keyword }))

row.cells.add(createTableCell(colDescription, strDescription))

Expand All @@ -119,31 +125,37 @@ class TransactionActorsProcessor : BlockProcessor(BLOCK_NAME_TRANSACTION_ACTORS)
return roleTable
}

private fun parseContributorAttributes(strLine: String): Pair<String, Contribution> {
private fun parseContributorAttributes(strLine: String): Pair<String, List<Contribution>> {
val attributes = parseAttributes(strLine)

val strActorId = attributes[Roles.Transaction.ACTOR_ID.key]
checkNotNull(strActorId) {
val actorId = attributes.firstOrNull{ it.first == Roles.Transaction.ACTOR_ID.key}
checkNotNull(actorId) {
logger.error("Actor in transaction is missing an actor id")
}
val strContribution = attributes[Roles.Transaction.CONTRIBUTION.key]
checkNotNull(strContribution) {
logger.error("Actor $strActorId in transaction is missing a contribution")
val strActorId = actorId.second
val contributions = mutableListOf<Contribution>()
for(contribution in attributes.filter{it.first == Roles.Transaction.CONTRIBUTION.key}) {
val strContribution = contribution.second
val cont = parseContribution(strContribution)
checkNotNull(cont) {
logger.error("Actor $strActorId's contribution '$strContribution' is not recognized")
}
contributions.add(cont)
}
val contribution = parseContribution(strContribution)
checkNotNull(contribution) {
logger.error("Actor $strActorId's contribution '$strContribution' is not recognized")

check(contributions.isNotEmpty()) {
logger.error("Actor $strActorId in transaction is missing a contribution")
}

return Pair(strActorId, contribution)
return Pair(strActorId, contributions)
}

private fun parseAttributes(strValue: String): Map<String, String> {
val attributes = mutableMapOf<String, String>()
private fun parseAttributes(strValue: String): List<Pair<String, String>> {
val attributes = mutableListOf<Pair<String, String>>()

for (match in RE_ATTRIBUTES.findAll(strValue)) {
val (key, value) = match.destructured
attributes[key] = value
attributes.add(Pair<String,String>(key, value))
}

return attributes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ data class SdpiActor(
@Serializable
data class SdpiActorRole(
val actorId: String,
val contribution: Contribution,
val contributions: List<Contribution>,
val description: List<String>,
) {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,28 +19,14 @@ data class SdpiTransaction(
return "link:#$strAnchor[$id]"
}

fun getContributionFor(contribution: Contribution): Contribution? {
if (actorRoles == null) {
return null
}

for(actor in actorRoles) {
if (actor.contribution == contribution) {
return actor.contribution
}
}

return null
}

fun getContributionForActor(strActorId: String): Contribution? {
fun getContributionForActor(strActorId: String): List<Contribution>? {
if (actorRoles == null) {
return null
}

for(actor in actorRoles) {
if (actor.actorId == strActorId) {
return actor.contribution
return actor.contributions
}
}

Expand Down
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ Each section shall contain a list of action items of the following format: `<bri

### Added

- Clarifying note to R7000 ([#501](https://github.com/IHE/DEV.SDPi/issues/501)).
- Clarifying statements to DEV-23, DEV-24, DEV-46, and DEV-47 w.r.t to ad-hoc and managed mode discovery([#409](https://github.com/IHE/DEV.SDPi/issues/409)).
- Clarifying note to R7000 ([#501](https://github.com/IHE/DEV.SDPi/issues/501))
- Clarifying statements to DEV-23, DEV-24, DEV-46, and DEV-47 w.r.t to ad-hoc and managed mode discovery([#409](https://github.com/IHE/DEV.SDPi/issues/409))
- OID Framework to TF-3Z ([#474](https://github.com/IHE/DEV.SDPi/issues/474))
- Distributed Alarm System option and related transactions DEV-48 and DEV-49 (a.k.a. early "pre-published" integration of the SDC A-PKP standard) ([#457](https://github.com/IHE/DEV.SDPi/issues/457))
- Make restriction of xsd:durations to hours, minutes, seconds, and fractional seconds mandatory for all xsd:duration values ([#517](https://github.com/IHE/DEV.SDPi/issues/517))

### Changes
Expand Down
23 changes: 22 additions & 1 deletion articles/sdpi-article-ihe-tf-asciidoc-cookbook.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,9 @@ or overriding obligations that apply when the actor option is selected for a par

A profile, profile option or actor option references a <<semantic-transactions,transaction>> using the `sdpi_include_transaction` [include processor](https://docs.asciidoctor.org/asciidoctorj/latest/extensions/include-processor/) and declares the obligations of contributors.

There are two forms for `sdpi_include_transaction`. The first form defines obligations for the actor roles defined in the transaction. That is, only the contribution (`initiator`, `receiver`, `responder`) and obligation (`required`, `optional`) are required. It is not necessary to repeat the actor. For example:
There are two forms for `sdpi_include_transaction`. The first form defines obligations for the actor roles defined in the transaction. That is, only the contribution (`initiator`, `receiver`, `responder`) and obligation (`required`, `optional`) are required. It is not necessary to repeat the actor provided the transaction actor obligation is not ambiguous. Transaction actor's obligations are ambiguous when more than one actor has the same obligation (e.g., two actors both initiate messages in the transaction).

For example:

[source, asciidoc]
----
Expand Down Expand Up @@ -629,6 +631,25 @@ Listens for vol2_clause_dev_23_message_hello messages to identify any <<vol1_spe

Attaching the `transaction` role to a section marks it as a [transaction](https://profiles.ihe.net/DEV/SDPi/index.html#vol2). A (document-unique) identifier must be defined in the `DEV-23` attribute. The `reftext` attribute is used for the transaction label in tables, etc.

Actors may make multiple contributions to a transaction. For example:

----
[sdpi_transaction_actors]
--

[actor-id="somds_medical_alert_consumer",contribution=Initiator,contribution=Receiver]
Requests a <<vol1_spec_sdpi_a_actor_somds_medical_alert_provider>> to end a Distributed Alarm System.
Listens for notifications from a <<vol1_spec_sdpi_a_actor_somds_medical_alert_provider>> that end
a Distributed Alarm System.

[actor-id="somds_medical_alert_provider",contribution=Responder,contribution=Initiator]
Listens for requests from a <<vol1_spec_sdpi_a_actor_somds_medical_alert_consumer>> to end a
Distributed Alarm System and grants such requests. Alternatively ends a Distributed Alarm System
on its own initiative and notifies the <<vol1_spec_sdpi_a_actor_somds_medical_alert_consumer>>.

--
----

The transactions object identifier (oid) may <<defining-oids,be set>> using the `oid-arcs` attribute. If not present, object identifiers will
be set automatically from the transaction id. When assigned automatically, two oids will be applied to each transaction:

Expand Down
Loading
Loading