AppConfigMigration.java
package org.heigit.ors.api.util;
import com.typesafe.config.ConfigObject;
import org.apache.log4j.Logger;
import org.heigit.ors.api.CorsProperties;
import org.heigit.ors.api.EndpointsProperties;
import org.heigit.ors.config.AppConfig;
import org.heigit.ors.routing.RoutingProfileType;
import org.heigit.ors.util.StringUtility;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class AppConfigMigration {
private static final Logger LOGGER = Logger.getLogger(AppConfigMigration.class.getName());
public static final String SERVICE_NAME_ISOCHRONES = "isochrones";
public static final String SERVICE_NAME_FASTISOCHRONES = "fastisochrones.";
public static final String PARAM_STATISTICS_PROVIDERS = "statistics_providers.";
public static final String SERVICE_NAME_MATRIX = "matrix";
public static final String SERVICE_NAME_ROUTING = "routing";
private static final String PARAM_ENABLED = "enabled";
private static final String PARAM_ATTRIBUTION = "attribution";
private static final String PARAM_MAXIMUM_RANGE_DISTANCE = "maximum_range_distance";
private static final String PARAM_MAXIMUM_RANGE_TIME = "maximum_range_time";
private static final AppConfig config = AppConfig.getGlobal();
private AppConfigMigration() {
}
public static void loadSystemMessagesfromAppConfig(List<SystemMessage.Message> messages) {
for (ConfigObject message : config.getObjectList("system_message")) {
try {
if (message.toConfig().getBoolean("active")) {
List<SystemMessage.Condition> conditions = new ArrayList<>();
loadConditionsForMessage(message, conditions);
messages.add(new SystemMessage.Message(message.toConfig().getString("text"), conditions));
}
} catch (Exception e) {
// ignore otherwise incomplete messages entirely
LOGGER.warn("Invalid SystemMessage object in ors config %s.".formatted(message.toString().substring(18)));
}
}
}
private static void loadConditionsForMessage(ConfigObject message, List<SystemMessage.Condition> conditions) {
try {
ConfigObject condition = message.toConfig().getObject("condition");
for (String key : condition.keySet()) {
conditions.add(new SystemMessage.Condition(key, condition.toConfig().getString(key)));
}
} catch (Exception e) {
// ignore missing condition block and keep message
LOGGER.info("Invalid or missing condition in message object.");
}
}
public static CorsProperties overrideCorsProperties(CorsProperties cors) {
List<String> allowedOrigins = config.getStringList("ors.api_settings.cors.allowed.origins");
if (!allowedOrigins.isEmpty())
cors.setAllowedOriginsList(allowedOrigins);
List<String> allowedHeaders = config.getStringList("ors.api_settings.cors.allowed.headers");
if (!allowedHeaders.isEmpty())
cors.setAllowedHeadersList(allowedHeaders);
double maxAge = config.getDouble("api_settings.cors.preflight_max_age");
if (!Double.isNaN(maxAge))
cors.setPreflightMaxAge((long) maxAge);
return cors;
}
public static EndpointsProperties overrideEndpointsProperties(EndpointsProperties endpoints) {
String swaggerDocumentationUrl = config.getParameter("info", "swagger_documentation_url");
if (!StringUtility.isNullOrEmpty(swaggerDocumentationUrl))
endpoints.setSwaggerDocumentationUrl(swaggerDocumentationUrl);
// ### Isochrones ###
EndpointsProperties.EndpointIsochronesProperties isochrones = endpoints.getIsochrones();
String value = config.getServiceParameter(SERVICE_NAME_ISOCHRONES, PARAM_ENABLED);
if (value != null)
isochrones.setEnabled(Boolean.parseBoolean(value));
value = config.getServiceParameter(SERVICE_NAME_ISOCHRONES, "maximum_locations");
if (!StringUtility.isNullOrEmpty(value))
isochrones.setMaximumLocations(Integer.parseInt(value));
value = config.getServiceParameter(SERVICE_NAME_ISOCHRONES, "allow_compute_area");
if (value != null)
isochrones.setAllowComputeArea(Boolean.parseBoolean(value));
value = config.getServiceParameter(SERVICE_NAME_ISOCHRONES, "maximum_intervals");
if (value != null)
isochrones.setMaximumIntervals(Integer.parseInt(value));
value = config.getServiceParameter(SERVICE_NAME_ISOCHRONES, PARAM_ATTRIBUTION);
if (value != null)
isochrones.setAttribution(value);
value = config.getServiceParameter(SERVICE_NAME_ISOCHRONES, PARAM_MAXIMUM_RANGE_DISTANCE);
if (value != null)
isochrones.setMaximumRangeDistanceDefault(Integer.parseInt(value));
else {
List<? extends ConfigObject> params = config.getObjectList(SERVICE_NAME_ISOCHRONES, PARAM_MAXIMUM_RANGE_DISTANCE);
int def = parseProfileValues(params, isochrones.getProfileMaxRangeDistances());
if (def != -1)
isochrones.setMaximumRangeDistanceDefault(def);
}
value = config.getServiceParameter(SERVICE_NAME_ISOCHRONES, PARAM_MAXIMUM_RANGE_TIME);
if (value != null)
isochrones.setMaximumRangeTimeDefault(Integer.parseInt(value));
else {
List<? extends ConfigObject> params = config.getObjectList(SERVICE_NAME_ISOCHRONES, PARAM_MAXIMUM_RANGE_TIME);
int def = parseProfileValues(params, isochrones.getProfileMaxRangeTimes());
if (def != -1)
isochrones.setMaximumRangeTimeDefault(def);
}
EndpointsProperties.MaximumRangeProperties fastisochrones = isochrones.getFastisochrones();
value = config.getServiceParameter(SERVICE_NAME_ISOCHRONES, SERVICE_NAME_FASTISOCHRONES + PARAM_MAXIMUM_RANGE_DISTANCE);
if (value != null)
fastisochrones.setMaximumRangeDistanceDefault(Integer.parseInt(value));
else {
List<? extends ConfigObject> params = config.getObjectList(SERVICE_NAME_ISOCHRONES, SERVICE_NAME_FASTISOCHRONES + PARAM_MAXIMUM_RANGE_DISTANCE);
int def = parseProfileValues(params, fastisochrones.getProfileMaxRangeDistances());
if (def != -1)
fastisochrones.setMaximumRangeDistanceDefault(def);
}
value = config.getServiceParameter(SERVICE_NAME_ISOCHRONES, SERVICE_NAME_FASTISOCHRONES + PARAM_MAXIMUM_RANGE_TIME);
if (value != null)
fastisochrones.setMaximumRangeTimeDefault(Integer.parseInt(value));
else {
List<? extends ConfigObject> params = config.getObjectList(SERVICE_NAME_ISOCHRONES, SERVICE_NAME_FASTISOCHRONES + PARAM_MAXIMUM_RANGE_TIME);
int def = parseProfileValues(params, fastisochrones.getProfileMaxRangeTimes());
if (def != -1)
fastisochrones.setMaximumRangeTimeDefault(def);
}
Map<String, EndpointsProperties.EndpointIsochronesProperties.StatisticsProviderProperties> statisticsProviderPropertiesMap = new HashMap<>();
Map<String, Object> providers = config.getServiceParametersMap(SERVICE_NAME_ISOCHRONES, "statistics_providers", false);
if (providers != null) {
for (Map.Entry<String, Object> entry : providers.entrySet()) {
Map<String, Object> provider = config.getServiceParametersMap(SERVICE_NAME_ISOCHRONES, PARAM_STATISTICS_PROVIDERS + entry.getKey(), false);
if (provider.containsKey("provider_name") && provider.containsKey("provider_parameters") && provider.containsKey("property_mapping")) {
EndpointsProperties.EndpointIsochronesProperties.StatisticsProviderProperties statisticsProviderProperties = new EndpointsProperties.EndpointIsochronesProperties.StatisticsProviderProperties();
statisticsProviderProperties.setProviderName(provider.get("provider_name").toString());
Map<String, Object> providerParams = config.getServiceParametersMap(SERVICE_NAME_ISOCHRONES, PARAM_STATISTICS_PROVIDERS + entry.getKey() + ".provider_parameters", false);
statisticsProviderProperties.setProviderParameters(providerParams);
Map<String, Object> map = config.getServiceParametersMap(SERVICE_NAME_ISOCHRONES, PARAM_STATISTICS_PROVIDERS + entry.getKey() + ".property_mapping", false);
Map<String, String> propMapping = new HashMap<>();
for (Map.Entry<String, Object> propEntry : map.entrySet())
propMapping.put(propEntry.getKey(), propEntry.getValue().toString());
statisticsProviderProperties.setPropertyMapping(propMapping);
value = config.getServiceParameter(SERVICE_NAME_ISOCHRONES, PARAM_STATISTICS_PROVIDERS + entry.getKey() + ".enabled");
if (value != null)
statisticsProviderProperties.setEnabled(Boolean.parseBoolean(value));
value = config.getServiceParameter(SERVICE_NAME_ISOCHRONES, PARAM_STATISTICS_PROVIDERS + entry.getKey() + ".attribution");
if (value != null)
statisticsProviderProperties.setAttribution(value);
statisticsProviderPropertiesMap.put(entry.getKey(), statisticsProviderProperties);
}
}
}
isochrones.getStatisticsProviders().putAll(statisticsProviderPropertiesMap);
// ### Snap ###
EndpointsProperties.EndpointSnapProperties snap = endpoints.getSnap();
value = config.getServiceParameter("snap", "enabled");
if (value != null)
snap.setEnabled(Boolean.parseBoolean(value));
value = config.getServiceParameter("snap", "attribution");
if (value != null)
snap.setAttribution(value);
// ### Matrix ###
EndpointsProperties.EndpointMatrixProperties matrix = endpoints.getMatrix();
value = config.getServiceParameter(SERVICE_NAME_MATRIX, PARAM_ENABLED);
if (value != null)
matrix.setEnabled(Boolean.parseBoolean(value));
value = config.getServiceParameter(SERVICE_NAME_MATRIX, PARAM_ATTRIBUTION);
if (value != null)
matrix.setAttribution(value);
value = config.getServiceParameter(SERVICE_NAME_MATRIX, "maximum_search_radius");
if (value != null)
matrix.setMaximumSearchRadius(Math.max(1, Double.parseDouble(value)));
value = config.getServiceParameter(SERVICE_NAME_MATRIX, "maximum_visited_nodes");
if (value != null)
matrix.setMaximumVisitedNodes(Math.max(1, Integer.parseInt(value)));
value = config.getServiceParameter(SERVICE_NAME_MATRIX, "u_turn_cost");
if (value != null && Double.parseDouble(value) != -1.0)
matrix.setUTurnCost(Double.parseDouble(value));
value = config.getServiceParameter(SERVICE_NAME_MATRIX, "maximum_routes");
if (value != null)
matrix.setMaximumRoutes(Math.max(1, Integer.parseInt(value)));
value = config.getServiceParameter(SERVICE_NAME_MATRIX, "maximum_routes_flexible");
if (value != null)
matrix.setMaximumRoutesFlexible(Math.max(1, Integer.parseInt(value)));
// ### Routing ###
EndpointsProperties.EndpointRoutingProperties routing = endpoints.getRouting();
value = config.getServiceParameter(SERVICE_NAME_ROUTING, PARAM_ENABLED);
if (value != null)
routing.setEnabled(Boolean.parseBoolean(value));
value = config.getServiceParameter(SERVICE_NAME_ROUTING, PARAM_ATTRIBUTION);
if (value != null)
routing.setAttribution(value);
String baseUrl = config.getParameter("info", "base_url");
if (!StringUtility.isNullOrEmpty(baseUrl))
routing.setGpxBaseUrl(baseUrl);
String supportMail = config.getParameter("info", "support_mail");
if (!StringUtility.isNullOrEmpty(supportMail))
routing.setGpxSupportMail(supportMail);
String authorTag = config.getParameter("info", "author_tag");
if (!StringUtility.isNullOrEmpty(authorTag))
routing.setGpxAuthor(authorTag);
String contentLicence = config.getParameter("info", "content_licence");
if (!StringUtility.isNullOrEmpty(contentLicence))
routing.setGpxContentLicence(contentLicence);
value = config.getServiceParameter(SERVICE_NAME_ROUTING, "routing_name");
if (value != null)
routing.setGpxName(value);
value = config.getServiceParameter(SERVICE_NAME_ROUTING, "maximum_avoid_polygon_area");
if (value != null)
routing.setMaximumAvoidPolygonArea(Math.max(1, Double.parseDouble(value)));
value = config.getServiceParameter(SERVICE_NAME_ROUTING, "maximum_avoid_polygon_extent");
if (value != null)
routing.setMaximumAvoidPolygonArea(Math.max(1, Double.parseDouble(value)));
value = config.getServiceParameter(SERVICE_NAME_ROUTING, "profiles.default_params.maximum_alternative_routes");
if (value != null)
routing.setMaximumAlternativeRoutes(Math.max(1, Integer.parseInt(value)));
return endpoints;
}
private static int parseProfileValues(List<? extends ConfigObject> params, Map<Integer, Integer> map) {
int def = -1;
for (ConfigObject cfgObj : params) {
if (cfgObj.containsKey("profiles") && cfgObj.containsKey("value")) {
String[] profiles = cfgObj.toConfig().getString("profiles").split(",");
int value = cfgObj.toConfig().getInt("value");
for (String profileStr : profiles) {
profileStr = profileStr.trim();
if ("any".equalsIgnoreCase(profileStr)) {
def = value;
} else {
Integer profile = RoutingProfileType.getFromString(profileStr);
if (profile != RoutingProfileType.UNKNOWN)
map.put(profile, value);
}
}
}
}
return def;
}
}