### Description

When using the DiffableUtils.diff with a vanilla OpenJDK Map, instead of the legacy ImmutableOpenMap interface, we return a mutable map (generic HashMap), which isn't the expected behaviour of the API:

https://github.com/elastic/elasticsearch/blob/45c56b22f946733712ad6d92600411c0885594c5/server/src/main/java/org/elasticsearch/cluster/DiffableUtils.java#L85

We should wrap the map returned by the diff API in an unmodifiable version.
server/src/main/java/org/elasticsearch/cluster/metadata/Metadata.java
}
        }
        /**
         * Collect all duplicate names across indices and aliases that were detected into a list of helpful duplicate failure messages.
         */
        private static void collectAliasDuplicates(
            ImmutableOpenMap<String, IndexMetadata> indicesMap,
            Set<String> aliasDuplicatesWithIndices,
            ArrayList<String> duplicates
        ) {
            for (IndexMetadata cursor : indicesMap.values()) {
                for (String alias : aliasDuplicatesWithIndices) {
                    if (cursor.getAliases().containsKey(alias)) {
                        duplicates.add(alias + " (alias of " + cursor.getIndex() + ") conflicts with index");
                    }
                }
            }
        }
        static SortedMap<String, IndexAbstraction> buildIndicesLookup(
            DataStreamMetadata dataStreamMetadata,
            ImmutableOpenMap<String, IndexMetadata> indices
        ) {
            SortedMap<String, IndexAbstraction> indicesLookup = new TreeMap<>();
            Map<String, IndexAbstraction.DataStream> indexToDataStreamLookup = new HashMap<>();
            // If there are no indices, then skip data streams. This happens only when metadata is read from disk
            if (indices.size() > 0) {
                Map<String, List<String>> dataStreamToAliasLookup = new HashMap<>();
                for (DataStreamAlias alias : dataStreamMetadata.getDataStreamAliases().values()) {
                    List<Index> allIndicesOfAllDataStreams = alias.getDataStreams().stream().map(name -> {
                        List<String> aliases = dataStreamToAliasLookup.computeIfAbsent(name, k -> new LinkedList<>());