Add missing list keys where necessary
[lispflowmapping.git] / mappingservice / lisp-proto / src / main / java / org / opendaylight / lispflowmapping / lisp / serializer / MapNotifySerializer.java
index 80fbfb8e9c9c6d5abe23ce84328ad410fa093ceb..4a7cb30087a364350750acab9b98ab6cc90d68fc 100644 (file)
@@ -9,20 +9,25 @@ package org.opendaylight.lispflowmapping.lisp.serializer;
 
 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.NumberUtil;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapNotify;
+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.mapnotifymessage.MapNotifyBuilder;
+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;
 
 /**
  * This class deals with serializing map notify from the java object to udp.
  */
-public class MapNotifySerializer {
+public final class MapNotifySerializer {
 
     private static final MapNotifySerializer INSTANCE = new MapNotifySerializer();
 
@@ -40,16 +45,18 @@ public class MapNotifySerializer {
             size += mapNotify.getAuthenticationData().length;
         }
         if (mapNotify.isXtrSiteIdPresent() != null && mapNotify.isXtrSiteIdPresent()) {
-            size += org.opendaylight.lispflowmapping.lisp.serializer.MapRegisterSerializer.Length.XTRID_SIZE +
-                    org.opendaylight.lispflowmapping.lisp.serializer.MapRegisterSerializer.Length.SITEID_SIZE;
+            size += org.opendaylight.lispflowmapping.lisp.serializer.MapRegisterSerializer.Length.XTRID_SIZE
+                  + org.opendaylight.lispflowmapping.lisp.serializer.MapRegisterSerializer.Length.SITEID_SIZE;
         }
         for (MappingRecordItem mappingRecord : mapNotify.getMappingRecordItem()) {
             size += MappingRecordSerializer.getInstance().getSerializationSize(mappingRecord.getMappingRecord());
         }
 
         ByteBuffer replyBuffer = ByteBuffer.allocate(size);
-        replyBuffer.put((byte) (LispMessageEnum.MapNotify.getValue() << 4));
+        replyBuffer.put((byte) ((byte) (MessageType.MapNotify.getIntValue() << 4)
+                | ByteUtil.boolToBit(BooleanUtils.isTrue(mapNotify.isXtrSiteIdPresent()), Flags.XTRSITEID)));
         replyBuffer.position(replyBuffer.position() + Length.RES);
+        replyBuffer.put(ByteUtil.boolToBit(BooleanUtils.isTrue(mapNotify.isMergeEnabled()), Flags.MERGE_ENABLED));
         if (mapNotify.getMappingRecordItem() != null) {
             replyBuffer.put((byte) mapNotify.getMappingRecordItem().size());
         } else {
@@ -71,22 +78,30 @@ public class MapNotifySerializer {
         }
 
         if (mapNotify.isXtrSiteIdPresent() != null && mapNotify.isXtrSiteIdPresent()) {
-            replyBuffer.put(mapNotify.getXtrId());
-            replyBuffer.put(mapNotify.getSiteId());
+            replyBuffer.put(mapNotify.getXtrId().getValue());
+            replyBuffer.put(mapNotify.getSiteId().getValue());
         }
         replyBuffer.clear();
         return replyBuffer;
     }
 
+    @SuppressWarnings("checkstyle:IllegalCatch")
     public MapNotify deserialize(ByteBuffer notifyBuffer) {
         try {
+            final byte typeAndFlags = notifyBuffer.get();
+            final int type = typeAndFlags >> 4;
+            if (MessageType.forValue(type) != MessageType.MapNotify) {
+                throw new LispSerializationException("Expected Map-Notify packet (type 4), but was type " + type);
+            }
+
             MapNotifyBuilder builder = new MapNotifyBuilder();
+            builder.setMappingRecordItem(new ArrayList<MappingRecordItem>());
 
-            byte typeAndFlags = notifyBuffer.get();
             boolean xtrSiteIdPresent = ByteUtil.extractBit(typeAndFlags, Flags.XTRSITEID);
             builder.setXtrSiteIdPresent(xtrSiteIdPresent);
 
             notifyBuffer.position(notifyBuffer.position() + Length.RES);
+            builder.setMergeEnabled(ByteUtil.extractBit(notifyBuffer.get(), Flags.MERGE_ENABLED));
 
             byte recordCount = (byte) ByteUtil.getUnsignedByte(notifyBuffer);
             builder.setNonce(notifyBuffer.getLong());
@@ -96,34 +111,53 @@ public class MapNotifySerializer {
             notifyBuffer.get(authenticationData);
             builder.setAuthenticationData(authenticationData);
 
-            builder.setMappingRecordItem(new ArrayList<MappingRecordItem>());
-            for (int i = 0; i < recordCount; i++) {
-                builder.getMappingRecordItem().add(new MappingRecordItemBuilder().setMappingRecord(
-                        (MappingRecordSerializer.getInstance().deserialize(notifyBuffer))).build());
-            }
-
             if (xtrSiteIdPresent) {
-                byte[] xtrId  = new byte[MapRegisterSerializer.Length.XTRID_SIZE];
-                notifyBuffer.get(xtrId);
-                byte[] siteId = new byte[MapRegisterSerializer.Length.SITEID_SIZE];
-                notifyBuffer.get(siteId);
+                List<MappingRecordBuilder> mrbs = new ArrayList<MappingRecordBuilder>();
+                for (int i = 0; i < recordCount; i++) {
+                    mrbs.add(MappingRecordSerializer.getInstance().deserializeToBuilder(notifyBuffer));
+                }
+                byte[] xtrIdBuf  = new byte[MapRegisterSerializer.Length.XTRID_SIZE];
+                notifyBuffer.get(xtrIdBuf);
+                XtrId xtrId = new XtrId(xtrIdBuf);
+                byte[] siteIdBuf = new byte[MapRegisterSerializer.Length.SITEID_SIZE];
+                notifyBuffer.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);
+                    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(notifyBuffer))
+                            .build());
+                }
             }
+
             notifyBuffer.limit(notifyBuffer.position());
             return builder.build();
         } catch (RuntimeException re) {
-            throw new LispSerializationException("Couldn't deserialize Map-Notify (len=" + notifyBuffer.capacity() + ")", re);
+            throw new LispSerializationException("Couldn't deserialize Map-Notify (len="
+                    + notifyBuffer.capacity() + ")", re);
         }
     }
 
     private interface Flags {
         byte XTRSITEID = 0x08;
+        byte MERGE_ENABLED = 0x04;
     }
 
     private interface Length {
         int HEADER_SIZE = 16;
-        int RES = 2;
+        int RES = 1;
     }
 
 }