All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hazelcast.internal.dynamicconfig.DynamicConfigYamlGenerator Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2008-2024, Hazelcast, Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.hazelcast.internal.dynamicconfig;

import com.hazelcast.config.AdvancedNetworkConfig;
import com.hazelcast.config.AliasedDiscoveryConfig;
import com.hazelcast.config.AttributeConfig;
import com.hazelcast.config.BTreeIndexConfig;
import com.hazelcast.config.CacheSimpleConfig;
import com.hazelcast.config.CacheSimpleEntryListenerConfig;
import com.hazelcast.config.CardinalityEstimatorConfig;
import com.hazelcast.config.ClassFilter;
import com.hazelcast.config.CollectionConfig;
import com.hazelcast.config.Config;
import com.hazelcast.config.ConfigAccessor;
import com.hazelcast.config.ConfigXmlGenerator;
import com.hazelcast.config.DataConnectionConfig;
import com.hazelcast.config.DataPersistenceConfig;
import com.hazelcast.config.DiscoveryConfig;
import com.hazelcast.config.DiscoveryStrategyConfig;
import com.hazelcast.config.DiskTierConfig;
import com.hazelcast.config.DurableExecutorConfig;
import com.hazelcast.config.EndpointConfig;
import com.hazelcast.config.EventJournalConfig;
import com.hazelcast.config.EvictionConfig;
import com.hazelcast.config.ExecutorConfig;
import com.hazelcast.config.FlakeIdGeneratorConfig;
import com.hazelcast.config.IcmpFailureDetectorConfig;
import com.hazelcast.config.IndexConfig;
import com.hazelcast.config.IndexType;
import com.hazelcast.config.InterfacesConfig;
import com.hazelcast.config.JavaSerializationFilterConfig;
import com.hazelcast.config.JoinConfig;
import com.hazelcast.config.ListConfig;
import com.hazelcast.config.ListenerConfig;
import com.hazelcast.config.MapConfig;
import com.hazelcast.config.MapStoreConfig;
import com.hazelcast.config.MemberAddressProviderConfig;
import com.hazelcast.config.MemcacheProtocolConfig;
import com.hazelcast.config.MemoryTierConfig;
import com.hazelcast.config.MergePolicyConfig;
import com.hazelcast.config.MerkleTreeConfig;
import com.hazelcast.config.MetricsConfig;
import com.hazelcast.config.MultiMapConfig;
import com.hazelcast.config.MulticastConfig;
import com.hazelcast.config.NearCacheConfig;
import com.hazelcast.config.NetworkConfig;
import com.hazelcast.config.PNCounterConfig;
import com.hazelcast.config.PartitioningAttributeConfig;
import com.hazelcast.config.PartitioningStrategyConfig;
import com.hazelcast.config.PredicateConfig;
import com.hazelcast.config.QueryCacheConfig;
import com.hazelcast.config.QueueConfig;
import com.hazelcast.config.QueueStoreConfig;
import com.hazelcast.config.ReliableTopicConfig;
import com.hazelcast.config.ReplicatedMapConfig;
import com.hazelcast.config.RestApiConfig;
import com.hazelcast.config.RestEndpointGroup;
import com.hazelcast.config.RestServerEndpointConfig;
import com.hazelcast.config.RingbufferConfig;
import com.hazelcast.config.RingbufferStoreConfig;
import com.hazelcast.config.SSLConfig;
import com.hazelcast.config.ScheduledExecutorConfig;
import com.hazelcast.config.ServerSocketEndpointConfig;
import com.hazelcast.config.SetConfig;
import com.hazelcast.config.SocketInterceptorConfig;
import com.hazelcast.config.SplitBrainProtectionConfig;
import com.hazelcast.config.SplitBrainProtectionListenerConfig;
import com.hazelcast.config.SymmetricEncryptionConfig;
import com.hazelcast.config.TcpIpConfig;
import com.hazelcast.config.TieredStoreConfig;
import com.hazelcast.config.TopicConfig;
import com.hazelcast.config.UserCodeNamespacesConfig;
import com.hazelcast.config.WanBatchPublisherConfig;
import com.hazelcast.config.WanConsumerConfig;
import com.hazelcast.config.WanCustomPublisherConfig;
import com.hazelcast.config.WanReplicationConfig;
import com.hazelcast.config.WanReplicationRef;
import com.hazelcast.config.vector.VectorCollectionConfig;
import com.hazelcast.config.vector.VectorIndexConfig;
import com.hazelcast.instance.ProtocolType;
import com.hazelcast.internal.config.AliasedDiscoveryConfigUtils;
import com.hazelcast.internal.namespace.ResourceDefinition;
import com.hazelcast.internal.util.CollectionUtil;
import com.hazelcast.memory.Capacity;
import com.hazelcast.shaded.org.snakeyaml.engine.v2.api.Dump;
import com.hazelcast.shaded.org.snakeyaml.engine.v2.api.DumpSettings;
import com.hazelcast.shaded.org.snakeyaml.engine.v2.common.FlowStyle;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.stream.Collectors;

import static com.hazelcast.config.ConfigAccessor.getActiveMemberNetworkConfig;
import static com.hazelcast.config.ConfigXmlGenerator.MASK_FOR_SENSITIVE_DATA;
import static com.hazelcast.config.ConfigXmlGenerator.endpointConfigElementName;
import static com.hazelcast.internal.config.AliasedDiscoveryConfigUtils.aliasedDiscoveryConfigsFrom;
import static com.hazelcast.internal.config.ConfigSections.LICENSE_KEY;
import static com.hazelcast.internal.dynamicconfig.DynamicConfigXmlGenerator.classNameOrImplClass;
import static com.hazelcast.internal.util.StringUtil.isNullOrEmpty;
import static java.lang.Boolean.TRUE;

/**
 * YAML counterpart of {@link ConfigXmlGenerator}. Note that this class isn't
 * complete like its counterpart. However, since dynamic configuration
 * persistence depends on this class, dynamically configurable configurations
 * must be added to this class.
 */
@SuppressWarnings({"checkstyle:MethodCount", "checkstyle:ClassFanOutComplexity"})
public class DynamicConfigYamlGenerator {

    private static final int INDENT = 2;
    private static final boolean DEFAULT_MASK_SENSITIVE_FIELDS = false;
    private static volatile boolean maskSensitiveFields = DEFAULT_MASK_SENSITIVE_FIELDS;

    public String generate(Config config, boolean maskSensitiveFields) {
        DynamicConfigYamlGenerator.maskSensitiveFields = maskSensitiveFields;
        Map document = new LinkedHashMap<>();
        Map root = new LinkedHashMap<>();
        document.put("hazelcast", root);

        root.put("cluster-name", config.getClusterName());

        Map propertiesMap = new LinkedHashMap<>();
        for (Map.Entry entry : config.getProperties().entrySet()) {
            propertiesMap.put(String.valueOf(entry.getKey()), entry.getValue());
        }
        root.put("properties", propertiesMap);

        licenseKeyYamlGenerator(root, config);
        mapYamlGenerator(root, config);
        cacheYamlGenerator(root, config);
        queueYamlGenerator(root, config);
        listYamlGenerator(root, config);
        setYamlGenerator(root, config);
        multiMapYamlGenerator(root, config);
        replicatedMapYamlGenerator(root, config);
        ringbufferYamlGenerator(root, config);
        topicYamlGenerator(root, config);
        reliableTopicYamlGenerator(root, config);
        executorYamlGenerator(root, config);
        durableExecutorYamlGenerator(root, config);
        scheduledExecutorYamlGenerator(root, config);
        cardinalityEstimatorYamlGenerator(root, config);
        flakeIdGeneratorYamlGenerator(root, config);
        pnCounterYamlGenerator(root, config);
        wanReplicationYamlGenerator(root, config);
        networkConfigYamlGenerator(root, config);
        advancedNetworkConfigYamlGenerator(root, config);
        dataConnectionYamlGenerator(root, config);
        namespacesConfigGenerator(root, config);
        metricsConfigGenerator(root, config);
        splitBrainProtectionConfigsGenerator(root, config);
        vectorCollectionYamlGenerator(root, config);

        // Reset maskSensitiveFields to default
        DynamicConfigYamlGenerator.maskSensitiveFields = DEFAULT_MASK_SENSITIVE_FIELDS;

        DumpSettings dumpSettings = DumpSettings.builder()
                .setDefaultFlowStyle(FlowStyle.BLOCK)
                .setIndicatorIndent(INDENT - 2)
                .setIndent(INDENT)
                .build();
        Dump dump = new Dump(dumpSettings);
        return dump.dumpToString(document);
    }

    public static void licenseKeyYamlGenerator(Map parent, Config config) {
        addNonNullToMap(parent, LICENSE_KEY.getName(), getOrMaskValue(config.getLicenseKey()));
    }

    @SuppressWarnings("checkstyle:MethodLength")
    public static void mapYamlGenerator(Map parent, Config config) {
        if (config.getMapConfigs().isEmpty()) {
            return;
        }

        Map child = new LinkedHashMap<>();
        for (MapConfig subConfigAsObject : config.getMapConfigs().values()) {
            Map subConfigAsMap = new LinkedHashMap<>();

            String cacheDeserializedValues = subConfigAsObject.getCacheDeserializedValues() != null
                    ? subConfigAsObject.getCacheDeserializedValues().name().replaceAll("_", "-")
                    : null;

            addNonNullToMap(subConfigAsMap, "in-memory-format",
                    subConfigAsObject.getInMemoryFormat().name());
            addNonNullToMap(subConfigAsMap, "statistics-enabled",
                    subConfigAsObject.isStatisticsEnabled());
            addNonNullToMap(subConfigAsMap, "per-entry-stats-enabled",
                    subConfigAsObject.isPerEntryStatsEnabled());
            addNonNullToMap(subConfigAsMap, "cache-deserialized-values",
                    cacheDeserializedValues);
            addNonNullToMap(subConfigAsMap, "backup-count",
                    subConfigAsObject.getBackupCount());
            addNonNullToMap(subConfigAsMap, "async-backup-count",
                    subConfigAsObject.getAsyncBackupCount());
            addNonNullToMap(subConfigAsMap, "time-to-live-seconds",
                    subConfigAsObject.getTimeToLiveSeconds());
            addNonNullToMap(subConfigAsMap, "max-idle-seconds",
                    subConfigAsObject.getMaxIdleSeconds());
            addNonNullToMap(subConfigAsMap, "merge-policy",
                    getMergePolicyConfigAsMap(subConfigAsObject.getMergePolicyConfig()));
            addNonNullToMap(subConfigAsMap, "split-brain-protection-ref",
                    subConfigAsObject.getSplitBrainProtectionName());
            addNonNullToMap(subConfigAsMap, "read-backup-data",
                    subConfigAsObject.isReadBackupData());
            addNonNullToMap(subConfigAsMap, "metadata-policy",
                    subConfigAsObject.getMetadataPolicy().name());
            addNonNullToMap(subConfigAsMap, "eviction",
                    getEvictionConfigAsMap(subConfigAsObject.getEvictionConfig()));
            addNonNullToMap(subConfigAsMap, "merkle-tree",
                    getMerkleTreeConfigAsMap(subConfigAsObject.getMerkleTreeConfig()));
            addNonNullToMap(subConfigAsMap, "event-journal",
                    getEventJournalConfigAsMap(subConfigAsObject.getEventJournalConfig()));
            addNonNullToMap(subConfigAsMap, "data-persistence",
                    getDataPersistenceConfigAsMap(subConfigAsObject.getDataPersistenceConfig()));
            addNonNullToMap(subConfigAsMap, "map-store",
                    getMapStoreConfigAsMap(subConfigAsObject.getMapStoreConfig()));
            addNonNullToMap(subConfigAsMap, "near-cache",
                    getNearCacheConfigAsMap(subConfigAsObject.getNearCacheConfig()));
            addNonNullToMap(subConfigAsMap, "wan-replication-ref",
                    getWanReplicationRefAsMap(subConfigAsObject.getWanReplicationRef(), true));
            addNonNullToMap(subConfigAsMap, "near-cache",
                    getNearCacheConfigAsMap(subConfigAsObject.getNearCacheConfig()));
            addNonNullToMap(subConfigAsMap, "indexes",
                    getIndexConfigsAsList(subConfigAsObject.getIndexConfigs()));
            addNonNullToMap(subConfigAsMap, "attributes",
                    getAttributeConfigsAsMap(subConfigAsObject.getAttributeConfigs()));
            addNonNullToMap(subConfigAsMap, "entry-listeners",
                    getEntryListenerConfigsAsList(subConfigAsObject.getEntryListenerConfigs()));
            addNonNullToMap(subConfigAsMap, "partition-lost-listeners",
                    getListenerConfigsAsList(subConfigAsObject.getPartitionLostListenerConfigs()));
            addNonNullToMap(subConfigAsMap, "partition-strategy",
                    getPartitioningStrategyAsString(subConfigAsObject.getPartitioningStrategyConfig()));
            addNonNullToMap(subConfigAsMap, "query-caches",
                    getQueryCacheConfigsAsMap(subConfigAsObject.getQueryCacheConfigs()));
            addNonNullToMap(subConfigAsMap, "tiered-store",
                    getTieredStoreConfigAsMap(subConfigAsObject.getTieredStoreConfig()));
            addNonNullToMap(subConfigAsMap, "partition-attributes",
                    getPartitioningAttributesAsList(subConfigAsObject.getPartitioningAttributeConfigs()));
            addNonNullToMap(subConfigAsMap, "user-code-namespace", subConfigAsObject.getUserCodeNamespace());

            child.put(subConfigAsObject.getName(), subConfigAsMap);
        }

        parent.put("map", child);
    }

    public static void cacheYamlGenerator(Map parent, Config config) {
        if (config.getCacheConfigs().isEmpty()) {
            return;
        }

        Map child = new LinkedHashMap<>();
        for (CacheSimpleConfig subConfigAsObject : config.getCacheConfigs().values()) {
            Map subConfigAsMap = new LinkedHashMap<>();

            addNonNullToMap(subConfigAsMap, "key-type",
                    wrapObjectWithMap("class-name", subConfigAsObject.getKeyType()));
            addNonNullToMap(subConfigAsMap, "value-type"
                    , wrapObjectWithMap("class-name", subConfigAsObject.getValueType()));
            addNonNullToMap(subConfigAsMap, "statistics-enabled",
                    subConfigAsObject.isStatisticsEnabled());
            addNonNullToMap(subConfigAsMap, "management-enabled",
                    subConfigAsObject.isManagementEnabled());
            addNonNullToMap(subConfigAsMap, "read-through",
                    subConfigAsObject.isReadThrough());
            addNonNullToMap(subConfigAsMap, "write-through",
                    subConfigAsObject.isWriteThrough());
            addNonNullToMap(subConfigAsMap, "cache-loader-factory",
                    wrapObjectWithMap("class-name", subConfigAsObject.getCacheLoaderFactory()));
            addNonNullToMap(subConfigAsMap, "cache-writer-factory",
                    wrapObjectWithMap("class-name", subConfigAsObject.getCacheWriterFactory()));
            addNonNullToMap(subConfigAsMap, "cache-loader",
                    wrapObjectWithMap("class-name", subConfigAsObject.getCacheLoader()));
            addNonNullToMap(subConfigAsMap, "cache-writer",
                    wrapObjectWithMap("class-name", subConfigAsObject.getCacheWriter()));
            addNonNullToMap(subConfigAsMap, "expiry-policy-factory",
                    getExpiryPolicyFactoryConfigAsMap(subConfigAsObject.getExpiryPolicyFactoryConfig()));
            addNonNullToMap(subConfigAsMap, "cache-entry-listeners",
                    getCacheSimpleEntryListenerConfigsAsList(subConfigAsObject.getCacheEntryListeners()));
            addNonNullToMap(subConfigAsMap, "in-memory-format",
                    subConfigAsObject.getInMemoryFormat().name());
            addNonNullToMap(subConfigAsMap, "backup-count",
                    subConfigAsObject.getBackupCount());
            addNonNullToMap(subConfigAsMap, "async-backup-count",
                    subConfigAsObject.getAsyncBackupCount());
            addNonNullToMap(subConfigAsMap, "eviction",
                    getEvictionConfigAsMap(subConfigAsObject.getEvictionConfig()));
            addNonNullToMap(subConfigAsMap, "wan-replication-ref",
                    getWanReplicationRefAsMap(subConfigAsObject.getWanReplicationRef(), false));
            addNonNullToMap(subConfigAsMap, "split-brain-protection-ref",
                    subConfigAsObject.getSplitBrainProtectionName());
            addNonNullToMap(subConfigAsMap, "partition-lost-listeners",
                    getListenerConfigsAsList(subConfigAsObject.getPartitionLostListenerConfigs()));
            addNonNullToMap(subConfigAsMap, "merge-policy",
                    getMergePolicyConfigAsMap(subConfigAsObject.getMergePolicyConfig()));
            addNonNullToMap(subConfigAsMap, "event-journal",
                    getEventJournalConfigAsMap(subConfigAsObject.getEventJournalConfig()));
            addNonNullToMap(subConfigAsMap, "data-persistence",
                    getDataPersistenceConfigAsMap(subConfigAsObject.getDataPersistenceConfig()));
            addNonNullToMap(subConfigAsMap, "merkle-tree",
                    getMerkleTreeConfigAsMap(subConfigAsObject.getMerkleTreeConfig()));
            addNonNullToMap(subConfigAsMap, "disable-per-entry-invalidation-events",
                    subConfigAsObject.isDisablePerEntryInvalidationEvents());
            addNonNullToMap(subConfigAsMap, "user-code-namespace", subConfigAsObject.getUserCodeNamespace());

            child.put(subConfigAsObject.getName(), subConfigAsMap);
        }

        parent.put("cache", child);
    }

    public static void queueYamlGenerator(Map parent, Config config) {
        if (config.getQueueConfigs().isEmpty()) {
            return;
        }

        Map child = new LinkedHashMap<>();
        for (QueueConfig subConfigAsObject : config.getQueueConfigs().values()) {
            Map subConfigAsMap = new LinkedHashMap<>();

            addNonNullToMap(subConfigAsMap, "priority-comparator-class-name",
                    subConfigAsObject.getPriorityComparatorClassName());
            addNonNullToMap(subConfigAsMap, "statistics-enabled",
                    subConfigAsObject.isStatisticsEnabled());
            addNonNullToMap(subConfigAsMap, "max-size",
                    subConfigAsObject.getMaxSize());
            addNonNullToMap(subConfigAsMap, "backup-count",
                    subConfigAsObject.getBackupCount());
            addNonNullToMap(subConfigAsMap, "async-backup-count",
                    subConfigAsObject.getAsyncBackupCount());
            addNonNullToMap(subConfigAsMap, "empty-queue-ttl",
                    subConfigAsObject.getEmptyQueueTtl());
            addNonNullToMap(subConfigAsMap, "item-listeners",
                    getItemListenerConfigsAsList(subConfigAsObject.getItemListenerConfigs()));
            addNonNullToMap(subConfigAsMap, "queue-store",
                    getQueueStoreConfigAsMap(subConfigAsObject.getQueueStoreConfig()));
            addNonNullToMap(subConfigAsMap, "split-brain-protection-ref",
                    subConfigAsObject.getSplitBrainProtectionName());
            addNonNullToMap(subConfigAsMap, "user-code-namespace", subConfigAsObject.getUserCodeNamespace());
            addNonNullToMap(subConfigAsMap, "merge-policy",
                    getMergePolicyConfigAsMap(subConfigAsObject.getMergePolicyConfig()));

            child.put(subConfigAsObject.getName(), subConfigAsMap);
        }

        parent.put("queue", child);
    }

    public static void listYamlGenerator(Map parent, Config config) {
        if (config.getListConfigs().isEmpty()) {
            return;
        }

        Map child = new LinkedHashMap<>();
        for (ListConfig subConfigAsObject : config.getListConfigs().values()) {
            child.put(subConfigAsObject.getName(), getCollectionConfigAsMap(subConfigAsObject));
        }

        parent.put("list", child);
    }

    public static void setYamlGenerator(Map parent, Config config) {
        if (config.getSetConfigs().isEmpty()) {
            return;
        }

        Map child = new LinkedHashMap<>();
        for (SetConfig subConfigAsObject : config.getSetConfigs().values()) {
            child.put(subConfigAsObject.getName(), getCollectionConfigAsMap(subConfigAsObject));
        }

        parent.put("set", child);
    }

    public static void multiMapYamlGenerator(Map parent, Config config) {
        if (config.getMultiMapConfigs().isEmpty()) {
            return;
        }

        Map child = new LinkedHashMap<>();
        for (MultiMapConfig subConfigAsObject : config.getMultiMapConfigs().values()) {
            Map subConfigAsMap = new LinkedHashMap<>();

            addNonNullToMap(subConfigAsMap, "backup-count",
                    subConfigAsObject.getBackupCount());
            addNonNullToMap(subConfigAsMap, "async-backup-count",
                    subConfigAsObject.getAsyncBackupCount());
            addNonNullToMap(subConfigAsMap, "statistics-enabled",
                    subConfigAsObject.isStatisticsEnabled());
            addNonNullToMap(subConfigAsMap, "binary",
                    subConfigAsObject.isBinary());
            addNonNullToMap(subConfigAsMap, "split-brain-protection-ref",
                    subConfigAsObject.getSplitBrainProtectionName());
            addNonNullToMap(subConfigAsMap, "value-collection-type",
                    subConfigAsObject.getValueCollectionType().name());
            addNonNullToMap(subConfigAsMap, "entry-listeners",
                    getEntryListenerConfigsAsList(subConfigAsObject.getEntryListenerConfigs()));
            addNonNullToMap(subConfigAsMap, "merge-policy",
                    getMergePolicyConfigAsMap(subConfigAsObject.getMergePolicyConfig()));
            addNonNullToMap(subConfigAsMap, "user-code-namespace", subConfigAsObject.getUserCodeNamespace());

            child.put(subConfigAsObject.getName(), subConfigAsMap);
        }

        parent.put("multimap", child);
    }

    public static void replicatedMapYamlGenerator(Map parent, Config config) {
        if (config.getReplicatedMapConfigs().isEmpty()) {
            return;
        }

        Map child = new LinkedHashMap<>();
        for (ReplicatedMapConfig subConfigAsObject : config.getReplicatedMapConfigs().values()) {
            Map subConfigAsMap = new LinkedHashMap<>();

            addNonNullToMap(subConfigAsMap, "in-memory-format",
                    subConfigAsObject.getInMemoryFormat().name());
            addNonNullToMap(subConfigAsMap, "async-fillup",
                    subConfigAsObject.isAsyncFillup());
            addNonNullToMap(subConfigAsMap, "statistics-enabled",
                    subConfigAsObject.isStatisticsEnabled());
            addNonNullToMap(subConfigAsMap, "split-brain-protection-ref",
                    subConfigAsObject.getSplitBrainProtectionName());
            addNonNullToMap(subConfigAsMap, "merge-policy",
                    getMergePolicyConfigAsMap(subConfigAsObject.getMergePolicyConfig()));
            addNonNullToMap(subConfigAsMap, "entry-listeners",
                    getEntryListenerConfigsAsList(subConfigAsObject.getListenerConfigs()));
            addNonNullToMap(subConfigAsMap, "user-code-namespace", subConfigAsObject.getUserCodeNamespace());

            child.put(subConfigAsObject.getName(), subConfigAsMap);
        }

        parent.put("replicatedmap", child);
    }

    public static void ringbufferYamlGenerator(Map parent, Config config) {
        if (config.getRingbufferConfigs().isEmpty()) {
            return;
        }

        Map child = new LinkedHashMap<>();
        for (RingbufferConfig subConfigAsObject : config.getRingbufferConfigs().values()) {
            Map subConfigAsMap = new LinkedHashMap<>();

            addNonNullToMap(subConfigAsMap, "capacity",
                    subConfigAsObject.getCapacity());
            addNonNullToMap(subConfigAsMap, "time-to-live-seconds",
                    subConfigAsObject.getTimeToLiveSeconds());
            addNonNullToMap(subConfigAsMap, "backup-count",
                    subConfigAsObject.getBackupCount());
            addNonNullToMap(subConfigAsMap, "async-backup-count",
                    subConfigAsObject.getAsyncBackupCount());
            addNonNullToMap(subConfigAsMap, "split-brain-protection-ref",
                    subConfigAsObject.getSplitBrainProtectionName());
            addNonNullToMap(subConfigAsMap, "in-memory-format",
                    subConfigAsObject.getInMemoryFormat().name());
            addNonNullToMap(subConfigAsMap, "ringbuffer-store",
                    getRingbufferStoreConfigAsMap(subConfigAsObject.getRingbufferStoreConfig()));
            addNonNullToMap(subConfigAsMap, "merge-policy",
                    getMergePolicyConfigAsMap(subConfigAsObject.getMergePolicyConfig()));
            addNonNullToMap(subConfigAsMap, "user-code-namespace", subConfigAsObject.getUserCodeNamespace());

            child.put(subConfigAsObject.getName(), subConfigAsMap);
        }

        parent.put("ringbuffer", child);
    }

    public static void topicYamlGenerator(Map parent, Config config) {
        if (config.getTopicConfigs().isEmpty()) {
            return;
        }

        Map child = new LinkedHashMap<>();
        for (TopicConfig subConfigAsObject : config.getTopicConfigs().values()) {
            Map subConfigAsMap = new LinkedHashMap<>();

            addNonNullToMap(subConfigAsMap, "statistics-enabled",
                    subConfigAsObject.isStatisticsEnabled());
            addNonNullToMap(subConfigAsMap, "global-ordering-enabled",
                    subConfigAsObject.isGlobalOrderingEnabled());
            addNonNullToMap(subConfigAsMap, "message-listeners",
                    getListenerConfigsAsList(subConfigAsObject.getMessageListenerConfigs()));
            addNonNullToMap(subConfigAsMap, "multi-threading-enabled",
                    subConfigAsObject.isMultiThreadingEnabled());
            addNonNullToMap(subConfigAsMap, "user-code-namespace", subConfigAsObject.getUserCodeNamespace());

            child.put(subConfigAsObject.getName(), subConfigAsMap);
        }

        parent.put("topic", child);
    }

    public static void reliableTopicYamlGenerator(Map parent, Config config) {
        if (config.getReliableTopicConfigs().isEmpty()) {
            return;
        }

        Map child = new LinkedHashMap<>();
        for (ReliableTopicConfig subConfigAsObject : config.getReliableTopicConfigs().values()) {
            Map subConfigAsMap = new LinkedHashMap<>();

            addNonNullToMap(subConfigAsMap, "statistics-enabled",
                    subConfigAsObject.isStatisticsEnabled());
            addNonNullToMap(subConfigAsMap, "read-batch-size",
                    subConfigAsObject.getReadBatchSize());
            addNonNullToMap(subConfigAsMap, "topic-overload-policy",
                    subConfigAsObject.getTopicOverloadPolicy().name());
            addNonNullToMap(subConfigAsMap, "message-listeners",
                    getListenerConfigsAsList(subConfigAsObject.getMessageListenerConfigs()));
            addNonNullToMap(subConfigAsMap, "user-code-namespace", subConfigAsObject.getUserCodeNamespace());
            child.put(subConfigAsObject.getName(), subConfigAsMap);
        }

        parent.put("reliable-topic", child);
    }

    public static void executorYamlGenerator(Map parent, Config config) {
        if (config.getExecutorConfigs().isEmpty()) {
            return;
        }

        Map child = new LinkedHashMap<>();
        for (ExecutorConfig subConfigAsObject : config.getExecutorConfigs().values()) {
            Map subConfigAsMap = new LinkedHashMap<>();

            addNonNullToMap(subConfigAsMap, "statistics-enabled",
                    subConfigAsObject.isStatisticsEnabled());
            addNonNullToMap(subConfigAsMap, "pool-size",
                    subConfigAsObject.getPoolSize());
            addNonNullToMap(subConfigAsMap, "queue-capacity",
                    subConfigAsObject.getQueueCapacity());
            addNonNullToMap(subConfigAsMap, "split-brain-protection-ref",
                    subConfigAsObject.getSplitBrainProtectionName());
            addNonNullToMap(subConfigAsMap, "user-code-namespace", subConfigAsObject.getUserCodeNamespace());

            child.put(subConfigAsObject.getName(), subConfigAsMap);
        }

        parent.put("executor-service", child);
    }

    public static void durableExecutorYamlGenerator(Map parent, Config config) {
        if (config.getDurableExecutorConfigs().isEmpty()) {
            return;
        }

        Map child = new LinkedHashMap<>();
        for (DurableExecutorConfig subConfigAsObject : config.getDurableExecutorConfigs().values()) {
            Map subConfigAsMap = new LinkedHashMap<>();

            addNonNullToMap(subConfigAsMap, "pool-size",
                    subConfigAsObject.getPoolSize());
            addNonNullToMap(subConfigAsMap, "durability",
                    subConfigAsObject.getDurability());
            addNonNullToMap(subConfigAsMap, "capacity",
                    subConfigAsObject.getCapacity());
            addNonNullToMap(subConfigAsMap, "split-brain-protection-ref",
                    subConfigAsObject.getSplitBrainProtectionName());
            addNonNullToMap(subConfigAsMap, "statistics-enabled",
                    subConfigAsObject.isStatisticsEnabled());
            addNonNullToMap(subConfigAsMap, "user-code-namespace", subConfigAsObject.getUserCodeNamespace());

            child.put(subConfigAsObject.getName(), subConfigAsMap);
        }

        parent.put("durable-executor-service", child);
    }

    public static void scheduledExecutorYamlGenerator(Map parent, Config config) {
        if (config.getScheduledExecutorConfigs().isEmpty()) {
            return;
        }

        Map child = new LinkedHashMap<>();
        for (ScheduledExecutorConfig subConfigAsObject : config.getScheduledExecutorConfigs().values()) {
            Map subConfigAsMap = new LinkedHashMap<>();

            addNonNullToMap(subConfigAsMap, "pool-size",
                    subConfigAsObject.getPoolSize());
            addNonNullToMap(subConfigAsMap, "durability",
                    subConfigAsObject.getDurability());
            addNonNullToMap(subConfigAsMap, "capacity",
                    subConfigAsObject.getCapacity());
            addNonNullToMap(subConfigAsMap, "capacity-policy",
                    subConfigAsObject.getCapacityPolicy().name());
            addNonNullToMap(subConfigAsMap, "split-brain-protection-ref",
                    subConfigAsObject.getSplitBrainProtectionName());
            addNonNullToMap(subConfigAsMap, "merge-policy",
                    getMergePolicyConfigAsMap(subConfigAsObject.getMergePolicyConfig()));
            addNonNullToMap(subConfigAsMap, "statistics-enabled",
                    subConfigAsObject.isStatisticsEnabled());
            addNonNullToMap(subConfigAsMap, "user-code-namespace", subConfigAsObject.getUserCodeNamespace());
            child.put(subConfigAsObject.getName(), subConfigAsMap);
        }

        parent.put("scheduled-executor-service", child);
    }

    public static void cardinalityEstimatorYamlGenerator(Map parent, Config config) {
        if (config.getCardinalityEstimatorConfigs().isEmpty()) {
            return;
        }

        Map child = new LinkedHashMap<>();
        for (CardinalityEstimatorConfig subConfigAsObject : config.getCardinalityEstimatorConfigs().values()) {
            Map subConfigAsMap = new LinkedHashMap<>();

            addNonNullToMap(subConfigAsMap, "backup-count",
                    subConfigAsObject.getBackupCount());
            addNonNullToMap(subConfigAsMap, "async-backup-count",
                    subConfigAsObject.getAsyncBackupCount());
            addNonNullToMap(subConfigAsMap, "split-brain-protection-ref",
                    subConfigAsObject.getSplitBrainProtectionName());
            addNonNullToMap(subConfigAsMap, "merge-policy",
                    getMergePolicyConfigAsMap(subConfigAsObject.getMergePolicyConfig()));

            child.put(subConfigAsObject.getName(), subConfigAsMap);
        }

        parent.put("cardinality-estimator", child);
    }

    public static void flakeIdGeneratorYamlGenerator(Map parent, Config config) {
        if (config.getFlakeIdGeneratorConfigs().isEmpty()) {
            return;
        }

        Map child = new LinkedHashMap<>();
        for (FlakeIdGeneratorConfig subConfigAsObject : config.getFlakeIdGeneratorConfigs().values()) {
            Map subConfigAsMap = new LinkedHashMap<>();

            addNonNullToMap(subConfigAsMap, "prefetch-count",
                    subConfigAsObject.getPrefetchCount());
            addNonNullToMap(subConfigAsMap, "prefetch-validity-millis",
                    subConfigAsObject.getPrefetchValidityMillis());
            addNonNullToMap(subConfigAsMap, "epoch-start",
                    subConfigAsObject.getEpochStart());
            addNonNullToMap(subConfigAsMap, "node-id-offset",
                    subConfigAsObject.getNodeIdOffset());
            addNonNullToMap(subConfigAsMap, "bits-sequence",
                    subConfigAsObject.getBitsSequence());
            addNonNullToMap(subConfigAsMap, "bits-node-id",
                    subConfigAsObject.getBitsNodeId());
            addNonNullToMap(subConfigAsMap, "allowed-future-millis",
                    subConfigAsObject.getAllowedFutureMillis());
            addNonNullToMap(subConfigAsMap, "statistics-enabled",
                    subConfigAsObject.isStatisticsEnabled());

            child.put(subConfigAsObject.getName(), subConfigAsMap);
        }

        parent.put("flake-id-generator", child);
    }

    public static void pnCounterYamlGenerator(Map parent, Config config) {
        if (config.getPNCounterConfigs().isEmpty()) {
            return;
        }

        Map child = new LinkedHashMap<>();
        for (PNCounterConfig subConfigAsObject : config.getPNCounterConfigs().values()) {
            Map subConfigAsMap = new LinkedHashMap<>();

            addNonNullToMap(subConfigAsMap, "replica-count",
                    subConfigAsObject.getReplicaCount());
            addNonNullToMap(subConfigAsMap, "split-brain-protection-ref",
                    subConfigAsObject.getSplitBrainProtectionName());
            addNonNullToMap(subConfigAsMap, "statistics-enabled",
                    subConfigAsObject.isStatisticsEnabled());

            child.put(subConfigAsObject.getName(), subConfigAsMap);
        }

        parent.put("pn-counter", child);
    }

    public static void dataConnectionYamlGenerator(Map parent, Config config) {
        if (config.getDataConnectionConfigs().isEmpty()) {
            return;
        }

        Map child = new LinkedHashMap<>();
        for (DataConnectionConfig dataConnectionConfig : config.getDataConnectionConfigs().values()) {
            Map subConfigAsMap = new LinkedHashMap<>();

            addNonNullToMap(subConfigAsMap, "type",
                    dataConnectionConfig.getType());
            addNonNullToMap(subConfigAsMap, "shared",
                    dataConnectionConfig.isShared());
            addNonNullToMap(subConfigAsMap, "properties",
                    getPropertiesAsMap(dataConnectionConfig.getProperties()));

            child.put(dataConnectionConfig.getName(), subConfigAsMap);
        }

        parent.put("data-connection", child);
    }

    public static void wanReplicationYamlGenerator(Map parent, Config config) {
        if (config.getWanReplicationConfigs().isEmpty()) {
            return;
        }

        Map child = new LinkedHashMap<>();
        for (WanReplicationConfig subConfigAsObject : config.getWanReplicationConfigs().values()) {
            Map subConfigAsMap = new LinkedHashMap<>();

            addNonNullToMap(subConfigAsMap, "batch-publisher",
                    getWanBatchPublisherConfigsAsMap(subConfigAsObject.getBatchPublisherConfigs()));
            addNonNullToMap(subConfigAsMap, "custom-publisher",
                    getWanCustomPublisherConfigsAsMap(subConfigAsObject.getCustomPublisherConfigs()));
            addNonNullToMap(subConfigAsMap, "consumer",
                    getWanConsumerConfigsAsMap(subConfigAsObject.getConsumerConfig()));

            child.put(subConfigAsObject.getName(), subConfigAsMap);
        }

        parent.put("wan-replication", child);
    }

    private void networkConfigYamlGenerator(Map parent, Config config) {
        if (config.getAdvancedNetworkConfig().isEnabled()) {
            return;
        }

        Map child = new LinkedHashMap<>();
        NetworkConfig netCfg = config.getNetworkConfig();
        addNonNullToMap(child, "public-address", netCfg.getPublicAddress());
        Map portCfg = new LinkedHashMap<>();
        addNonNullToMap(portCfg, "port", netCfg.getPort());
        addNonNullToMap(portCfg, "port-count", netCfg.getPortCount());
        addNonNullToMap(portCfg, "auto-increment", netCfg.isPortAutoIncrement());
        child.put("port", portCfg);
        addNonNullToMap(child, "reuse-address", netCfg.isReuseAddress());

        Collection outboundPortDefinitions = netCfg.getOutboundPortDefinitions();
        if (CollectionUtil.isNotEmpty(outboundPortDefinitions)) {
            child.put("outbound-ports", new ArrayList<>(outboundPortDefinitions));
        }
        JoinConfig join = netCfg.getJoin();
        Map joinSubConfig = new LinkedHashMap<>();
        autoDetectionConfigYamlGenerator(joinSubConfig, join);
        multicastConfigYamlGenerator(joinSubConfig, join);
        tcpIpConfigYamlGenerator(joinSubConfig, config);
        aliasedDiscoveryConfigsYamlGenerator(joinSubConfig, aliasedDiscoveryConfigsFrom(join));
        discoveryStrategyConfigYamlGenerator(joinSubConfig, join.getDiscoveryConfig());
        addNonNullToMap(child, "join", joinSubConfig);

        interfacesConfigYamlGenerator(child, netCfg.getInterfaces());
        sslConfigYamlGenerator(child, netCfg.getSSLConfig());
        socketInterceptorConfigYamlGenerator(child, netCfg.getSocketInterceptorConfig());
        symmetricEncInterceptorConfigYamlGenerator(child, netCfg.getSymmetricEncryptionConfig());
        memberAddressProviderConfigYamlGenerator(child, netCfg.getMemberAddressProviderConfig());
        failureDetectorConfigYamlGenerator(child, netCfg.getIcmpFailureDetectorConfig());
        restApiYamlGenerator(child, netCfg.getRestApiConfig());
        memcacheProtocolYamlGenerator(child, netCfg.getMemcacheProtocolConfig());
        parent.put("network", child);
    }

    private void advancedNetworkConfigYamlGenerator(Map parent, Config config) {
        AdvancedNetworkConfig netCfg = config.getAdvancedNetworkConfig();
        if (!netCfg.isEnabled()) {
            return;
        }
        Map child = new LinkedHashMap<>();
        child.put("enabled", netCfg.isEnabled());

        JoinConfig join = netCfg.getJoin();
        Map joinSubConfig = new LinkedHashMap<>();
        autoDetectionConfigYamlGenerator(joinSubConfig, join);
        multicastConfigYamlGenerator(joinSubConfig, join);
        tcpIpConfigYamlGenerator(joinSubConfig, config);
        aliasedDiscoveryConfigsYamlGenerator(joinSubConfig, aliasedDiscoveryConfigsFrom(join));
        discoveryStrategyConfigYamlGenerator(joinSubConfig, join.getDiscoveryConfig());
        addNonNullToMap(child, "join", joinSubConfig);

        failureDetectorConfigYamlGenerator(child, netCfg.getIcmpFailureDetectorConfig());
        memberAddressProviderConfigYamlGenerator(child, netCfg.getMemberAddressProviderConfig());
        for (EndpointConfig endpointConfig : netCfg.getEndpointConfigs().values()) {
            endpointConfigYamlGenerator(child, endpointConfig);
        }
        parent.put("advanced-network", child);
    }

    public static void tcpIpConfigYamlGenerator(Map parent, Config config) {
        TcpIpConfig tcpIpConfig = getActiveMemberNetworkConfig(config).getJoin().getTcpIpConfig();
        Map child = new LinkedHashMap<>();
        child.put("enabled", tcpIpConfig.isEnabled());
        child.put("connection-timeout-seconds", tcpIpConfig.getConnectionTimeoutSeconds());
        addNonNullToMap(child, "member-list", tcpIpConfig.getMembers());
        addNonNullToMap(child, "required-member", tcpIpConfig.getRequiredMember());
        parent.put("tcp-ip", child);
    }

    private static void autoDetectionConfigYamlGenerator(Map parent, JoinConfig joinConfig) {
        Map child = new LinkedHashMap<>();
        child.put("enabled", joinConfig.getAutoDetectionConfig().isEnabled());
        parent.put("auto-detection", child);
    }

    private static void multicastConfigYamlGenerator(Map parent, JoinConfig joinConfig) {
        Map child = new LinkedHashMap<>();
        MulticastConfig multicastCfg = joinConfig.getMulticastConfig();
        if (multicastCfg == null) {
            return;
        }
        addNonNullToMap(child, "enabled", multicastCfg.isEnabled());
        addNonNullToMap(child, "loopback-mode-enabled", multicastCfg.getLoopbackModeEnabled());
        addNonNullToMap(child, "multicast-group", multicastCfg.getMulticastGroup());
        addNonNullToMap(child, "multicast-port", multicastCfg.getMulticastPort());
        addNonNullToMap(child, "multicast-timeout-seconds", multicastCfg.getMulticastTimeoutSeconds());
        addNonNullToMap(child, "multicast-time-to-live", multicastCfg.getMulticastTimeToLive());
        addNonNullToMap(child, "trusted-interfaces", new ArrayList<>(multicastCfg.getTrustedInterfaces()));
        parent.put("multicast", child);
    }

    private static void aliasedDiscoveryConfigsYamlGenerator(Map parent,
                                                             List> configs) {
        if (configs == null) {
            return;
        }
        for (AliasedDiscoveryConfig c : configs) {
            Map child = new LinkedHashMap<>();
            child.put("enabled", c.isEnabled());
            if (c.isUsePublicIp()) {
                child.put("use-public-ip", "true");
            }
            if (!c.getProperties().isEmpty()) {
                child.put("properties", c.getProperties());
            }

            parent.put(AliasedDiscoveryConfigUtils.tagFor(c), child);
        }
    }

    private static void discoveryStrategyConfigYamlGenerator(Map parent, DiscoveryConfig discoveryConfig) {
        if (discoveryConfig == null) {
            return;
        }
        Map child = new LinkedHashMap<>();
        String nodeFilterClass = classNameOrImplClass(discoveryConfig.getNodeFilterClass(), discoveryConfig.getNodeFilter());
        if (nodeFilterClass != null) {
            child.put("node-filter", wrapObjectWithMap("class", nodeFilterClass));
        }

        Collection configs = discoveryConfig.getDiscoveryStrategyConfigs();
        if (CollectionUtil.isNotEmpty(configs)) {
            for (DiscoveryStrategyConfig config : configs) {
                Map discoveryStrategySubConfig = new LinkedHashMap<>();
                addNonNullToMap(
                        discoveryStrategySubConfig,
                        "class",
                        classNameOrImplClass(config.getClassName(), config.getDiscoveryStrategyFactory())
                );
                addNonNullToMap(
                        discoveryStrategySubConfig,
                        "enabled",
                        classNameOrImplClass(config.getClassName(), config.getDiscoveryStrategyFactory())
                );
                addNonNullToMap(
                        discoveryStrategySubConfig,
                        "properties",
                        config.getProperties()
                );
                child.put("discovery-strategy", discoveryStrategySubConfig);
            }
        }
        parent.put("discovery-strategies", child);
    }

    private static void sslConfigYamlGenerator(Map parent, SSLConfig sslConfig) {
        if (sslConfig == null) {
            return;
        }
        Map child = new LinkedHashMap<>();
        sslConfig = new SSLConfig(sslConfig);
        child.put("enabled", sslConfig.isEnabled());

        String factoryClassName = classNameOrImplClass(sslConfig.getFactoryClassName(), sslConfig.getFactoryImplementation());
        if (factoryClassName != null) {
            sslConfig.setFactoryClassName(factoryClassName);
            child.put("factory-class-name", factoryClassName);
        }

        Properties props = sslConfig.getProperties();

        if (maskSensitiveFields && props.containsKey("trustStorePassword")) {
            props.setProperty("trustStorePassword", MASK_FOR_SENSITIVE_DATA);
        }

        if (maskSensitiveFields && props.containsKey("keyStorePassword")) {
            props.setProperty("keyStorePassword", MASK_FOR_SENSITIVE_DATA);
        }
        addNonNullToMap(child, "properties", props);

        parent.put("ssl", child);
    }

    private static void interfacesConfigYamlGenerator(Map parent, InterfacesConfig interfaces) {
        if (interfaces.getInterfaces() == null || interfaces.getInterfaces().isEmpty()) {
            return;
        }
        Map child = new LinkedHashMap<>();
        child.put("enabled", interfaces.isEnabled());
        child.put("interfaces", new ArrayList<>(interfaces.getInterfaces()));
        parent.put("interfaces", child);
    }

    private static void socketInterceptorConfigYamlGenerator(
            Map parent,
            SocketInterceptorConfig socketInterceptorCfg
    ) {
        if (socketInterceptorCfg == null) {
            return;
        }
        Map child = new LinkedHashMap<>();
        child.put("enabled", socketInterceptorCfg.isEnabled());
        String className = classNameOrImplClass(socketInterceptorCfg.getClassName(), socketInterceptorCfg.getImplementation());
        addNonNullToMap(child, "class-name", className);
        addNonNullToMap(child, "properties", getPropertiesAsMap(socketInterceptorCfg.getProperties()));
        parent.put("socket-interceptor", child);
    }

    private static void symmetricEncInterceptorConfigYamlGenerator(Map parent, SymmetricEncryptionConfig sec) {
        if (sec == null) {
            return;
        }
        Map child = new LinkedHashMap<>();
        child.put("enabled", sec.isEnabled());
        addNonNullToMap(child, "algorithm", sec.getAlgorithm());
        addNonNullToMap(child, "salt", getOrMaskValue(sec.getSalt()));
        addNonNullToMap(child, "password", getOrMaskValue(sec.getPassword()));
        addNonNullToMap(child, "iteration-count", sec.getIterationCount());
        parent.put("symmetric-encryption", child);
    }

    private static void memberAddressProviderConfigYamlGenerator(
            Map parent,
            MemberAddressProviderConfig memberAddressProviderConfig
    ) {
        if (memberAddressProviderConfig == null) {
            return;
        }
        String className = classNameOrImplClass(memberAddressProviderConfig.getClassName(),
                memberAddressProviderConfig.getImplementation());
        if (isNullOrEmpty(className)) {
            return;
        }
        Map child = new LinkedHashMap<>();
        child.put("enabled", memberAddressProviderConfig.isEnabled());
        child.put("class-name", className);
        addNonNullToMap(child, "properties", getPropertiesAsMap(memberAddressProviderConfig.getProperties()));
        parent.put("member-address-provider", child);
    }

    private static void failureDetectorConfigYamlGenerator(
            Map parent,
            IcmpFailureDetectorConfig icmpFailureDetectorConfig
    ) {
        if (icmpFailureDetectorConfig == null) {
            return;
        }
        Map child = new LinkedHashMap<>();
        addNonNullToMap(child, "enabled", icmpFailureDetectorConfig.isEnabled());
        addNonNullToMap(child, "timeout-milliseconds", icmpFailureDetectorConfig.getTimeoutMilliseconds());
        addNonNullToMap(child, "fail-fast-on-startup", icmpFailureDetectorConfig.isFailFastOnStartup());
        addNonNullToMap(child, "interval-milliseconds", icmpFailureDetectorConfig.getIntervalMilliseconds());
        addNonNullToMap(child, "max-attempts", icmpFailureDetectorConfig.getMaxAttempts());
        addNonNullToMap(child, "parallel-mode", icmpFailureDetectorConfig.isParallelMode());
        addNonNullToMap(child, "ttl", icmpFailureDetectorConfig.getTtl());

        parent.put("failure-detector", wrapObjectWithMap("icmp", child));
    }

    private static void restApiYamlGenerator(Map parent, RestApiConfig restApiConfig) {
        if (restApiConfig == null) {
            return;
        }
        Map child = new LinkedHashMap<>();
        child.put("enabled", restApiConfig.isEnabled());

        Map endpointGroupsAsMap = new LinkedHashMap<>();
        Set enabledGroups = restApiConfig.getEnabledGroups();
        for (RestEndpointGroup endpointGroup : RestEndpointGroup.getAllEndpointGroups()) {
            endpointGroupsAsMap.put(endpointGroup.name(), wrapObjectWithMap("enabled",
                    enabledGroups.stream().anyMatch(enabledGroup -> enabledGroup.getCode() == endpointGroup.getCode())));
        }
        child.put("endpoint-groups", endpointGroupsAsMap);
        parent.put("rest-api", child);
    }

    private static void memcacheProtocolYamlGenerator(Map parent, MemcacheProtocolConfig memcacheProtocolConfig) {
        if (memcacheProtocolConfig == null) {
            return;
        }
        parent.put("memcache-protocol", wrapObjectWithMap("enabled", memcacheProtocolConfig.isEnabled()));
    }

    private static void endpointConfigYamlGenerator(Map parent, EndpointConfig endpointConfig) {
        Map child = new LinkedHashMap<>();

        if (endpointConfig.getName() != null && !endpointConfig.getProtocolType().equals(ProtocolType.WAN)) {
            child.put("name", endpointConfig.getName());
        }

        Collection outboundPortDefinitions = endpointConfig.getOutboundPortDefinitions();
        if (CollectionUtil.isNotEmpty(outboundPortDefinitions)) {
            addNonNullToMap(child, "outbound-ports", new ArrayList<>(outboundPortDefinitions));
        }
        interfacesConfigYamlGenerator(child, endpointConfig.getInterfaces());
        sslConfigYamlGenerator(child, endpointConfig.getSSLConfig());
        socketInterceptorConfigYamlGenerator(child, endpointConfig.getSocketInterceptorConfig());
        symmetricEncInterceptorConfigYamlGenerator(child, endpointConfig.getSymmetricEncryptionConfig());

        if (endpointConfig instanceof RestServerEndpointConfig restServerEndpointConfig) {
            Map endpointGroupsAsMap = new LinkedHashMap<>();
            Set enabledGroups = restServerEndpointConfig.getEnabledGroups();
            for (RestEndpointGroup endpointGroup : RestEndpointGroup.getAllEndpointGroups()) {
                endpointGroupsAsMap.put(endpointGroup.name(), wrapObjectWithMap("enabled",
                        enabledGroups.stream().anyMatch(enabledGroup -> enabledGroup.getCode() == endpointGroup.getCode())));
            }
            child.put("endpoint-groups", endpointGroupsAsMap);
        }

        // socket-options
        Map socketOptions = new LinkedHashMap<>();
        addNonNullToMap(socketOptions, "buffer-direct", endpointConfig.isSocketBufferDirect());
        addNonNullToMap(socketOptions, "tcp-no-delay", endpointConfig.isSocketTcpNoDelay());
        addNonNullToMap(socketOptions, "keep-alive", endpointConfig.isSocketKeepAlive());
        addNonNullToMap(socketOptions, "connect-timeout-seconds", endpointConfig.getSocketConnectTimeoutSeconds());
        addNonNullToMap(socketOptions, "send-buffer-size-kb", endpointConfig.getSocketSendBufferSizeKb());
        addNonNullToMap(socketOptions, "receive-buffer-size-kb", endpointConfig.getSocketRcvBufferSizeKb());
        addNonNullToMap(socketOptions, "linger-seconds", endpointConfig.getSocketLingerSeconds());
        if (!socketOptions.isEmpty()) {
            addNonNullToMap(child, "socket-options", socketOptions);
        }

        if (endpointConfig instanceof ServerSocketEndpointConfig serverSocketEndpointConfig) {

            Map portCfg = new LinkedHashMap<>();
            addNonNullToMap(portCfg, "port", serverSocketEndpointConfig.getPort());
            addNonNullToMap(portCfg, "port-count", serverSocketEndpointConfig.getPortCount());
            addNonNullToMap(portCfg, "auto-increment", serverSocketEndpointConfig.isPortAutoIncrement());
            addNonNullToMap(child, "public-address", serverSocketEndpointConfig.getPublicAddress());
            addNonNullToMap(child, "reuse-address", serverSocketEndpointConfig.isReuseAddress());
            addNonNullToMap(child, "port", portCfg);
        }
        if (endpointConfig.getName() != null && endpointConfig.getProtocolType().equals(ProtocolType.WAN)) {
            parent.put(endpointConfigElementName(endpointConfig), wrapObjectWithMap(endpointConfig.getName(), child));
        } else {
            parent.put(endpointConfigElementName(endpointConfig), child);
        }
    }

    static Map javaSerializationFilterGenerator(JavaSerializationFilterConfig jsfConfig) {
        Map javaSerializationFilterCfg = new LinkedHashMap<>();
        addNonNullToMap(javaSerializationFilterCfg, "defaults-disabled", jsfConfig.isDefaultsDisabled());
        Map whiteListAsMap = classFilterGenerator(jsfConfig.getWhitelist());
        Map blackListAsMap = classFilterGenerator(jsfConfig.getBlacklist());
        javaSerializationFilterCfg.put("blacklist", blackListAsMap);
        javaSerializationFilterCfg.put("whitelist", whiteListAsMap);
        return javaSerializationFilterCfg;
    }

    static Map classFilterGenerator(ClassFilter classFilter) {
        if (classFilter == null || classFilter.isEmpty()) {
            return Collections.emptyMap();
        }
        Map classFilterMap = new LinkedHashMap<>();
        List packagesAsList = new ArrayList<>();
        List classesAsList = new ArrayList<>();
        List prefixesAsList = new ArrayList<>();
        for (String p : classFilter.getPackages()) {
            packagesAsList.add(p);
        }
        for (String c : classFilter.getClasses()) {
            classesAsList.add(c);
        }
        for (String p : classFilter.getPrefixes()) {
            prefixesAsList.add(p);
        }
        classFilterMap.put("package", packagesAsList);
        classFilterMap.put("class", classesAsList);
        classFilterMap.put("prefix", prefixesAsList);
        return classFilterMap;
    }

    public static void namespacesConfigGenerator(Map parent, Config config) {
        Map child = new LinkedHashMap<>();
        UserCodeNamespacesConfig userCodeNamespacesConfig = config.getNamespacesConfig();
        addNonNullToMap(child, "enabled", userCodeNamespacesConfig.isEnabled());
        parent.put("user-code-namespaces", child);

        if (userCodeNamespacesConfig.getClassFilterConfig() != null) {
            Map javaSerializationFilterCfg =
                    javaSerializationFilterGenerator(userCodeNamespacesConfig.getClassFilterConfig());
            addNonNullToMap(child, "class-filter", javaSerializationFilterCfg);
        }

        namespaceConfigGenerator(child, config);
    }

    public static void namespaceConfigGenerator(Map parent, Config config) {
        ConfigAccessor.getNamespaceConfigs(config.getNamespacesConfig()).forEach((namespaceName, namespaceConfig) -> {
            List> items = new ArrayList<>();

            for (ResourceDefinition resourceDefinition : ConfigAccessor.getResourceDefinitions(namespaceConfig)) {
                Map subConfigAsMap = new LinkedHashMap<>();
                subConfigAsMap.put("id", resourceDefinition.id());
                subConfigAsMap.put("resource-type", resourceDefinition.type().toString());
                subConfigAsMap.put("url", resourceDefinition.url());

                items.add(subConfigAsMap);
            }

            parent.put(namespaceName, items);
        });
    }

    private static void metricsConfigGenerator(Map parent, Config config) {
        MetricsConfig metricsConfig = config.getMetricsConfig();
        Map child = new LinkedHashMap<>();

        parent.put("metrics", child);
        child.put("enabled", metricsConfig.isEnabled());
        if (!metricsConfig.isEnabled()) {
            return;
        }
        addNonNullToMap(child, "collection-frequency-seconds", metricsConfig.getCollectionFrequencySeconds());
        if (metricsConfig.getJmxConfig().isEnabled()) {
            Map jmxMap = new LinkedHashMap<>(1);
            jmxMap.put("enabled", metricsConfig.getJmxConfig().isEnabled());
            child.put("jmx", jmxMap);
        }
        if (metricsConfig.getManagementCenterConfig().isEnabled()) {
            Map mcMap = new LinkedHashMap<>(1);
            mcMap.put("enabled", metricsConfig.getManagementCenterConfig().isEnabled());
            addNonNullToMap(mcMap, "retention-seconds", metricsConfig.getManagementCenterConfig().getRetentionSeconds());
            child.put("management-center", mcMap);
        }
    }

    private static void splitBrainProtectionConfigsGenerator(Map parent, Config config) {
        Map splitBrainProtectionConfigs = config.getSplitBrainProtectionConfigs();
        if (splitBrainProtectionConfigs.isEmpty()) {
            return;
        }
        Map child = new LinkedHashMap<>();
        parent.put("split-brain-protection", child);
        for (Map.Entry entry : splitBrainProtectionConfigs.entrySet()) {
            Map configMap = new LinkedHashMap<>();
            child.put(entry.getKey(), configMap);
            addNonNullToMap(configMap, "enabled", entry.getValue().isEnabled());
            addNonNullToMap(configMap, "minimum-cluster-size", entry.getValue().getMinimumClusterSize());
            if (entry.getValue().getProtectOn() != null) {
                configMap.put("protect-on", entry.getValue().getProtectOn().name());
            }
            addNonNullToMap(configMap, "function-class-name", entry.getValue().getFunctionClassName());
            if (!entry.getValue().getListenerConfigs().isEmpty()) {
                List listenersList = new ArrayList<>(entry.getValue().getListenerConfigs().size());
                for (SplitBrainProtectionListenerConfig listenerConfig : entry.getValue().getListenerConfigs()) {
                    listenersList.add(listenerConfig.getClassName());
                }
                configMap.put("listeners", listenersList);
            }
        }
    }


    public static void vectorCollectionYamlGenerator(Map parent, Config config) {
        var vectorsConfigAsMap = config.getVectorCollectionConfigs().values().stream().collect(
                Collectors.toMap(
                        VectorCollectionConfig::getName,
                        entry -> {
                            Map vectorConfigAsMap = new LinkedHashMap<>();
                            addNonNullToMap(
                                    vectorConfigAsMap,
                                    "indexes",
                                    vectorIndexesToList(entry.getVectorIndexConfigs())
                            );
                            return vectorConfigAsMap;
                        }
                )
        );
        parent.put("vector-collection", vectorsConfigAsMap);
    }

    private static List> vectorIndexesToList(List vectorIndexesConfigs) {
        return vectorIndexesConfigs.stream().map(entry -> {
            Map map = new HashMap<>();
            map.put("metric", entry.getMetric().name());
            map.put("dimension", entry.getDimension());
            addNonNullToMap(map, "name", entry.getName());
            addNonNullToMap(map, "max-degree", entry.getMaxDegree());
            addNonNullToMap(map, "ef-construction", entry.getEfConstruction());
            addNonNullToMap(map, "use-deduplication", entry.isUseDeduplication());
            return map;
        }).collect(Collectors.toList());
    }

    private static Map getWanConsumerConfigsAsMap(WanConsumerConfig wanConsumerConfig) {
        if (wanConsumerConfig == null) {
            return null;
        }

        Map wanConsumerConfigAsMap = new LinkedHashMap<>();

        addNonNullToMap(wanConsumerConfigAsMap, "class-name",
                classNameOrImplClass(wanConsumerConfig.getClassName(), wanConsumerConfig.getImplementation()));
        addNonNullToMap(wanConsumerConfigAsMap, "persist-wan-replicated-data",
                wanConsumerConfig.isPersistWanReplicatedData());
        addNonNullToMap(wanConsumerConfigAsMap, "properties",
                getPropertiesAsMap(wanConsumerConfig.getProperties()));

        return wanConsumerConfigAsMap;
    }

    private static Map getWanCustomPublisherConfigsAsMap(
            List wanCustomPublisherConfigs
    ) {
        if (wanCustomPublisherConfigs == null || wanCustomPublisherConfigs.isEmpty()) {
            return null;
        }

        Map wanBatchPublisherConfigsAsMap = new LinkedHashMap<>();
        for (WanCustomPublisherConfig wanCustomPublisherConfig : wanCustomPublisherConfigs) {
            Map wanCustomPublisherConfigAsMap = new LinkedHashMap<>();

            addNonNullToMap(wanCustomPublisherConfigAsMap, "class-name",
                    wanCustomPublisherConfig.getClassName());
            addNonNullToMap(wanCustomPublisherConfigAsMap, "properties",
                    getPropertiesAsMap(wanCustomPublisherConfig.getProperties()));

            wanBatchPublisherConfigsAsMap.put(wanCustomPublisherConfig.getPublisherId(), wanCustomPublisherConfigAsMap);
        }

        return wanBatchPublisherConfigsAsMap;
    }

    @SuppressWarnings("checkstyle:MethodLength")
    private static Map getWanBatchPublisherConfigsAsMap(
            List wanBatchPublisherConfigs
    ) {
        if (wanBatchPublisherConfigs == null || wanBatchPublisherConfigs.isEmpty()) {
            return null;
        }

        Map wanBatchPublisherConfigsAsMap = new LinkedHashMap<>();

        for (WanBatchPublisherConfig wanBatchPublisherConfig : wanBatchPublisherConfigs) {
            Map wanBatchPublisherConfigAsMap = new LinkedHashMap<>();

            addNonNullToMap(wanBatchPublisherConfigAsMap, "cluster-name",
                    wanBatchPublisherConfig.getClusterName());
             addNonNullToMap(wanBatchPublisherConfigAsMap, "publisher-id",
                     wanBatchPublisherConfig.getPublisherId());
            addNonNullToMap(wanBatchPublisherConfigAsMap, "batch-size",
                    wanBatchPublisherConfig.getBatchSize());
            addNonNullToMap(wanBatchPublisherConfigAsMap, "batch-max-delay-millis",
                    wanBatchPublisherConfig.getBatchMaxDelayMillis());
            addNonNullToMap(wanBatchPublisherConfigAsMap, "response-timeout-millis",
                    wanBatchPublisherConfig.getResponseTimeoutMillis());
            addNonNullToMap(wanBatchPublisherConfigAsMap, "acknowledge-type",
                    wanBatchPublisherConfig.getAcknowledgeType().name());
            addNonNullToMap(wanBatchPublisherConfigAsMap, "initial-publisher-state",
                    wanBatchPublisherConfig.getInitialPublisherState().name());
            addNonNullToMap(wanBatchPublisherConfigAsMap, "snapshot-enabled",
                    wanBatchPublisherConfig.isSnapshotEnabled());
            addNonNullToMap(wanBatchPublisherConfigAsMap, "idle-max-park-ns",
                    wanBatchPublisherConfig.getIdleMaxParkNs());
            addNonNullToMap(wanBatchPublisherConfigAsMap, "idle-min-park-ns",
                    wanBatchPublisherConfig.getIdleMinParkNs());
            addNonNullToMap(wanBatchPublisherConfigAsMap, "max-concurrent-invocations",
                    wanBatchPublisherConfig.getMaxConcurrentInvocations());
            addNonNullToMap(wanBatchPublisherConfigAsMap, "discovery-period-seconds",
                    wanBatchPublisherConfig.getDiscoveryPeriodSeconds());
            addNonNullToMap(wanBatchPublisherConfigAsMap, "use-endpoint-private-address",
                    wanBatchPublisherConfig.isUseEndpointPrivateAddress());
            addNonNullToMap(wanBatchPublisherConfigAsMap, "queue-full-behavior",
                    wanBatchPublisherConfig.getQueueFullBehavior().name());
            addNonNullToMap(wanBatchPublisherConfigAsMap, "max-target-endpoints",
                    wanBatchPublisherConfig.getMaxTargetEndpoints());
            addNonNullToMap(wanBatchPublisherConfigAsMap, "queue-capacity",
                    wanBatchPublisherConfig.getQueueCapacity());
            addNonNullToMap(wanBatchPublisherConfigAsMap, "properties",
                    getPropertiesAsMap(wanBatchPublisherConfig.getProperties()));
            addNonNullToMap(wanBatchPublisherConfigAsMap, "target-endpoints",
                    wanBatchPublisherConfig.getTargetEndpoints());
            addNonNullToMap(wanBatchPublisherConfigAsMap, "endpoint",
                    wanBatchPublisherConfig.getEndpoint());
            addNonNullToMap(wanBatchPublisherConfigAsMap, "sync",
                    wrapObjectWithMap("consistency-check-strategy",
                            wanBatchPublisherConfig.getSyncConfig().getConsistencyCheckStrategy().name()));
            addNonNullToMap(wanBatchPublisherConfigAsMap, "discovery-strategies",
                    getDiscoveryConfigAsMap(wanBatchPublisherConfig.getDiscoveryConfig()));
            addNonNullToMap(wanBatchPublisherConfigAsMap, "discovery-strategies",
                    getDiscoveryConfigAsMap(wanBatchPublisherConfig.getDiscoveryConfig()));

            for (
                    AliasedDiscoveryConfig aliasedDiscoveryConfig
                    :
                    aliasedDiscoveryConfigsFrom(wanBatchPublisherConfig)
            ) {
                addNonNullToMap(wanBatchPublisherConfigAsMap, aliasedDiscoveryConfig.getTag(),
                        getAliasedDiscoveryConfigAsMap(aliasedDiscoveryConfig));
            }

            wanBatchPublisherConfigsAsMap.put(wanBatchPublisherConfig.getPublisherId(), wanBatchPublisherConfigAsMap);
        }

        return wanBatchPublisherConfigsAsMap;
    }

    private static Map getAliasedDiscoveryConfigAsMap(
            AliasedDiscoveryConfig aliasedDiscoveryConfig
    ) {
        if (aliasedDiscoveryConfig == null) {
            return null;
        }

        Map aliasedDiscoveryConfigAsMap = new LinkedHashMap<>();

        addNonNullToMap(aliasedDiscoveryConfigAsMap, "enabled", aliasedDiscoveryConfig.isEnabled());
        addNonNullToMap(aliasedDiscoveryConfigAsMap, "use-public-ip", aliasedDiscoveryConfig.isUsePublicIp());
        for (String key : aliasedDiscoveryConfig.getProperties().keySet()) {
            addNonNullToMap(aliasedDiscoveryConfigAsMap, key, aliasedDiscoveryConfig.getProperties().get(key));
        }

        return aliasedDiscoveryConfigAsMap;
    }

    private static Map getDiscoveryConfigAsMap(DiscoveryConfig discoveryConfig) {
        if (discoveryConfig == null) {
            return null;
        }

        Map discoveryConfigAsMap = new LinkedHashMap<>();

        addNonNullToMap(discoveryConfigAsMap, "node-filter",
                wrapObjectWithMap("class",
                        classNameOrImplClass(discoveryConfig.getNodeFilterClass(), discoveryConfig.getNodeFilter())));

        List> discoveryStrategyConfigsAsList = new LinkedList<>();
        for (DiscoveryStrategyConfig discoveryStrategyConfig : discoveryConfig.getDiscoveryStrategyConfigs()) {
            Map discoveryStrategyConfigAsMap = new LinkedHashMap<>();

            addNonNullToMap(discoveryStrategyConfigAsMap, "enabled", "true");
            addNonNullToMap(discoveryStrategyConfigAsMap, "class",
                    classNameOrImplClass(discoveryStrategyConfig.getClassName(),
                            discoveryStrategyConfig.getDiscoveryStrategyFactory()));
            addNonNullToMap(discoveryStrategyConfigAsMap, "properties",
                    getPropertiesAsMap(discoveryStrategyConfig.getProperties()));

            discoveryStrategyConfigsAsList.add(discoveryStrategyConfigAsMap);
        }

        addNonNullToMap(discoveryConfigAsMap, "discovery-strategies", discoveryStrategyConfigsAsList);

        return discoveryConfigAsMap;
    }

    private static Map getTieredStoreConfigAsMap(TieredStoreConfig tieredStoreConfig) {
        if (tieredStoreConfig == null) {
            return null;
        }
        Map tieredStoreConfigAsMap = new LinkedHashMap<>();
        addNonNullToMap(tieredStoreConfigAsMap, "enabled",
                tieredStoreConfig.isEnabled());
        addNonNullToMap(tieredStoreConfigAsMap, "memory-tier",
                getMemoryTierConfigAsMap(tieredStoreConfig.getMemoryTierConfig()));
        addNonNullToMap(tieredStoreConfigAsMap, "disk-tier",
                getDiskTierConfigAsMap(tieredStoreConfig.getDiskTierConfig()));

        return tieredStoreConfigAsMap;
    }

    private static Map getMemoryTierConfigAsMap(MemoryTierConfig memoryTierConfig) {
        if (memoryTierConfig == null) {
            return null;
        }
        Map memoryTierConfigAsMap = new LinkedHashMap<>();

        addNonNullToMap(memoryTierConfigAsMap, "capacity", getCapacityAsMap(memoryTierConfig.getCapacity()));

        return memoryTierConfigAsMap;
    }

    private static Map getCapacityAsMap(Capacity capacity) {
        if (capacity == null) {
            return null;
        }
        Map capacityAsMap = new LinkedHashMap<>();
        addNonNullToMap(capacityAsMap, "unit", capacity.getUnit().toString());
        addNonNullToMap(capacityAsMap, "value", "" + capacity.getValue());

        return capacityAsMap;
    }

    private static Map getDiskTierConfigAsMap(DiskTierConfig diskTierConfig) {
        if (diskTierConfig == null) {
            return null;
        }
        Map diskTierConfigAsMap = new LinkedHashMap<>();

        addNonNullToMap(diskTierConfigAsMap, "enabled", diskTierConfig.isEnabled());
        addNonNullToMap(diskTierConfigAsMap, "device-name", diskTierConfig.getDeviceName());

        return diskTierConfigAsMap;
    }

    private static String getPartitioningStrategyAsString(PartitioningStrategyConfig partitioningStrategyConfig) {
        if (partitioningStrategyConfig == null) {
            return null;
        }

        return classNameOrImplClass(partitioningStrategyConfig.getPartitioningStrategyClass(),
                partitioningStrategyConfig.getPartitioningStrategy());
    }

    private static List> getPartitioningAttributesAsList(List attributeConfigs) {
        if (attributeConfigs == null || attributeConfigs.isEmpty()) {
            return null;
        }

        return attributeConfigs.stream()
                .map(DynamicConfigYamlGenerator::getPartitionAttributeAsMap)
                .collect(Collectors.toList());
    }

    private static Map getPartitionAttributeAsMap(PartitioningAttributeConfig config) {
        final Map configAsMap = new LinkedHashMap<>();
        configAsMap.put("name", config.getAttributeName());
        return configAsMap;
    }

    private static Map getPredicateConfigAsMap(PredicateConfig predicateConfig) {
        if (predicateConfig == null) {
            return null;
        }

        Map predicateConfigAsMap = new LinkedHashMap<>();

        String type = predicateConfig.getClassName() != null
                ? "class-name"
                : "sql";

        String content = predicateConfig.getClassName() != null
                ? predicateConfig.getClassName()
                : predicateConfig.getSql();

        addNonNullToMap(predicateConfigAsMap, type, content);

        return predicateConfigAsMap;
    }

    private static Map getQueryCacheConfigsAsMap(List queryCacheConfigs) {
        if (queryCacheConfigs == null || queryCacheConfigs.isEmpty()) {
            return null;
        }

        Map queryCacheConfigsAsMap = new LinkedHashMap<>();
        for (QueryCacheConfig queryCacheConfig : queryCacheConfigs) {
            Map queryCacheConfigAsMap = new LinkedHashMap<>();
            addNonNullToMap(queryCacheConfigAsMap, "include-value",
                    queryCacheConfig.isIncludeValue());
            addNonNullToMap(queryCacheConfigAsMap, "in-memory-format",
                    queryCacheConfig.getInMemoryFormat().name());
            addNonNullToMap(queryCacheConfigAsMap, "populate",
                    queryCacheConfig.isPopulate());
            addNonNullToMap(queryCacheConfigAsMap, "coalesce",
                    queryCacheConfig.isCoalesce());
            addNonNullToMap(queryCacheConfigAsMap, "delay-seconds",
                    queryCacheConfig.getDelaySeconds());
            addNonNullToMap(queryCacheConfigAsMap, "batch-size",
                    queryCacheConfig.getBatchSize());
            addNonNullToMap(queryCacheConfigAsMap, "buffer-size",
                    queryCacheConfig.getBufferSize());
            addNonNullToMap(queryCacheConfigAsMap, "eviction",
                    getEvictionConfigAsMap(queryCacheConfig.getEvictionConfig()));
            addNonNullToMap(queryCacheConfigAsMap, "indexes",
                    getIndexConfigsAsList(queryCacheConfig.getIndexConfigs()));
            addNonNullToMap(queryCacheConfigAsMap, "predicate",
                    getPredicateConfigAsMap(queryCacheConfig.getPredicateConfig()));
            addNonNullToMap(queryCacheConfigAsMap, "entry-listeners",
                    getEntryListenerConfigsAsList(queryCacheConfig.getEntryListenerConfigs()));
            addNonNullToMap(queryCacheConfigAsMap, "serialize-keys",
                    queryCacheConfig.isSerializeKeys());

            queryCacheConfigsAsMap.put(queryCacheConfig.getName(), queryCacheConfigAsMap);
        }

        return queryCacheConfigsAsMap;
    }

    private static Map getAttributeConfigsAsMap(List attributeConfigs) {
        if (attributeConfigs == null || attributeConfigs.isEmpty()) {
            return null;
        }

        Map attributeConfigsAsMap = new LinkedHashMap<>();
        for (AttributeConfig attributeConfig : attributeConfigs) {
            addNonNullToMap(attributeConfigsAsMap, attributeConfig.getName(),
                    wrapObjectWithMap("extractor-class-name", attributeConfig.getExtractorClassName()));
        }

        return attributeConfigsAsMap;
    }

    private static List> getIndexConfigsAsList(List indexConfigs) {
        if (indexConfigs == null || indexConfigs.isEmpty()) {
            return null;
        }

        List> indexConfigsAsList = new LinkedList<>();
        for (IndexConfig indexConfig : indexConfigs) {
            Map indexConfigAsMap = new LinkedHashMap<>();

            addNonNullToMap(indexConfigAsMap, "name", indexConfig.getName());
            addNonNullToMap(indexConfigAsMap, "type", indexConfig.getType().name());
            addNonNullToMap(indexConfigAsMap, "attributes", indexConfig.getAttributes());

            if (indexConfig.getType() == IndexType.BITMAP) {
                Map bitmapIndexOptionsAsMap = new LinkedHashMap<>();
                addNonNullToMap(bitmapIndexOptionsAsMap, "unique-key",
                        indexConfig.getBitmapIndexOptions().getUniqueKey());
                addNonNullToMap(bitmapIndexOptionsAsMap, "unique-key-transformation",
                        indexConfig.getBitmapIndexOptions().getUniqueKeyTransformation().name());

                indexConfigAsMap.put("bitmap-index-options", bitmapIndexOptionsAsMap);
            } else if (indexConfig.getType() == IndexType.SORTED) {
                BTreeIndexConfig bTreeConf = indexConfig.getBTreeIndexConfig();
                Map btreeOptionsAsMap = new LinkedHashMap<>();
                addNonNullToMap(btreeOptionsAsMap, "page-size", getCapacityAsMap(bTreeConf.getPageSize()));

                Map memoryTierAsMap = new LinkedHashMap<>();
                addNonNullToMap(memoryTierAsMap, "capacity", getCapacityAsMap(bTreeConf.getMemoryTierConfig().getCapacity()));

                addNonNullToMap(btreeOptionsAsMap, "memory-tier", memoryTierAsMap);
                indexConfigAsMap.put("btree-index", btreeOptionsAsMap);
            }

            addNonNullToList(indexConfigsAsList, indexConfigAsMap);
        }

        return indexConfigsAsList;
    }

    private static Map getNearCacheConfigAsMap(NearCacheConfig nearCacheConfig) {
        if (nearCacheConfig == null) {
            return null;
        }

        Map nearCacheConfigAsMap = new LinkedHashMap<>();

        addNonNullToMap(nearCacheConfigAsMap, "name",
                nearCacheConfig.getName());
        addNonNullToMap(nearCacheConfigAsMap, "in-memory-format",
                nearCacheConfig.getInMemoryFormat().name());
        addNonNullToMap(nearCacheConfigAsMap, "invalidate-on-change",
                nearCacheConfig.isInvalidateOnChange());
        addNonNullToMap(nearCacheConfigAsMap, "time-to-live-seconds",
                nearCacheConfig.getTimeToLiveSeconds());
        addNonNullToMap(nearCacheConfigAsMap, "max-idle-seconds",
                nearCacheConfig.getMaxIdleSeconds());
        addNonNullToMap(nearCacheConfigAsMap, "serialize-keys",
                nearCacheConfig.isSerializeKeys());
        addNonNullToMap(nearCacheConfigAsMap, "cache-local-entries",
                nearCacheConfig.isCacheLocalEntries());
        addNonNullToMap(nearCacheConfigAsMap, "eviction",
                getEvictionConfigAsMap(nearCacheConfig.getEvictionConfig()));

        return nearCacheConfigAsMap;
    }

    private static Map getMerkleTreeConfigAsMap(MerkleTreeConfig merkleTreeConfig) {
        if (merkleTreeConfig == null || merkleTreeConfig.getEnabled() == null) {
            return null;
        }

        Map merkleTreeConfigAsMap = new LinkedHashMap<>();

        addNonNullToMap(merkleTreeConfigAsMap, "enabled", TRUE.equals(merkleTreeConfig.getEnabled()));
        addNonNullToMap(merkleTreeConfigAsMap, "depth", merkleTreeConfig.getDepth());

        return merkleTreeConfigAsMap;
    }

    private static Map getDataPersistenceConfigAsMap(DataPersistenceConfig dataPersistenceConfig) {
        if (dataPersistenceConfig == null) {
            return null;
        }

        Map dataPersistenceConfigAsMap = new LinkedHashMap<>();

        addNonNullToMap(dataPersistenceConfigAsMap, "enabled", dataPersistenceConfig.isEnabled());
        addNonNullToMap(dataPersistenceConfigAsMap, "fsync", dataPersistenceConfig.isFsync());
        return dataPersistenceConfigAsMap;
    }

    private static Map getEventJournalConfigAsMap(EventJournalConfig eventJournalConfig) {
        if (eventJournalConfig == null) {
            return null;
        }

        Map eventJournalConfigAsMap = new LinkedHashMap<>();

        addNonNullToMap(eventJournalConfigAsMap, "enabled",
                eventJournalConfig.isEnabled());
        addNonNullToMap(eventJournalConfigAsMap, "capacity",
                eventJournalConfig.getCapacity());
        addNonNullToMap(eventJournalConfigAsMap, "time-to-live-seconds",
                eventJournalConfig.getTimeToLiveSeconds());

        return eventJournalConfigAsMap;
    }

    private static Map getWanReplicationRefAsMap(WanReplicationRef wanReplicationRef, boolean isMap) {
        if (wanReplicationRef == null) {
            return null;
        }

        Map wanReplicationRefAsMap = new LinkedHashMap<>();

        addNonNullToMap(wanReplicationRefAsMap, "merge-policy-class-name",
                wanReplicationRef.getMergePolicyClassName());
        addNonNullToMap(wanReplicationRefAsMap, "republishing-enabled",
                wanReplicationRef.isRepublishingEnabled());
        addNonNullToMap(wanReplicationRefAsMap, "filters",
                wanReplicationRef.getFilters());

        if (isMap) {
            return wrapObjectWithMap(wanReplicationRef.getName(), wanReplicationRefAsMap);
        } else {
            addNonNullToMap(wanReplicationRefAsMap, "name", wanReplicationRef.getName());
            return wanReplicationRefAsMap;
        }
    }

    private static Map getEvictionConfigAsMap(EvictionConfig evictionConfig) {
        if (evictionConfig == null) {
            return null;
        }

        Map evictionConfigAsMap = new LinkedHashMap<>();

        String comparatorClassName = !isNullOrEmpty(evictionConfig.getComparatorClassName())
                ? evictionConfig.getComparatorClassName()
                : null;

        addNonNullToMap(evictionConfigAsMap, "size", evictionConfig.getSize());
        addNonNullToMap(evictionConfigAsMap, "max-size-policy", evictionConfig.getMaxSizePolicy().name());
        addNonNullToMap(evictionConfigAsMap, "eviction-policy", evictionConfig.getEvictionPolicy().name());
        addNonNullToMap(evictionConfigAsMap, "comparator-class-name", comparatorClassName);

        return evictionConfigAsMap;

    }

    private static List> getCacheSimpleEntryListenerConfigsAsList(
            List cacheSimpleEntryListenerConfigs
    ) {
        if (cacheSimpleEntryListenerConfigs == null || cacheSimpleEntryListenerConfigs.isEmpty()) {
            return null;
        }

        List> cacheSimpleEntryListenerConfigsAsList = new LinkedList<>();

        for (CacheSimpleEntryListenerConfig cacheSimpleEntryListenerConfig : cacheSimpleEntryListenerConfigs) {
            Map cacheSimpleEntryListenerConfigsAsMap = new LinkedHashMap<>();

            addNonNullToMap(cacheSimpleEntryListenerConfigsAsMap, "old-value-required",
                    cacheSimpleEntryListenerConfig.isOldValueRequired());
            addNonNullToMap(cacheSimpleEntryListenerConfigsAsMap, "synchronous",
                    cacheSimpleEntryListenerConfig.isSynchronous());
            addNonNullToMap(cacheSimpleEntryListenerConfigsAsMap, "cache-entry-listener-factory",
                    wrapObjectWithMap("class-name", cacheSimpleEntryListenerConfig.getCacheEntryListenerFactory()));
            addNonNullToMap(cacheSimpleEntryListenerConfigsAsMap, "cache-entry-event-filter-factory",
                    wrapObjectWithMap("class-name", cacheSimpleEntryListenerConfig.getCacheEntryEventFilterFactory()));

            addNonNullToList(cacheSimpleEntryListenerConfigsAsList, cacheSimpleEntryListenerConfigsAsMap);
        }

        return cacheSimpleEntryListenerConfigsAsList;
    }

    private static Map getExpiryPolicyFactoryConfigAsMap(
            CacheSimpleConfig.ExpiryPolicyFactoryConfig expiryPolicyFactoryConfig
    ) {
        if (expiryPolicyFactoryConfig == null) {
            return null;
        }

        if (!isNullOrEmpty(expiryPolicyFactoryConfig.getClassName())) {
            return wrapObjectWithMap("class-name", expiryPolicyFactoryConfig.getClassName());
        } else {
            CacheSimpleConfig.ExpiryPolicyFactoryConfig.TimedExpiryPolicyFactoryConfig timedConfig
                    = expiryPolicyFactoryConfig.getTimedExpiryPolicyFactoryConfig();

            if (
                    timedConfig != null
                            && timedConfig.getExpiryPolicyType() != null
                            && timedConfig.getDurationConfig() != null
            ) {
                Map timedConfigAsMap = new LinkedHashMap<>();
                addNonNullToMap(timedConfigAsMap, "expiry-policy-type",
                        timedConfig.getExpiryPolicyType().name());
                addNonNullToMap(timedConfigAsMap, "duration-amount",
                        timedConfig.getDurationConfig().getDurationAmount());
                addNonNullToMap(timedConfigAsMap, "time-unit",
                        timedConfig.getDurationConfig().getTimeUnit().name());

                return wrapObjectWithMap("timed-expiry-policy-factory", timedConfigAsMap);
            }
            return null;
        }
    }

    private static Map getCollectionConfigAsMap(CollectionConfig collectionConfig) {
        if (collectionConfig == null) {
            return null;
        }

        Map subConfigAsMap = new LinkedHashMap<>();

        addNonNullToMap(subConfigAsMap, "statistics-enabled",
                collectionConfig.isStatisticsEnabled());
        addNonNullToMap(subConfigAsMap, "max-size",
                collectionConfig.getMaxSize());
        addNonNullToMap(subConfigAsMap, "backup-count",
                collectionConfig.getBackupCount());
        addNonNullToMap(subConfigAsMap, "async-backup-count",
                collectionConfig.getAsyncBackupCount());
        addNonNullToMap(subConfigAsMap, "split-brain-protection-ref",
                collectionConfig.getSplitBrainProtectionName());
        addNonNullToMap(subConfigAsMap, "item-listeners",
                getItemListenerConfigsAsList(collectionConfig.getItemListenerConfigs()));
        addNonNullToMap(subConfigAsMap, "merge-policy",
                getMergePolicyConfigAsMap(collectionConfig.getMergePolicyConfig()));
        addNonNullToMap(subConfigAsMap, "user-code-namespace", collectionConfig.getUserCodeNamespace());

        return subConfigAsMap;
    }

    private static List> getItemListenerConfigsAsList(
            List listenerConfigs
    ) {
        if (listenerConfigs == null || listenerConfigs.isEmpty()) {
            return null;
        }

        List> listenerConfigsAsList = new LinkedList<>();

        for (ListenerConfig listenerConfig : listenerConfigs) {
            Map listenerConfigAsMap = new LinkedHashMap<>();

            addNonNullToMap(listenerConfigAsMap, "class-name",
                    classNameOrImplClass(listenerConfig.getClassName(), listenerConfig.getImplementation()));
            addNonNullToMap(listenerConfigAsMap, "include-value",
                    listenerConfig.isIncludeValue());

            addNonNullToList(listenerConfigsAsList, listenerConfigAsMap);
        }

        return listenerConfigsAsList;
    }

    private static List> getEntryListenerConfigsAsList(List listenerConfigs) {
        if (listenerConfigs == null || listenerConfigs.isEmpty()) {
            return null;
        }

        List> listenerConfigsAsList = new LinkedList<>();
        for (ListenerConfig listenerConfig : listenerConfigs) {
            Map listenerConfigAsMap = new LinkedHashMap<>();

            addNonNullToMap(listenerConfigAsMap, "class-name",
                    classNameOrImplClass(listenerConfig.getClassName(), listenerConfig.getImplementation()));
            addNonNullToMap(listenerConfigAsMap, "include-value",
                    listenerConfig.isIncludeValue());
            addNonNullToMap(listenerConfigAsMap, "local",
                    listenerConfig.isLocal());

            addNonNullToList(listenerConfigsAsList, listenerConfigAsMap);
        }

        return listenerConfigsAsList;
    }

    private static Map getPropertiesAsMap(@SuppressWarnings("rawtypes") Map properties) {
        if (properties == null || properties.isEmpty()) {
            return null;
        }

        Map propertiesAsMap = new LinkedHashMap<>();

        for (String key : properties.keySet()) {
            addNonNullToMap(propertiesAsMap, key, properties.get(key));
        }

        return propertiesAsMap;
    }

    private static Map getPropertiesAsMap(Properties properties) {
        if (properties == null || properties.isEmpty()) {
            return null;
        }

        Map propertiesAsMap = new LinkedHashMap<>();

        for (Object key : properties.keySet()) {
            addNonNullToMap(propertiesAsMap, key.toString(), properties.getProperty(key.toString()));
        }

        return propertiesAsMap;
    }

    private static Map getStoreConfigAsMap(
            boolean enabled,
            String className,
            String factoryClassName,
            Properties properties
    ) {
        Map storeConfigAsMap = new LinkedHashMap<>();

        addNonNullToMap(storeConfigAsMap, "enabled", enabled);
        addNonNullToMap(storeConfigAsMap, "class-name", className);
        addNonNullToMap(storeConfigAsMap, "factory-class-name", factoryClassName);
        addNonNullToMap(storeConfigAsMap, "properties", getPropertiesAsMap(properties));

        return storeConfigAsMap;
    }

    private static Map getMapStoreConfigAsMap(MapStoreConfig mapStoreConfig) {
        if (mapStoreConfig == null) {
            return null;
        }

        // Note that order is different from the ConfigXmlGenerator#classNameOrImplClass().
        // Here implementation takes priority rather than classname.
        String className = mapStoreConfig.getImplementation() != null
                ? mapStoreConfig.getImplementation().getClass().getName()
                : mapStoreConfig.getClassName();
        String factoryClassName = mapStoreConfig.getFactoryImplementation() != null
                ? mapStoreConfig.getFactoryImplementation().getClass().getName()
                : mapStoreConfig.getFactoryClassName();

        Map mapStoreConfigAsMap = getStoreConfigAsMap(
                mapStoreConfig.isEnabled(),
                className,
                factoryClassName,
                mapStoreConfig.getProperties()
        );

        addNonNullToMap(mapStoreConfigAsMap, "initial-mode", mapStoreConfig.getInitialLoadMode().name());
        addNonNullToMap(mapStoreConfigAsMap, "offload", mapStoreConfig.isOffload());
        addNonNullToMap(mapStoreConfigAsMap, "write-coalescing", mapStoreConfig.isWriteCoalescing());
        addNonNullToMap(mapStoreConfigAsMap, "write-delay-seconds", mapStoreConfig.getWriteDelaySeconds());
        addNonNullToMap(mapStoreConfigAsMap, "write-batch-size", mapStoreConfig.getWriteBatchSize());

        return mapStoreConfigAsMap;
    }

    private static Map getQueueStoreConfigAsMap(QueueStoreConfig queueStoreConfig) {
        if (queueStoreConfig == null) {
            return null;
        }

        return getStoreConfigAsMap(
                queueStoreConfig.isEnabled(),
                classNameOrImplClass(
                        queueStoreConfig.getClassName(),
                        queueStoreConfig.getStoreImplementation()
                ),
                classNameOrImplClass(
                        queueStoreConfig.getFactoryClassName(),
                        queueStoreConfig.getFactoryImplementation()
                ),
                queueStoreConfig.getProperties()
        );
    }

    private static Map getRingbufferStoreConfigAsMap(RingbufferStoreConfig ringbufferStoreConfig) {
        if (ringbufferStoreConfig == null) {
            return null;
        }

        return getStoreConfigAsMap(
                ringbufferStoreConfig.isEnabled(),
                classNameOrImplClass(
                        ringbufferStoreConfig.getClassName(),
                        ringbufferStoreConfig.getStoreImplementation()
                ),
                classNameOrImplClass(
                        ringbufferStoreConfig.getFactoryClassName(),
                        ringbufferStoreConfig.getFactoryImplementation()
                ),
                ringbufferStoreConfig.getProperties()
        );
    }

    private static List getListenerConfigsAsList(List listenerConfigs) {
        if (listenerConfigs == null || listenerConfigs.isEmpty()) {
            return null;
        }

        List listenerConfigsAsList = new LinkedList<>();
        for (ListenerConfig listenerConfig : listenerConfigs) {
            addNonNullToList(listenerConfigsAsList,
                    classNameOrImplClass(listenerConfig.getClassName(), listenerConfig.getImplementation()));
        }

        return listenerConfigsAsList;
    }

    private static Map getMergePolicyConfigAsMap(MergePolicyConfig mergePolicyConfig) {
        if (mergePolicyConfig == null) {
            return null;
        }

        Map mergePolicyConfigAsMap = new LinkedHashMap<>();

        addNonNullToMap(mergePolicyConfigAsMap, "class-name", mergePolicyConfig.getPolicy());
        addNonNullToMap(mergePolicyConfigAsMap, "batch-size", mergePolicyConfig.getBatchSize());

        return mergePolicyConfigAsMap;
    }

    private static Map wrapObjectWithMap(String key, Object value) {
        if (value == null) {
            return null;
        }
        Map wrappedObject = new LinkedHashMap<>();
        wrappedObject.put(key, value);
        return wrappedObject;
    }

    private static  void addNonNullToList(List list, E element) {
        if (element != null) {
            list.add(element);
        }
    }

    private static  void addNonNullToMap(Map map, K key, V value) {
        if (value != null) {
            map.put(key, value);
        }
    }

    private static String getOrMaskValue(String value) {
        return maskSensitiveFields ? MASK_FOR_SENSITIVE_DATA : value;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy