Bump upstreams
[lispflowmapping.git] / mappingservice / implementation / src / main / java / org / opendaylight / lispflowmapping / implementation / mdsal / MappingDataListener.java
index 84185db9ca5d0e86df0665d6717e81030e0e9272..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.common.api.data.AsyncDataChangeEvent;
-import org.opendaylight.lispflowmapping.implementation.LispMappingService;
-import org.opendaylight.lispflowmapping.implementation.config.ConfigIni;
-import org.opendaylight.lispflowmapping.lisp.util.MapServerMapResolverUtil;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev150820.MapRegister;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150820.MappingDatabase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150820.MappingOrigin;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150820.db.instance.Mapping;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150820.mapping.database.InstanceId;
-import org.opendaylight.yangtools.yang.binding.DataObject;
+import java.util.ArrayList;
+import java.util.List;
+import org.opendaylight.lispflowmapping.interfaces.mapcache.IMappingSystem;
+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.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -29,82 +35,127 @@ import org.slf4j.LoggerFactory;
  * DataListener for all Mapping modification events.
  *
  * @author Lorand Jakab
+ * @author Florin Coras
  *
  */
-public class MappingDataListener extends AbstractDataListener {
+public class MappingDataListener extends AbstractDataListener<Mapping> {
     private static final Logger LOG = LoggerFactory.getLogger(MappingDataListener.class);
-    private LispMappingService msmr;
-    private static final ConfigIni configIni = new ConfigIni();
-    private volatile boolean smr = configIni.smrIsSet();
+    private IMappingSystem mapSystem;
+    private NotificationPublishService notificationPublishService;
+    private final boolean isMaster = false;
 
-    public MappingDataListener(DataBroker broker, LispMappingService msmr) {
+    public MappingDataListener(DataBroker broker, IMappingSystem msmr, NotificationPublishService nps) {
         setBroker(broker);
-        setMsmr(msmr);
-        setPath(InstanceIdentifier.create(MappingDatabase.class).child(InstanceId.class)
+        setMappingSystem(msmr);
+        setNotificationProviderService(nps);
+        setPath(InstanceIdentifier.create(MappingDatabase.class).child(VirtualNetworkIdentifier.class)
                 .child(Mapping.class));
         LOG.trace("Registering Mapping listener.");
         registerDataChangeListener();
     }
 
+    public void setNotificationProviderService(NotificationPublishService nps) {
+        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();
 
-     // 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();
+            if (ModificationType.DELETE == mod.modificationType()) {
+                // Process deleted mappings
 
-                LOG.trace("Received created data");
-                LOG.trace("Key: {}", entry.getKey());
-                LOG.trace("Value: {}", mapping);
+                final Mapping mapping = mod.dataBefore();
 
-                if (mapping.getOrigin() != MappingOrigin.Southbound) {
-                    MapRegister register = MapServerMapResolverUtil.getMapRegister(mapping);
-                    msmr.handleMapRegister(register, smr);
-                } else {
-                    LOG.trace("Mapping is coming from the southbound plugin, already handled");
+                // Only treat mapping changes caused by Northbound, since Southbound changes are already handled
+                // before being persisted, except for cluster slaves
+                if (mapping.getOrigin() == MappingOrigin.Southbound && mapSystem.isMaster()) {
+                    continue;
                 }
-            }
-        }
 
-        // 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();
+                LOG.trace("Received deleted data");
+                LOG.trace("Key: {}", change.getRootPath().path());
+                LOG.trace("Value: {}", mapping);
+
+                final Mapping convertedMapping = convertToBinaryIfNecessary(mapping);
 
-                LOG.trace("Received changed data");
-                LOG.trace("Key: {}", entry.getKey());
-                LOG.trace("Value: {}", entry.getValue());
+                mapSystem.removeMapping(convertedMapping.getOrigin(), convertedMapping.getMappingRecord().getEid());
 
-                if (mapping.getOrigin() != MappingOrigin.Southbound) {
-                    MapRegister register = MapServerMapResolverUtil.getMapRegister(mapping);
-                    msmr.handleMapRegister(register, smr);
+            } 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, except for cluster slaves XXX separate NB and SB to avoid ignoring
+                // SB notifications
+                if (mapping.getOrigin() == MappingOrigin.Southbound && mapSystem.isMaster()) {
+                    continue;
+                }
+
+                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("Mapping is coming from the southbound plugin, already handled");
+                    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();
 
-                LOG.trace("Received deleted data");
-                LOG.trace("Key: {}", entry);
-                LOG.trace("Value: {}", dataObject);
+        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);
+        }
 
-                msmr.removeMapping(mapping.getLispAddressContainer());
+        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 setMsmr(LispMappingService msmr) {
-        this.msmr = 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;
     }
 }