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

com.swirlds.config.extensions.sources.MappedConfigSource Maven / Gradle / Ivy

Go to download

Swirlds is a software platform designed to build fully-distributed applications that harness the power of the cloud without servers. Now you can develop applications with fairness in decision making, speed, trust and reliability, at a fraction of the cost of traditional server-based platforms.

There is a newer version: 0.56.6
Show newest version
/*
 * Copyright (C) 2022-2024 Hedera Hashgraph, LLC
 *
 * 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.swirlds.config.extensions.sources;

import com.swirlds.config.api.source.ConfigSource;
import edu.umd.cs.findbugs.annotations.NonNull;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

/**
 * A {@link ConfigSource} that can be used as a wrapper for other config sources, providing functionality to define
 * mappings for given properties. This allows the same property value defined for one name in the wrapped
 * {@link ConfigSource} to be accessed by both names.
 * 

* For example, suppose you want to rename the "dbUrl" property to "general.databaseUrl". You can use a * {@code MappingConfigSource} to create a mapping between "dbUrl" and "general.databaseUrl", so that you can use both * names with the same value during the transition time. *

*

* Note that multiple mappings defined for a property is not allowed and will throw an {@link IllegalArgumentException} * at runtime. *

*

* Note that adding a mapping to a property not defined in the original {@link ConfigSource} will throw an * {@link IllegalArgumentException} at runtime. *

*

* Note that the ordinal of this {@code ConfigSource} is taken from the original {@link ConfigSource} that was wrapped * by this class. *

* * @see ConfigSource * @see ConfigMapping */ public class MappedConfigSource extends AbstractConfigSource { private static final String PROPERTY_NOT_FOUND = "Property '{}' not found in original config source"; private static final String PROPERTY_ALREADY_DEFINED = "Property '%s' already defined"; private static final String DUPLICATE_PROPERTY = "Property '{}' already found in original config source"; private static final String PROPERTY_ALREADY_MAPPED = "Property '%s' has already a mapping defined"; private static final Logger logger = LogManager.getLogger(MappedConfigSource.class); private final ConfigSource wrappedSource; private final Queue configMappings; private final Map properties; /** * Constructor that takes the wrapped config. * * @param wrappedSource the wrapped config */ public MappedConfigSource(@NonNull final ConfigSource wrappedSource) { this.wrappedSource = Objects.requireNonNull(wrappedSource, "wrappedSource must not be null"); configMappings = new ConcurrentLinkedQueue<>(); properties = new HashMap<>(); } /** * Adds the mappedName {@code 'mappedName'<->'originalName'}. * * @param mappedName the mappedName name * @param originalName the original name */ public void addMapping(@NonNull final String mappedName, @NonNull final String originalName) { addMapping(new ConfigMapping(mappedName, originalName)); } /** * Adds the mappedName {@code 'mappedName'<->'originalName'}. * * @param configMapping defined mapping */ public void addMapping(@NonNull final ConfigMapping configMapping) { Objects.requireNonNull(configMapping, "configMapping must not be null"); if (configMappings.stream() .map(ConfigMapping::mappedName) .anyMatch(m -> Objects.equals(m, configMapping.mappedName()))) { throw new IllegalArgumentException(PROPERTY_ALREADY_DEFINED.formatted(configMapping.mappedName())); } if (configMappings.stream() .map(ConfigMapping::originalName) .anyMatch(o -> Objects.equals(o, configMapping.originalName()))) { throw new IllegalArgumentException(PROPERTY_ALREADY_MAPPED.formatted(configMapping.originalName())); } configMappings.add(configMapping); } /** * {@inheritDoc} */ @Override @NonNull protected Map getInternalProperties() { if (properties.isEmpty()) { final Map internalProperties = wrappedSource.getProperties(); final Map mappedProperties = new HashMap<>(); configMappings.forEach(configMapping -> { if (internalProperties.containsKey(configMapping.mappedName())) { logger.warn(DUPLICATE_PROPERTY, configMapping.mappedName()); } else if (!internalProperties.containsKey(configMapping.originalName())) { logger.warn(PROPERTY_NOT_FOUND, configMapping.originalName()); } else { mappedProperties.put( configMapping.mappedName(), internalProperties.get(configMapping.originalName())); logger.debug("Added config mapping: {}", configMapping); } }); properties.putAll(internalProperties); properties.putAll(mappedProperties); } return Collections.unmodifiableMap(properties); } /** * {@inheritDoc} */ @Override public int getOrdinal() { return wrappedSource.getOrdinal(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy