Skip to content

Maintain consistent element order in exports#45

Open
rogin wants to merge 2 commits intoOpenIntegrationEngine:mainfrom
rogin:maint-element-order-exports
Open

Maintain consistent element order in exports#45
rogin wants to merge 2 commits intoOpenIntegrationEngine:mainfrom
rogin:maint-element-order-exports

Conversation

@rogin
Copy link
Contributor

@rogin rogin commented Apr 19, 2025

Fixes an old and common complaint. Previous test results here. I've only verified that it built successfully using Java 8.

Testing points:

  • elements export in a consistent order
  • diffs (as with git, or diff) are improved with consistent order
  • imports with the new order import cleanly
  • legacy imports without ordered elements still import cleanly

jonbartels
jonbartels previously approved these changes Apr 20, 2025
Signed-off-by: Richard Ogin <rogin@users.noreply.github.com>
gibson9583
gibson9583 previously approved these changes Jun 16, 2025
kpalang
kpalang previously approved these changes Jun 16, 2025
package com.mirth.connect.donkey.model.message;

import java.util.HashMap;
import java.util.TreeMap;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since a TreeMap is sorted and a HashMap is not, I'm guessing there could be considerable changes compared to a prior export the first time an export is done with the new code?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, then subsequent exports will benefit.

Copy link
Member

@tonygermano tonygermano Jun 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a purpose for having MapContent as part of this PR? I think it only shows up in a message export, and not part of the server configuration?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll revert it and verify.

@rogin rogin dismissed stale reviews from kpalang, gibson9583, and jonbartels via 7162f41 June 18, 2025 20:13
@tonygermano
Copy link
Member

tonygermano commented Jun 20, 2025

Can you describe your testing? I'm sure this does work when creating and exporting new code templates and libraries. Do we know for certain that when xstream creates the objects from xml that it isn't recreating them as HashSets?

@jonbartels jonbartels added enhancement New feature or request help wanted Extra attention is needed labels Jun 23, 2025
@ssrowe ssrowe requested a review from Copilot March 11, 2026 18:36
@ssrowe
Copy link

ssrowe commented Mar 11, 2026

@rogin would you be able to complete the DSO and rebase this so we can include it in our next release?

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses non-deterministic ordering in exported artifacts by switching key collection types to sorted implementations so serialized output is stable across runs, improving diffability and reducing noisy changes during import/export.

Changes:

  • Use TreeSet for code template library channel ID sets to stabilize export ordering.
  • Use TreeSet for CodeTemplateContextSet to stabilize context ordering.
  • Use TreeMap/TreeMap-backed defaults in map serialization/content to stabilize map entry ordering in serialized output.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
server/src/com/mirth/connect/model/codetemplates/CodeTemplateLibrary.java Switch enabled/disabled channel ID sets to sorted sets for stable export order.
server/src/com/mirth/connect/model/codetemplates/CodeTemplateContextSet.java Use a sorted set delegate to ensure consistent iteration/serialization order of contexts.
donkey/src/main/java/com/mirth/connect/donkey/util/MapUtil.java Use TreeMap in recovery/deserialization paths to produce deterministic serialized map output.
donkey/src/main/java/com/mirth/connect/donkey/model/message/MapContent.java Default map-backed content to TreeMap to encourage stable map iteration/serialization.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 47 to 52
public CodeTemplateLibrary() {
id = UUID.randomUUID().toString();
enabledChannelIds = new HashSet<String>();
disabledChannelIds = new HashSet<String>();
enabledChannelIds = new TreeSet<String>();
disabledChannelIds = new TreeSet<String>();
codeTemplates = new ArrayList<CodeTemplate>();
}
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The constructor now initializes enabled/disabledChannelIds as TreeSet for deterministic ordering, but the setters still accept and assign arbitrary Set implementations. There are call sites that pass HashSet (e.g., client CodeTemplatePanel, server ChannelServletTest), which will reintroduce non-deterministic export order and undermine the purpose of this change. Consider defensively copying in the setters (e.g., wrap in a new TreeSet) so CodeTemplateLibrary always holds a sorted set regardless of how it’s populated (including after deserialization or UI updates).

Copilot uses AI. Check for mistakes.
Comment on lines 62 to 66
return serializer.serialize(map);
} catch (Exception e) {
Map<String, Object> newMap = new HashMap<String, Object>();
Map<String, Object> newMap = new TreeMap<String, Object>();

for (Entry<String, Object> entry : map.entrySet()) {
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes aim to make map serialization deterministic by using TreeMap, but existing MapUtil tests don’t assert ordering. To prevent regressions (and to validate the PR’s main goal), add a unit test that serializes a map with out-of-order keys and verifies the resulting XML entry order is consistent/sorted for the TreeMap-backed paths (both the fallback re-serialization path and deserializeMapWithInvalidValues).

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request help wanted Extra attention is needed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants