### 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/DiffableUtils.java
for (Map.Entry<K, Diff<T>> diff : diffs) {
                builder.put(diff.getKey(), diff.getValue().apply(builder.get(diff.getKey())));
            }
            for (Map.Entry<K, T> upsert : upserts) {
                builder.put(upsert.getKey(), upsert.getValue());
            }
            return builder;
        }
    }
    /**
     * Represents differences between two ImmutableOpenMap of (possibly diffable) objects
     *
     * @param <T> the object type
     */
    public static class ImmutableOpenMapDiff<K, T> extends MapDiff<K, T, ImmutableOpenMap<K, T>> {
        private ImmutableOpenMapDiff(
            KeySerializer<K> keySerializer,
            ValueSerializer<K, T> valueSerializer,
            List<K> deletes,
            List<Map.Entry<K, Diff<T>>> diffs,
            List<Map.Entry<K, T>> upserts
        ) {
            super(keySerializer, valueSerializer, deletes, diffs, upserts);
        }
        private ImmutableOpenMapDiff(StreamInput in, KeySerializer<K> keySerializer, ValueSerializer<K, T> valueSerializer)
            throws IOException {
            super(in, keySerializer, valueSerializer);
        }
        private static <K, T> ImmutableOpenMapDiff<K, T> create(
            ImmutableOpenMap<K, T> before,