package io.seldon.api.locale; import java.io.IOException; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.apache.commons.lang3.builder.ReflectionToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.fasterxml.jackson.databind.ObjectMapper; import io.seldon.api.state.ClientConfigHandler; import io.seldon.api.state.ClientConfigUpdateListener; @Component public class DimensionsMappingManager implements ClientConfigUpdateListener { private static Logger logger = Logger.getLogger(DimensionsMappingManager.class.getName()); public static class DimensionsMappingConfig { public Map<String, Object> mappings_by_locale; @Override public String toString() { return ReflectionToStringBuilder.toString(this, ToStringStyle.SHORT_PREFIX_STYLE); } } private final String DIMENSIONS_MAPPING_KEY = "dimensions_mapping"; private ObjectMapper objMapper = new ObjectMapper(); private Map<String, DimensionsMappingConfig> client_dimensions_mappings = new HashMap<>(); @Autowired public DimensionsMappingManager(ClientConfigHandler configHandler) { if (configHandler != null) { configHandler.addListener(this); } } public void updateDimensionsMappingConfig(String client, String json) { try { DimensionsMappingConfig dimensionsMappingConfig = getDimensionsMappingConfigFromJson(json); client_dimensions_mappings.put(client, dimensionsMappingConfig); logger.info(String.format("Updated client_dimensions_mappings for client[%s] value[%s]", client, dimensionsMappingConfig)); } catch (Exception e) { logger.error(String.format("Failed to update dimensions mapping using json[%s]", json), e); } } public void removeDimensionsMappingConfig(String client) { client_dimensions_mappings.remove(client); logger.info(String.format("Removed client_dimensions_mappings for client[%s]", client)); } public Set<Integer> getMappedDimensionsByLocale(String client, Set<Integer> dimensions, String locale) { logger.debug("dimensions in: "+dimensions); Set<Integer> mapped_dimensions = dimensions; DimensionsMappingConfig dimensionsMappingConfig = client_dimensions_mappings.get(client); if ((locale != null) && (dimensionsMappingConfig != null)) { Map<String, Object> mappings_for_the_locale = (Map<String, Object>) dimensionsMappingConfig.mappings_by_locale.get(locale); if (mappings_for_the_locale != null) { mapped_dimensions = new HashSet<Integer>(); for (int dimension : dimensions) { Object mapped_dimension_obj = mappings_for_the_locale.get(String.valueOf(dimension)); // @formatter:off int mapped_dimension = (mapped_dimension_obj != null) ? Integer.valueOf((String) mapped_dimension_obj) : dimension; // only map if there is an available mapping otherwise use original dimension // @formatter:on mapped_dimensions.add(mapped_dimension); } } } logger.debug("dimensions out: "+mapped_dimensions); return mapped_dimensions; } @Override public String toString() { return ReflectionToStringBuilder.toString(this, ToStringStyle.SHORT_PREFIX_STYLE); } private DimensionsMappingConfig getDimensionsMappingConfigFromJson(String json) throws IOException { DimensionsMappingConfig dmc = null; dmc = objMapper.readValue(json, DimensionsMappingConfig.class); return dmc; } @Override public void configUpdated(String client, String configKey, String configValue) { if (configKey.equals(DIMENSIONS_MAPPING_KEY)) { logger.info("Received new dimensions_mapping config for " + client + ": " + configValue); updateDimensionsMappingConfig(client, configValue); } } @Override public void configRemoved(String client, String configKey) { if (configKey.equals(DIMENSIONS_MAPPING_KEY)) { removeDimensionsMappingConfig(client); } } }