package at.gv.egiz.moazs.preprocess; import at.gv.zustellung.app2mzs.xsd.ConfigType; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.*; import org.springframework.stereotype.Component; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.stream.Stream; import java.util.stream.StreamSupport; import static at.gv.zustellung.app2mzs.xsd.ConfigType.configTypeBuilder; import static at.gv.zustellung.app2mzs.xsd.ServerType.serverTypeBuilder; import static java.util.stream.Collectors.*; import static java.util.stream.Collectors.toMap; @Component public class ConfigProfileGenerator { private static final String PROFILE_PREFIX = "delivery-request-configuration-profiles."; private static final String TNVZ_REQUEST_KEY = "perform-query-person-request"; private static final String MSG_URL_KEY = "msg.url"; private final ConfigurableEnvironment env; private final ConfigProfileMerger merger; @Autowired public ConfigProfileGenerator(ConfigurableEnvironment env, ConfigProfileMerger merger) { this.env = env; this.merger = merger; } public Map generate() { var groupedKeys = getStreamOfPropertyKeysFromEnv() .filter(this::isConfigurationProfileProperty) .map(this::removePrefix) .collect(groupingBy(this::keepPrefix, mapping(this::removePrefix, toSet()))); var profiles = groupedKeys.entrySet().stream() .collect(toMap(Entry::getKey, this::createConfigFromEnv)); var defaultProfile = profiles.get("default"); return mergeProfiles(profiles, defaultProfile); } // @author pedorro // inspired by https://stackoverflow.com/questions/23506471/spring-access-all-environment-properties-as-a-map-or-properties-object/42521523#42521523 private Stream getStreamOfPropertyKeysFromEnv() { MutablePropertySources propSrcs = env.getPropertySources(); return StreamSupport.stream(propSrcs.spliterator(), false) .filter(ps -> ps instanceof EnumerablePropertySource) .map(ps -> ((EnumerablePropertySource) ps).getPropertyNames()) .flatMap(Arrays::stream); } private boolean isConfigurationProfileProperty(String propName) { return propName.startsWith(PROFILE_PREFIX); } private String keepPrefix(String name) { return name.substring(0, name.indexOf('.')); } private String removePrefix(String name) { return name.substring(name.indexOf('.') + 1); } private ConfigType createConfigFromEnv(Entry> entry) { var profile = entry.getKey(); var values = new HashMap(); entry.getValue().stream() .forEach(key -> { var assembledKey = PROFILE_PREFIX + '.' + profile + '.' + key; var value = env.getProperty(assembledKey); values.put(key, value); }); var server = serverTypeBuilder() .withZUSEUrlID(values.get(MSG_URL_KEY)) .build(); Boolean performQueryPersonRequest = values.get(TNVZ_REQUEST_KEY) == null ? null : Boolean.getBoolean(values.get(TNVZ_REQUEST_KEY)); return configTypeBuilder() .withPerformQueryPersonRequest(performQueryPersonRequest) .withServer(server) .build(); } private Map mergeProfiles(Map profiles, ConfigType defaultProfile) { return profiles.entrySet().stream() .collect(toUnmodifiableMap( Entry::getKey, e -> merger.merge(e.getValue(), defaultProfile))); } }