2 * Copyright (c) 2016 Cisco Systems, Inc. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.lispflowmapping.implementation.util;
10 import java.util.ArrayList;
11 import java.util.Date;
12 import java.util.LinkedHashMap;
13 import java.util.List;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.locatorrecords.LocatorRecord;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.container.MappingRecord;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.container.MappingRecordBuilder;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.rloc.container.Rloc;
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
24 * Utility class to implement merging of locator sets
26 * @author Lorand Jakab
29 public final class MappingMergeUtil {
30 protected static final Logger LOG = LoggerFactory.getLogger(MappingMergeUtil.class);
32 // Utility class, should not be instantiated
33 private MappingMergeUtil() {
36 private static void mergeCommonMappingRecordFields(MappingRecordBuilder mrb, MappingRecord record) {
37 // Set xTR-ID and site-ID from the current mapping, it help with determining the timestamp
38 mrb.setXtrId(record.getXtrId());
39 mrb.setSiteId(record.getSiteId());
40 // For the TTL value we take the minimum of all records
41 mrb.setRecordTtl(Math.min(mrb.getRecordTtl(), record.getRecordTtl()));
42 if (!mrb.getAction().equals(record.getAction())) {
43 LOG.warn("Mapping merge operation: actions are different, which one is used is undefined");
45 if (mrb.isAuthoritative() != record.isAuthoritative()) {
46 LOG.warn("Mapping merge operation: authoritative status is different, which one is used is undefined");
48 if (!mrb.getEid().equals(record.getEid())) {
49 LOG.warn("Mapping merge operation: EID records are different, which one is used is undefined");
53 private static LocatorRecord mergeLocators(LocatorRecord existingLocator, LocatorRecord newLocator) {
54 if (existingLocator.isLocalLocator()) {
55 return existingLocator;
60 private static void mergeLocatorRecords(MappingRecordBuilder mrb, MappingRecord newRecord) {
61 List<LocatorRecord> locators = mrb.getLocatorRecord();
63 // Optimization: unless we had to merge any of the locators due to differences in weights, etc, we return
64 // the original 'locators' List with any new locators added
65 boolean mergeHappened = false;
67 // We assume locators are unique and don't show up several times (with different or identical p/w/mp/mw),
68 // so we create a LinkedHashMap (which preserves order) of the locators from the existing merged record,
70 Map<Rloc, LocatorRecord> locatorMap = new LinkedHashMap<Rloc, LocatorRecord>();
71 for (LocatorRecord locator : locators) {
72 locatorMap.put(locator.getRloc(), locator);
74 for (LocatorRecord newLocator : newRecord.getLocatorRecord()) {
75 Rloc newRloc = newLocator.getRloc();
76 if (locatorMap.containsKey(newRloc)) {
77 // XXX LocatorRecord YANG generated class doesn't override equals() so I'm not sure of the behavior
78 // here, need to verify if it works as expected
79 if (locatorMap.get(newRloc).equals(newLocator)) {
82 LocatorRecord mergedLocator = mergeLocators(locatorMap.get(newRloc), newLocator);
83 locatorMap.put(newRloc, mergedLocator);
87 // We add both the LinkedHanshMap and the List, in case we can return the original list plus new
88 // elements and need not generate a new list with merged locators (which should be the most common
90 locatorMap.put(newRloc, newLocator);
91 locators.add(newLocator);
96 List<LocatorRecord> mergedLocators = new ArrayList<LocatorRecord>();
97 for (Map.Entry<Rloc, LocatorRecord> entry : locatorMap.entrySet()) {
98 mergedLocators.add(entry.getValue());
100 mrb.setLocatorRecord(mergedLocators);
102 // TODO Check if this is necessary after and .add() was called on locators
103 mrb.setLocatorRecord(locators);
107 public static MappingRecord mergeMappings(MappingRecord currentMergedMapping, MappingRecord newMapping,
108 byte[] xtrId, Date regdate) {
109 if (currentMergedMapping == null) {
113 MappingRecordBuilder mrb = new MappingRecordBuilder(currentMergedMapping);
114 mergeCommonMappingRecordFields(mrb, newMapping);
115 mergeLocatorRecords(mrb, newMapping);
119 mrb.setTimestamp(regdate.getTime());
125 public static MappingRecord mergeXtrIdMappings(List<Object> records) {
126 MappingRecordBuilder mrb = new MappingRecordBuilder((MappingRecord) records.get(0));
127 for (int i = 1; i < records.size(); i++) {
128 MappingRecord record = (MappingRecord) records.get(i);
129 mergeCommonMappingRecordFields(mrb, record);
130 mergeLocatorRecords(mrb, record);