Add missing list keys where necessary
[lispflowmapping.git] / mappingservice / lisp-proto / src / main / java / org / opendaylight / lispflowmapping / lisp / serializer / MapRegisterSerializer.java
index 83b3d4e5927eaa77af32cbe83e3bdf1f50015d72..cac0bbd6fb778b7be0e914563356814642f6fe17 100644 (file)
@@ -7,23 +7,29 @@
  */
 package org.opendaylight.lispflowmapping.lisp.serializer;
 
+import java.net.InetAddress;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
-
+import java.util.List;
 import org.apache.commons.lang3.BooleanUtils;
 import org.opendaylight.lispflowmapping.lisp.serializer.exception.LispSerializationException;
-import org.opendaylight.lispflowmapping.lisp.type.LispMessageEnum;
 import org.opendaylight.lispflowmapping.lisp.util.ByteUtil;
+import org.opendaylight.lispflowmapping.lisp.util.LispAddressUtil;
 import org.opendaylight.lispflowmapping.lisp.util.NumberUtil;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapRegister;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eidtolocatorrecords.EidToLocatorRecord;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eidtolocatorrecords.EidToLocatorRecordBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MessageType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.SiteId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.XtrId;
+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.lisp.proto.rev151105.mapping.record.list.MappingRecordItem;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.list.MappingRecordItemBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.list.MappingRecordItemKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapregisternotification.MapRegisterBuilder;
 
 /**
  * This class deals with deserializing map register from udp to the java object.
  */
-public class MapRegisterSerializer {
+public final class MapRegisterSerializer {
 
     private static final MapRegisterSerializer INSTANCE = new MapRegisterSerializer();
 
@@ -43,17 +49,19 @@ public class MapRegisterSerializer {
         if (mapRegister.isXtrSiteIdPresent() != null && mapRegister.isXtrSiteIdPresent()) {
             size += Length.XTRID_SIZE + Length.SITEID_SIZE;
         }
-        for (EidToLocatorRecord eidToLocatorRecord : mapRegister.getEidToLocatorRecord()) {
-            size += EidToLocatorRecordSerializer.getInstance().getSerializationSize(eidToLocatorRecord);
+        for (MappingRecordItem eidToLocatorRecord : mapRegister.getMappingRecordItem()) {
+            size += MappingRecordSerializer.getInstance().getSerializationSize(eidToLocatorRecord.getMappingRecord());
         }
 
         ByteBuffer registerBuffer = ByteBuffer.allocate(size);
-        registerBuffer.put((byte) ((byte) (LispMessageEnum.MapRegister.getValue() << 4) |
-                ByteUtil.boolToBit(BooleanUtils.isTrue(mapRegister.isProxyMapReply()), Flags.PROXY) |
-                ByteUtil.boolToBit(BooleanUtils.isTrue(mapRegister.isXtrSiteIdPresent()), Flags.XTRSITEID)));
+        registerBuffer.put((byte) ((byte) (MessageType.MapRegister.getIntValue() << 4)
+                | ByteUtil.boolToBit(BooleanUtils.isTrue(mapRegister.isProxyMapReply()), Flags.PROXY)
+                ByteUtil.boolToBit(BooleanUtils.isTrue(mapRegister.isXtrSiteIdPresent()), Flags.XTRSITEID)));
         registerBuffer.position(registerBuffer.position() + Length.RES);
-        registerBuffer.put(ByteUtil.boolToBit(BooleanUtils.isTrue(mapRegister.isWantMapNotify()), Flags.WANT_MAP_REPLY));
-        registerBuffer.put((byte) mapRegister.getEidToLocatorRecord().size());
+        registerBuffer.put((byte)
+                (ByteUtil.boolToBit(BooleanUtils.isTrue(mapRegister.isMergeEnabled()), Flags.MERGE_ENABLED)
+                | ByteUtil.boolToBit(BooleanUtils.isTrue(mapRegister.isWantMapNotify()), Flags.WANT_MAP_NOTIFY)));
+        registerBuffer.put((byte) mapRegister.getMappingRecordItem().size());
         registerBuffer.putLong(NumberUtil.asLong(mapRegister.getNonce()));
         registerBuffer.putShort(NumberUtil.asShort(mapRegister.getKeyId()));
 
@@ -63,30 +71,38 @@ public class MapRegisterSerializer {
         } else {
             registerBuffer.putShort((short) 0);
         }
-        for (EidToLocatorRecord eidToLocatorRecord : mapRegister.getEidToLocatorRecord()) {
-            EidToLocatorRecordSerializer.getInstance().serialize(registerBuffer, eidToLocatorRecord);
+        for (MappingRecordItem eidToLocatorRecord : mapRegister.getMappingRecordItem()) {
+            MappingRecordSerializer.getInstance().serialize(registerBuffer, eidToLocatorRecord.getMappingRecord());
         }
 
         if (mapRegister.isXtrSiteIdPresent() != null && mapRegister.isXtrSiteIdPresent()) {
-            registerBuffer.put(mapRegister.getXtrId());
-            registerBuffer.put(mapRegister.getSiteId());
+            registerBuffer.put(mapRegister.getXtrId().getValue());
+            registerBuffer.put(mapRegister.getSiteId().getValue());
         }
         registerBuffer.clear();
         return registerBuffer;
     }
 
-    public MapRegister deserialize(ByteBuffer registerBuffer) {
+    @SuppressWarnings("checkstyle:IllegalCatch")
+    public MapRegister deserialize(ByteBuffer registerBuffer, InetAddress sourceRloc) {
         try {
+            final byte typeAndFlags = registerBuffer.get();
+            final int type = typeAndFlags >> 4;
+            if (MessageType.forValue(type) != MessageType.MapRegister) {
+                throw new LispSerializationException("Expected Map-Register packet (type 3), but was type " + type);
+            }
+
             MapRegisterBuilder builder = new MapRegisterBuilder();
-            builder.setEidToLocatorRecord(new ArrayList<EidToLocatorRecord>());
+            builder.setMappingRecordItem(new ArrayList<MappingRecordItem>());
 
-            byte typeAndFlags = registerBuffer.get();
             boolean xtrSiteIdPresent = ByteUtil.extractBit(typeAndFlags, Flags.XTRSITEID);
             builder.setProxyMapReply(ByteUtil.extractBit(typeAndFlags, Flags.PROXY));
             builder.setXtrSiteIdPresent(xtrSiteIdPresent);
 
             registerBuffer.position(registerBuffer.position() + Length.RES);
-            builder.setWantMapNotify(ByteUtil.extractBit(registerBuffer.get(), Flags.WANT_MAP_REPLY));
+            byte mergeAndMapReply = registerBuffer.get();
+            builder.setWantMapNotify(ByteUtil.extractBit(mergeAndMapReply, Flags.WANT_MAP_NOTIFY));
+            builder.setMergeEnabled(ByteUtil.extractBit(mergeAndMapReply, Flags.MERGE_ENABLED));
             byte recordCount = (byte) ByteUtil.getUnsignedByte(registerBuffer);
             builder.setNonce(registerBuffer.getLong());
             builder.setKeyId(registerBuffer.getShort());
@@ -95,34 +111,54 @@ public class MapRegisterSerializer {
             registerBuffer.get(authenticationData);
             builder.setAuthenticationData(authenticationData);
 
-            for (int i = 0; i < recordCount; i++) {
-                builder.getEidToLocatorRecord().add(
-                        new EidToLocatorRecordBuilder(EidToLocatorRecordSerializer.getInstance().deserialize(registerBuffer)).build());
-            }
-
             if (xtrSiteIdPresent) {
-                byte[] xtrId  = new byte[Length.XTRID_SIZE];
-                registerBuffer.get(xtrId);
-                byte[] siteId = new byte[Length.SITEID_SIZE];
-                registerBuffer.get(siteId);
+                List<MappingRecordBuilder> mrbs = new ArrayList<MappingRecordBuilder>();
+                for (int i = 0; i < recordCount; i++) {
+                    mrbs.add(MappingRecordSerializer.getInstance().deserializeToBuilder(registerBuffer));
+                }
+                byte[] xtrIdBuf  = new byte[Length.XTRID_SIZE];
+                registerBuffer.get(xtrIdBuf);
+                XtrId xtrId = new XtrId(xtrIdBuf);
+                byte[] siteIdBuf = new byte[Length.SITEID_SIZE];
+                registerBuffer.get(siteIdBuf);
+                SiteId siteId = new SiteId(siteIdBuf);
                 builder.setXtrId(xtrId);
                 builder.setSiteId(siteId);
+                int idx = 0;
+                for (MappingRecordBuilder mrb : mrbs) {
+                    mrb.setXtrId(xtrId);
+                    mrb.setSiteId(siteId);
+                    mrb.setSourceRloc(LispAddressUtil.addressBinaryFromInet(sourceRloc));
+                    builder.getMappingRecordItem().add(new MappingRecordItemBuilder()
+                            .withKey(new MappingRecordItemKey(Integer.toString(idx)))
+                            .setMappingRecord(mrb.build()).build());
+                    idx++;
+                }
+            } else {
+                for (int i = 0; i < recordCount; i++) {
+                    builder.getMappingRecordItem().add(new MappingRecordItemBuilder()
+                            .withKey(new MappingRecordItemKey(Integer.toString(i)))
+                            .setMappingRecord(MappingRecordSerializer.getInstance().deserialize(registerBuffer))
+                            .build());
+                }
             }
+
             registerBuffer.limit(registerBuffer.position());
             byte[] mapRegisterBytes = new byte[registerBuffer.position()];
             registerBuffer.position(0);
             registerBuffer.get(mapRegisterBytes);
             return builder.build();
         } catch (RuntimeException re) {
-            throw new LispSerializationException("Couldn't deserialize Map-Register (len=" + registerBuffer.capacity() + ")", re);
+            throw new LispSerializationException("Couldn't deserialize Map-Register (len="
+                    + registerBuffer.capacity() + ")", re);
         }
-
     }
 
     private interface Flags {
         byte PROXY = 0x08;
         byte XTRSITEID = 0x02;
-        byte WANT_MAP_REPLY = 0x01;
+        byte MERGE_ENABLED = 0x04;
+        byte WANT_MAP_NOTIFY = 0x01;
     }
 
     public interface Length {