### 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
public void writeTo(StreamOutput out) throws IOException {
            out.writeString(clusterUUID);
            out.writeBoolean(clusterUUIDCommitted);
            out.writeLong(version);
            coordinationMetadata.writeTo(out);
            Settings.writeSettingsToStream(transientSettings, out);
            Settings.writeSettingsToStream(persistentSettings, out);
            if (out.getVersion().onOrAfter(Version.V_7_3_0)) {
                hashesOfConsistentSettings.writeTo(out);
            }
            indices.writeTo(out);
            templates.writeTo(out);
            customs.writeTo(out);
            if (out.getVersion().onOrAfter(Version.V_8_4_0)) {
                immutableStateMetadata.writeTo(out);
            }
        }
        @Override
        public Metadata apply(Metadata part) {
            
            
            final var updatedIndices = indices.apply(part.indices);
            Builder builder = new Builder(part.mappingsByHash, updatedIndices.size());
            builder.clusterUUID(clusterUUID);
            builder.clusterUUIDCommitted(clusterUUIDCommitted);
            builder.version(version);
            builder.coordinationMetadata(coordinationMetadata);
            builder.transientSettings(transientSettings);
            builder.persistentSettings(persistentSettings);
            builder.hashesOfConsistentSettings(hashesOfConsistentSettings.apply(part.hashesOfConsistentSettings));