You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@trafficcontrol.apache.org by GitBox <gi...@apache.org> on 2018/12/06 00:29:04 UTC

[GitHub] ajschmidt commented on a change in pull request #2785: In Traffic Router Support Snapshots which only update Delivery Services

ajschmidt commented on a change in pull request #2785: In Traffic Router Support Snapshots which only update Delivery Services
URL: https://github.com/apache/trafficcontrol/pull/2785#discussion_r239290158
 
 

 ##########
 File path: traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/config/SnapshotEventsProcessor.java
 ##########
 @@ -0,0 +1,324 @@
+/*
+ *
+ * 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.comcast.cdn.traffic_control.traffic_router.core.config;
+
+import com.comcast.cdn.traffic_control.traffic_router.core.cache.Cache;
+import com.comcast.cdn.traffic_control.traffic_router.core.cache.Cache.DeliveryServiceReference;
+import com.comcast.cdn.traffic_control.traffic_router.core.ds.DeliveryService;
+import com.comcast.cdn.traffic_control.traffic_router.core.util.JsonUtils;
+import com.comcast.cdn.traffic_control.traffic_router.core.util.JsonUtilsException;
+import com.fasterxml.jackson.databind.JsonNode;
+import org.apache.log4j.Logger;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.time.Instant;
+
+public class SnapshotEventsProcessor {
+	private static final Logger LOGGER = Logger.getLogger(SnapshotEventsProcessor.class);
+	final private Map<String, DeliveryService> creationEvents = new HashMap<>();
+	final private Map<String, DeliveryService> updateEvents = new HashMap<>();
+	final private Map<String, DeliveryService> deleteEvents = new HashMap<>();
+	final private Map<String, Cache> mappingEvents = new HashMap<>();
+	final private List<String> serverModEvents = new ArrayList<>();
+
+	public List<String> getDeleteCacheEvents() {
+		return deleteCacheEvents;
+	}
+
+	final private List<String> deleteCacheEvents = new ArrayList<>();
+	private JsonNode existingConfig = null;
+	private boolean loadall = false;
+
+	public static SnapshotEventsProcessor diffCrConfigs(final JsonNode newSnapDb,
+	                                                    final JsonNode existingDb) throws
+			JsonUtilsException, ParseException {
+		LOGGER.info("In diffCrConfigs");
+		final SnapshotEventsProcessor sepRet = new SnapshotEventsProcessor();
+
+		if (newSnapDb == null)
+		{
+			final String errstr = "Required parameter 'newSnapDb' was null";
+			LOGGER.error(errstr);
+			JsonUtils.throwException(errstr);
+		}
+		// Load the entire crConfig from the snapshot if there isn't one saved on the filesystem
+		if (existingDb == null || existingDb.size()< 1) {
+			sepRet.parseDeliveryServices(newSnapDb);
+			sepRet.loadall = true;
+			return sepRet;
+		}
+		// Load the entire crConfig from the snapshot if it is not version a version supporting
+		// DS Snapshots
+		if (!sepRet.versionSupportsDsSnapshots(newSnapDb)){
+			LOGGER.info("In diffCrConfig got old version of crConfig.");
+			sepRet.parseDeliveryServices(newSnapDb);
+			sepRet.loadall = true;
+			return sepRet;
+		}
+		// Load the entire crConfig from the snapshot if the load flag is set in the snapshot
+		final JsonNode config = JsonUtils.getJsonNode(newSnapDb, ConfigHandler.configKey);
+		if (Instant.parse(JsonUtils.optString(config, "modified", "1970-01-01T00:00:00Z")).isAfter(ConfigHandler.getLastSnapshotInstant())) {
+			sepRet.parseDeliveryServices(newSnapDb);
+			sepRet.loadall = true;
+			return sepRet;
+		}
+		// process only the changes to Delivery Services if none of the above conditions are met
+		sepRet.diffDeliveryServices(newSnapDb, existingDb);
+		sepRet.diffCacheMappings(newSnapDb, existingDb);
+		return sepRet;
+	}
+
+	private boolean versionSupportsDsSnapshots(final JsonNode snapDb) throws JsonUtilsException {
+		if (snapDb == null) {
+			return false;
+		}
+		return snapDb.has(ConfigHandler.versionKey);
+	}
+
+	private void diffCacheMappings(final JsonNode newSnapDb, final JsonNode existingDb) throws JsonUtilsException,
+			ParseException {
+		setExistingConfig(JsonUtils.getJsonNode(existingDb, ConfigHandler.configKey));
+		final JsonNode newServers = JsonUtils.getJsonNode(newSnapDb, ConfigHandler.contentServersKey);
+		final Iterator<String> newServersIter = newServers.fieldNames();
+		while (newServersIter.hasNext()) {
+			final String cid = newServersIter.next();
+			final JsonNode newCacheJo = newServers.get(cid);
+			if (!newCacheJo.has(ConfigHandler.deliveryServicesKey)) {
+				continue;
+			}
+			final Iterator<String> dsrKeys =
+					JsonUtils.getJsonNode(newCacheJo, ConfigHandler.deliveryServicesKey).fieldNames();
+			while (dsrKeys.hasNext()) {
+				final String dsrId = dsrKeys.next();
+				if (serverModEvents.contains(dsrId)) {
+					addMappingEvent(newCacheJo, cid);
+				}
+			}
+			if (dssLinkChangeDetected(cid, newCacheJo, existingDb)) {
+				addMappingEvent(newCacheJo, cid);
+			}
+		}
+
+		parseDeleteCacheEvents(JsonUtils.getJsonNode(existingDb, ConfigHandler.contentServersKey), newServers);
+	}
+
+	private boolean dssLinkChangeDetected(final String cid, final JsonNode newCacheJo, final JsonNode existingDb) throws
+			JsonUtilsException {
+		if (existingDb == null)
+		{
+			return true;
+		}
+		final JsonNode existingServers = JsonUtils.getJsonNode(existingDb,ConfigHandler.contentServersKey);
+		if (!existingServers.has(cid)) {
+		    return true;
+		}
+		final JsonNode existingCache = JsonUtils.getJsonNode(existingServers,cid);
+		if (newCacheJo.has(ConfigHandler.deliveryServicesKey) && !existingCache.has(ConfigHandler.deliveryServicesKey)) {
+			return true;
+		}
+		if (newCacheJo.has(ConfigHandler.deliveryServicesKey)) {
+			final JsonNode newDsLinks = JsonUtils.getJsonNode(newCacheJo, ConfigHandler.deliveryServicesKey);
+			return !newDsLinks.equals(JsonUtils.getJsonNode(existingCache, ConfigHandler.deliveryServicesKey));
+		} else {
+			return true;
+		}
+	}
+
+	private void addMappingEvent(final JsonNode newCacheJo, final String cid) throws JsonUtilsException, ParseException {
+		if (mappingEvents.keySet().contains(cid)) {
+			return;
+		}
+		final Cache modCache = new Cache(cid, cid, 1);
+		final List<DeliveryServiceReference> dsRefs = parseDsRefs(newCacheJo);
+		if (!dsRefs.isEmpty()) {
+			modCache.setDeliveryServices(dsRefs);
+		}
+		mappingEvents.put(cid, modCache);
+	}
+
+	private void parseDeleteCacheEvents(final JsonNode exCacheServers, final JsonNode newServers) {
+		final Iterator<String> exServersIter = exCacheServers.fieldNames();
+		exServersIter.forEachRemaining(cId->{
 
 Review comment:
   In most cases there are calls within the 'while' code block which throw exceptions. When you switch the code to a closure the exceptions get trapped inside it. The only way to handle it is to add a try/catch block inside the closure and add the exception to a 'final' container you defined outside the closure and then throw the exception once you have returned from the closure. Very messy.  

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services