package com.netflix.suro.routing; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.inject.Inject; import com.google.inject.Singleton; import com.netflix.config.DynamicStringProperty; import com.netflix.governator.annotations.Configuration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.annotation.PostConstruct; import java.util.Map; /** * {@link com.netflix.config.DynamicProperty} driven routing map configuration. Whenever a change is made to the * dynamic property of routing rules, this module will parse the JSON and set a new configuration on the * main {@link RoutingMap}. * * @author elandau */ @Singleton public class DynamicPropertyRoutingMapConfigurator { public static final String ROUTING_MAP_PROPERTY = "SuroServer.routingMap"; private static Logger LOG = LoggerFactory.getLogger(DynamicPropertyRoutingMapConfigurator.class); private final RoutingMap routingMap; private final ObjectMapper jsonMapper; @Configuration(ROUTING_MAP_PROPERTY) private String initialRoutingMap; @Inject public DynamicPropertyRoutingMapConfigurator( RoutingMap routingMap, ObjectMapper jsonMapper) { this.routingMap = routingMap; this.jsonMapper = jsonMapper; } @PostConstruct public void init() { DynamicStringProperty routingMapFP = new DynamicStringProperty(ROUTING_MAP_PROPERTY, initialRoutingMap) { @Override protected void propertyChanged() { buildMap(get()); } }; buildMap(routingMapFP.get()); } private void buildMap(String map) { try { Map<String, RoutingMap.RoutingInfo> routes = jsonMapper.readValue( map, new TypeReference<Map<String, RoutingMap.RoutingInfo>>() {}); routingMap.set(routes); } catch (Exception e) { LOG.info("Error reading routing map from fast property: "+e.getMessage(), e); } } }