Add CSR1Kv configs
[lispflowmapping.git] / mappingservice / implementation / src / main / java / org / opendaylight / lispflowmapping / implementation / mdsal / MappingDataListener.java
index f7a0f73691130e8ef735d9c319ead3a1153bd421..aedf49deae54bdaf2e8327e5fa837b5cf99745f6 100644 (file)
@@ -7,18 +7,33 @@
  */
 package org.opendaylight.lispflowmapping.implementation.mdsal;
 
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.List;
+import java.util.Set;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType;
 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
 import org.opendaylight.lispflowmapping.implementation.util.MSNotificationInputUtil;
+import org.opendaylight.lispflowmapping.interfaces.dao.SubKeys;
+import org.opendaylight.lispflowmapping.interfaces.dao.Subscriber;
 import org.opendaylight.lispflowmapping.interfaces.mapcache.IMappingSystem;
+import org.opendaylight.lispflowmapping.lisp.type.MappingData;
+import org.opendaylight.lispflowmapping.lisp.util.LispAddressUtil;
+import org.opendaylight.lispflowmapping.lisp.util.SourceDestKeyHelper;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.SourceDestKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.container.Eid;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.locatorrecords.LocatorRecord;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.locatorrecords.LocatorRecordBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.container.MappingRecord;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.container.MappingRecordBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.MappingChange;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.MappingDatabase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.MappingOrigin;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.db.instance.Mapping;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.db.instance.MappingBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.mapping.database.VirtualNetworkIdentifier;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
@@ -35,6 +50,7 @@ public class MappingDataListener extends AbstractDataListener<Mapping> {
     private static final Logger LOG = LoggerFactory.getLogger(MappingDataListener.class);
     private IMappingSystem mapSystem;
     private NotificationPublishService notificationPublishService;
+    private boolean isMaster = false;
 
     public MappingDataListener(DataBroker broker, IMappingSystem msmr, NotificationPublishService nps) {
         setBroker(broker);
@@ -65,8 +81,8 @@ public class MappingDataListener extends AbstractDataListener<Mapping> {
                 final Mapping mapping = mod.getDataBefore();
 
                 // Only treat mapping changes caused by Northbound, since Southbound changes are already handled
-                // before being persisted.
-                if (mapping.getOrigin() == MappingOrigin.Southbound) {
+                // before being persisted, except for cluster slaves
+                if (mapping.getOrigin() == MappingOrigin.Southbound && mapSystem.isMaster()) {
                     continue;
                 }
 
@@ -74,21 +90,18 @@ public class MappingDataListener extends AbstractDataListener<Mapping> {
                 LOG.trace("Key: {}", change.getRootPath().getRootIdentifier());
                 LOG.trace("Value: {}", mapping);
 
-                mapSystem.removeMapping(mapping.getOrigin(), mapping.getMappingRecord().getEid());
-                try {
-                    notificationPublishService.putNotification(MSNotificationInputUtil.toMappingChanged(
-                            mapping, MappingChange.Removed));
-                } catch (InterruptedException e) {
-                    LOG.warn("Notification publication interrupted!");
-                }
+                final Mapping convertedMapping = convertToBinaryIfNecessary(mapping);
+
+                mapSystem.removeMapping(convertedMapping.getOrigin(), convertedMapping.getMappingRecord().getEid());
 
             } else if (ModificationType.SUBTREE_MODIFIED == mod.getModificationType() || ModificationType.WRITE == mod
                     .getModificationType()) {
                 final Mapping mapping = mod.getDataAfter();
 
                 // Only treat mapping changes caused by Northbound, since Southbound changes are already handled
-                // before being persisted. XXX separate NB and SB to avoid ignoring SB notifications
-                if (mapping.getOrigin() == MappingOrigin.Southbound) {
+                // before being persisted, except for cluster slaves XXX separate NB and SB to avoid ignoring
+                // SB notifications
+                if (mapping.getOrigin() == MappingOrigin.Southbound && mapSystem.isMaster()) {
                     continue;
                 }
 
@@ -104,13 +117,25 @@ public class MappingDataListener extends AbstractDataListener<Mapping> {
                 LOG.trace("Key: {}", change.getRootPath().getRootIdentifier());
                 LOG.trace("Value: {}", mapping);
 
-                mapSystem.addMapping(mapping.getOrigin(), mapping.getMappingRecord().getEid(),
-                        mapping.getMappingRecord(), false);
+                final Mapping convertedMapping = convertToBinaryIfNecessary(mapping);
+                Eid convertedEid = convertedMapping.getMappingRecord().getEid();
+
+                mapSystem.addMapping(convertedMapping.getOrigin(), convertedEid,
+                        new MappingData(convertedMapping.getMappingRecord()));
+                Set<Subscriber> subscribers = (Set<Subscriber>) mapSystem.getData(MappingOrigin.Southbound,
+                        convertedEid, SubKeys.SUBSCRIBERS);
+                Set<Subscriber> dstSubscribers = null;
+                // For SrcDst LCAF also send SMRs to Dst prefix
+                if (convertedEid.getAddress() instanceof SourceDestKey) {
+                    Eid dstAddr = SourceDestKeyHelper.getDstBinary(convertedEid);
+                    dstSubscribers = (Set<Subscriber>) mapSystem.getData(MappingOrigin.Southbound,
+                            dstAddr, SubKeys.SUBSCRIBERS);
+                }
 
                 try {
                     // The notifications are used for sending SMR.
-                    notificationPublishService.putNotification(MSNotificationInputUtil.toMappingChanged(mapping,
-                            mappingChange));
+                    notificationPublishService.putNotification(MSNotificationInputUtil.toMappingChanged(
+                            convertedMapping, subscribers, dstSubscribers, mappingChange));
                 } catch (InterruptedException e) {
                     LOG.warn("Notification publication interrupted!");
                 }
@@ -120,4 +145,44 @@ public class MappingDataListener extends AbstractDataListener<Mapping> {
             }
         }
     }
+
+    private static Mapping convertToBinaryIfNecessary(Mapping mapping) {
+        MappingRecord originalRecord = mapping.getMappingRecord();
+        List<LocatorRecord> originalLocators = originalRecord.getLocatorRecord();
+
+        List<LocatorRecord> convertedLocators = null;
+        if (originalLocators != null) {
+            // If convertedLocators is non-null, while originalLocators is also non-null, conversion has been made
+            convertedLocators = convertToBinaryIfNecessary(originalLocators);
+        }
+
+        if (LispAddressUtil.addressNeedsConversionToBinary(originalRecord.getEid().getAddress())
+                || (originalLocators != null && convertedLocators != null)) {
+            MappingRecordBuilder mrb = new MappingRecordBuilder(originalRecord);
+            mrb.setEid(LispAddressUtil.convertToBinary(originalRecord.getEid()));
+            if (convertedLocators != null) {
+                mrb.setLocatorRecord(convertedLocators);
+            }
+            return new MappingBuilder(mapping).setMappingRecord(mrb.build()).build();
+        }
+        return mapping;
+    }
+
+    private static List<LocatorRecord> convertToBinaryIfNecessary(List<LocatorRecord> originalLocators) {
+        List<LocatorRecord> convertedLocators = null;
+        for (LocatorRecord record : originalLocators) {
+            if (LispAddressUtil.addressNeedsConversionToBinary(record.getRloc().getAddress())) {
+                LocatorRecordBuilder lrb = new LocatorRecordBuilder(record);
+                lrb.setRloc(LispAddressUtil.convertToBinary(record.getRloc()));
+                if (convertedLocators == null) {
+                    convertedLocators = new ArrayList<LocatorRecord>();
+                }
+                convertedLocators.add(lrb.build());
+            }
+        }
+        if (convertedLocators != null) {
+            return convertedLocators;
+        }
+        return originalLocators;
+    }
 }