Bump upstreams
[lispflowmapping.git] / mappingservice / implementation / src / main / java / org / opendaylight / lispflowmapping / implementation / mdsal / MappingDataListener.java
index ee1500c58c7b895514e239655846f536c6e93f1f..e2a0afdb1e4bf216fb1ca23a83ecc2bc8eb80498 100644 (file)
@@ -7,20 +7,26 @@
  */
 package org.opendaylight.lispflowmapping.implementation.mdsal;
 
-import java.util.Map;
-import java.util.Set;
-
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
-import org.opendaylight.lispflowmapping.implementation.util.MSNotificationInputUtil;
+import java.util.ArrayList;
+import java.util.List;
 import org.opendaylight.lispflowmapping.interfaces.mapcache.IMappingSystem;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.MappingChange;
+import org.opendaylight.lispflowmapping.lisp.type.MappingData;
+import org.opendaylight.lispflowmapping.lisp.util.LispAddressUtil;
+import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.mdsal.binding.api.DataObjectModification;
+import org.opendaylight.mdsal.binding.api.DataObjectModification.ModificationType;
+import org.opendaylight.mdsal.binding.api.DataTreeModification;
+import org.opendaylight.mdsal.binding.api.NotificationPublishService;
+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.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.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -32,10 +38,11 @@ import org.slf4j.LoggerFactory;
  * @author Florin Coras
  *
  */
-public class MappingDataListener extends AbstractDataListener {
+public class MappingDataListener extends AbstractDataListener<Mapping> {
     private static final Logger LOG = LoggerFactory.getLogger(MappingDataListener.class);
     private IMappingSystem mapSystem;
     private NotificationPublishService notificationPublishService;
+    private final boolean isMaster = false;
 
     public MappingDataListener(DataBroker broker, IMappingSystem msmr, NotificationPublishService nps) {
         setBroker(broker);
@@ -51,97 +58,104 @@ public class MappingDataListener extends AbstractDataListener {
         this.notificationPublishService = nps;
     }
 
+    void setMappingSystem(IMappingSystem msmr) {
+        this.mapSystem = msmr;
+    }
+
     @Override
-    public void onDataChanged(
-            AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+    public void onDataTreeChanged(List<DataTreeModification<Mapping>> changes) {
+        for (DataTreeModification<Mapping> change : changes) {
+            final DataObjectModification<Mapping> mod = change.getRootNode();
+
+            if (ModificationType.DELETE == mod.modificationType()) {
+                // Process deleted mappings
 
-     // Process newly created mappings
-        Map<InstanceIdentifier<?>, DataObject> createdData = change.getCreatedData();
-        for (Map.Entry<InstanceIdentifier<?>, DataObject> entry : createdData.entrySet()) {
-            if (entry.getValue() instanceof Mapping) {
-                Mapping mapping = (Mapping)entry.getValue();
+                final Mapping mapping = mod.dataBefore();
 
                 // 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
+                if (mapping.getOrigin() == MappingOrigin.Southbound && mapSystem.isMaster()) {
                     continue;
                 }
 
-                LOG.trace("Received created data");
-                LOG.trace("Key: {}", entry.getKey());
+                LOG.trace("Received deleted data");
+                LOG.trace("Key: {}", change.getRootPath().path());
                 LOG.trace("Value: {}", mapping);
 
-                mapSystem.addMapping(mapping.getOrigin(), mapping.getMappingRecord().getEid(),
-                        mapping.getMappingRecord());
+                final Mapping convertedMapping = convertToBinaryIfNecessary(mapping);
 
-                try {
-                    // The notifications are used for sending SMR.
-                    notificationPublishService.putNotification(MSNotificationInputUtil.toMappingChanged(mapping,
-                            MappingChange.Created));
-                } catch (InterruptedException e) {
-                    LOG.warn("Notification publication interrupted!");
-                }
-            }
-        }
+                mapSystem.removeMapping(convertedMapping.getOrigin(), convertedMapping.getMappingRecord().getEid());
 
-        // Process updated mappings
-        Map<InstanceIdentifier<?>, DataObject> updatedData = change.getUpdatedData();
-        for (Map.Entry<InstanceIdentifier<?>, DataObject> entry : updatedData.entrySet()) {
-            if (entry.getValue() instanceof Mapping) {
-                Mapping mapping = (Mapping)entry.getValue();
+            } else if (ModificationType.SUBTREE_MODIFIED == mod.modificationType()
+                       || ModificationType.WRITE == mod.modificationType()) {
+                final Mapping mapping = mod.dataAfter();
 
                 // 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 XXX separate NB and SB to avoid ignoring
+                // SB notifications
+                if (mapping.getOrigin() == MappingOrigin.Southbound && mapSystem.isMaster()) {
                     continue;
                 }
 
-                LOG.trace("Received changed data");
-                LOG.trace("Key: {}", entry.getKey());
-                LOG.trace("Value: {}", entry.getValue());
-
-                mapSystem.addMapping(mapping.getOrigin(), mapping.getMappingRecord().getEid(),
-                        mapping.getMappingRecord());
-
-                // The notifications are used for sending SMR.
-                try {
-                    notificationPublishService.putNotification(MSNotificationInputUtil.toMappingChanged(mapping,
-                            MappingChange.Updated));
-                } catch (InterruptedException e) {
-                    LOG.warn("Notification publication interrupted!");
+                final Mapping convertedMapping = convertToBinaryIfNecessary(mapping);
+                Eid convertedEid = convertedMapping.getMappingRecord().getEid();
+
+                if (ModificationType.SUBTREE_MODIFIED == mod.modificationType()) {
+                    LOG.trace("Received update data");
+                    LOG.trace("Key: {}", change.getRootPath().path());
+                    LOG.trace("Value: {}", mapping);
+                    mapSystem.updateMapping(convertedMapping.getOrigin(), convertedEid,
+                            new MappingData(convertedMapping.getMappingRecord()));
+                } else {
+                    LOG.trace("Received write data");
+                    LOG.trace("Key: {}", change.getRootPath().path());
+                    LOG.trace("Value: {}", mapping);
+                    mapSystem.addMapping(convertedMapping.getOrigin(), convertedEid,
+                            new MappingData(convertedMapping.getMappingRecord()));
                 }
+            } else {
+                LOG.warn("Ignoring unhandled modification type {}", mod.modificationType());
             }
         }
+    }
 
-        // Process deleted mappings
-        Set<InstanceIdentifier<?>> removedData = change.getRemovedPaths();
-        for (InstanceIdentifier<?> entry : removedData) {
-            DataObject dataObject = change.getOriginalData().get(entry);
-            if (dataObject instanceof Mapping) {
-                Mapping mapping = (Mapping)dataObject;
+    private static Mapping convertToBinaryIfNecessary(Mapping mapping) {
+        MappingRecord originalRecord = mapping.getMappingRecord();
+        List<LocatorRecord> originalLocators = originalRecord.getLocatorRecord();
 
-                // Only treat mapping changes caused by Northbound, since Southbound changes are already handled
-                // before being persisted.
-                if (mapping.getOrigin() == MappingOrigin.Southbound) {
-                    continue;
-                }
+        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);
+        }
 
-                LOG.trace("Received deleted data");
-                LOG.trace("Key: {}", entry);
-                LOG.trace("Value: {}", dataObject);
-
-                mapSystem.removeMapping(mapping.getOrigin(), mapping.getMappingRecord().getEid());
-                try {
-                    notificationPublishService.putNotification(MSNotificationInputUtil.toMappingChanged(
-                            mapping, MappingChange.Removed));
-                } catch (InterruptedException e) {
-                    LOG.warn("Notification publication interrupted!");
-                }
+        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;
     }
 
-    void setMappingSystem(IMappingSystem msmr) {
-        this.mapSystem = msmr;
+    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<>();
+                }
+                convertedLocators.add(lrb.build());
+            }
+        }
+        if (convertedLocators != null) {
+            return convertedLocators;
+        }
+        return originalLocators;
     }
 }