Add unit tests for LISP control message serializer and deserializer

Change-Id: Id517db99635ad8e055d6581e5c0f3ac9f45f2869
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapNotify.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapNotify.java
index 30eba1f..14399c2 100644
--- a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapNotify.java
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapNotify.java
@@ -99,7 +99,11 @@
 
     @Override
     public byte[] getAuthenticationData() {
-        return ImmutableByteSequence.copyFrom(authenticationData).asArray();
+        if (authenticationData != null && authenticationData.length != 0) {
+            return ImmutableByteSequence.copyFrom(authenticationData).asArray();
+        } else {
+            return new byte[0];
+        }
     }
 
     @Override
@@ -132,12 +136,13 @@
                 Objects.equal(recordCount, that.recordCount) &&
                 Objects.equal(keyId, that.keyId) &&
                 Objects.equal(authDataLength, that.authDataLength) &&
-                Objects.equal(authenticationData, that.authenticationData);
+                Arrays.equals(authenticationData, that.authenticationData);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hashCode(nonce, recordCount, keyId, authDataLength, authenticationData);
+        return Objects.hashCode(nonce, recordCount, keyId, authDataLength) +
+                Arrays.hashCode(authenticationData);
     }
 
     public static final class DefaultNotifyBuilder implements NotifyBuilder {
@@ -180,18 +185,35 @@
 
         @Override
         public NotifyBuilder withAuthenticationData(byte[] authenticationData) {
-            this.authenticationData = authenticationData;
+            if (authenticationData != null) {
+                this.authenticationData = authenticationData;
+            } else {
+                this.authenticationData = new byte[0];
+            }
             return this;
         }
 
         @Override
         public NotifyBuilder withMapRecords(List<LispMapRecord> mapRecords) {
-            this.mapRecords = ImmutableList.copyOf(mapRecords);
+            if (mapRecords != null) {
+                this.mapRecords = ImmutableList.copyOf(mapRecords);
+            } else {
+                this.mapRecords = Lists.newArrayList();
+            }
             return this;
         }
 
         @Override
         public LispMapNotify build() {
+
+            if (authenticationData == null) {
+                authenticationData = new byte[0];
+            }
+
+            if (mapRecords == null) {
+                mapRecords = Lists.newArrayList();
+            }
+
             return new DefaultLispMapNotify(nonce, keyId, authDataLength,
                     authenticationData, recordCount, mapRecords);
         }
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRecord.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRecord.java
index a924c7f..f53d04d 100644
--- a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRecord.java
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRecord.java
@@ -209,12 +209,21 @@
 
         @Override
         public MapRecordBuilder withLocators(List<LispLocatorRecord> records) {
-            this.locatorRecords = ImmutableList.copyOf(records);
+            if (records != null) {
+                this.locatorRecords = ImmutableList.copyOf(records);
+            } else {
+                this.locatorRecords = Lists.newArrayList();
+            }
             return this;
         }
 
         @Override
         public LispMapRecord build() {
+
+            if (locatorRecords == null) {
+                locatorRecords = Lists.newArrayList();
+            }
+
             return new DefaultLispMapRecord(recordTtl, locatorCount, maskLength,
                     action, authoritative, mapVersionNumber, eidPrefixAfi, locatorRecords);
         }
@@ -228,6 +237,8 @@
         private static final int AUTHORITATIVE_INDEX = 4;
         private static final int RESERVED_SKIP_LENGTH = 1;
 
+        private static final int REPLY_ACTION_SHIFT_BIT = 5;
+
         @Override
         public LispMapRecord readFrom(ByteBuf byteBuf) throws LispParseError, LispReaderException {
 
@@ -235,17 +246,22 @@
             int recordTtl = byteBuf.readInt();
 
             // Locator count -> 8 bits
-            int locatorCount = byteBuf.readUnsignedShort();
+            int locatorCount = byteBuf.readUnsignedByte();
 
             // EID mask length -> 8 bits
             byte maskLength = (byte) byteBuf.readUnsignedByte();
 
-            // TODO: need to de-serialize LispMapReplyAction
+            byte actionWithFlag = (byte) byteBuf.readUnsignedByte();
 
-            byte actionWithFlag = byteBuf.readByte();
+            // action -> 3 bit
+            int actionByte = actionWithFlag >> REPLY_ACTION_SHIFT_BIT;
+            LispMapReplyAction action = LispMapReplyAction.valueOf(actionByte);
+            if (action == null) {
+                action = LispMapReplyAction.NoAction;
+            }
 
             // authoritative flag -> 1 bit
-            boolean authoritative = ByteOperator.getBit(actionWithFlag, AUTHORITATIVE_INDEX);
+            boolean authoritative = ByteOperator.getBit((byte) (actionWithFlag >> AUTHORITATIVE_INDEX), 0);
 
             // let's skip the reserved field
             byteBuf.skipBytes(RESERVED_SKIP_LENGTH);
@@ -264,6 +280,7 @@
                         .withRecordTtl(recordTtl)
                         .withLocatorCount(locatorCount)
                         .withMaskLength(maskLength)
+                        .withAction(action)
                         .withAuthoritative(authoritative)
                         .withMapVersionNumber(mapVersionNumber)
                         .withLocators(locators)
@@ -301,9 +318,8 @@
             // authoritative bit
             byte authoritative = DISABLE_BIT;
             if (message.isAuthoritative()) {
-                authoritative = ENABLE_BIT;
+                authoritative = ENABLE_BIT << AUTHORITATIVE_FLAG_SHIFT_BIT;
             }
-            authoritative = (byte) (authoritative << AUTHORITATIVE_FLAG_SHIFT_BIT);
 
             byteBuf.writeByte((byte) (action + authoritative));
 
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRegister.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRegister.java
index abaf3c8..b6ed216 100644
--- a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRegister.java
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRegister.java
@@ -29,6 +29,8 @@
 import java.util.List;
 
 import static com.google.common.base.MoreObjects.toStringHelper;
+import static org.onosproject.lisp.msg.protocols.DefaultLispMapRecord.MapRecordReader;
+import static org.onosproject.lisp.msg.protocols.DefaultLispMapRecord.MapRecordWriter;
 
 
 /**
@@ -117,7 +119,11 @@
 
     @Override
     public byte[] getAuthenticationData() {
-        return ImmutableByteSequence.copyFrom(this.authenticationData).asArray();
+        if (authenticationData != null && authenticationData.length != 0) {
+            return ImmutableByteSequence.copyFrom(authenticationData).asArray();
+        } else {
+            return new byte[0];
+        }
     }
 
     @Override
@@ -153,7 +159,7 @@
                 Objects.equal(recordCount, that.recordCount) &&
                 Objects.equal(keyId, that.keyId) &&
                 Objects.equal(authDataLength, that.authDataLength) &&
-                Objects.equal(authenticationData, that.authenticationData) &&
+                Arrays.equals(authenticationData, that.authenticationData) &&
                 Objects.equal(proxyMapReply, that.proxyMapReply) &&
                 Objects.equal(wantMapNotify, that.wantMapNotify);
     }
@@ -161,7 +167,7 @@
     @Override
     public int hashCode() {
         return Objects.hashCode(nonce, recordCount, keyId, authDataLength,
-                authenticationData, proxyMapReply, wantMapNotify);
+                proxyMapReply, wantMapNotify) + Arrays.hashCode(authenticationData);
     }
 
     public static final class DefaultRegisterBuilder implements RegisterBuilder {
@@ -218,18 +224,34 @@
 
         @Override
         public RegisterBuilder withAuthenticationData(byte[] authenticationData) {
-            this.authenticationData = authenticationData;
+            if (authenticationData != null) {
+                this.authenticationData = authenticationData;
+            } else {
+                this.authenticationData = new byte[0];
+            }
             return this;
         }
 
         @Override
         public RegisterBuilder withMapRecords(List<LispMapRecord> mapRecords) {
-            this.mapRecords = ImmutableList.copyOf(mapRecords);
+            if (mapRecords != null) {
+                this.mapRecords = ImmutableList.copyOf(mapRecords);
+            } else {
+                this.mapRecords = Lists.newArrayList();
+            }
             return this;
         }
 
         @Override
         public LispMapRegister build() {
+            if (authenticationData == null) {
+                authenticationData = new byte[0];
+            }
+
+            if (mapRecords == null) {
+                mapRecords = Lists.newArrayList();
+            }
+
             return new DefaultLispMapRegister(nonce, keyId, authDataLength,
                     authenticationData, recordCount, mapRecords, proxyMapReply, wantMapNotify);
         }
@@ -280,7 +302,7 @@
 
             List<LispMapRecord> mapRecords = Lists.newArrayList();
             for (int i = 0; i < recordCount; i++) {
-                mapRecords.add(new DefaultLispMapRecord.MapRecordReader().readFrom(byteBuf));
+                mapRecords.add(new MapRecordReader().readFrom(byteBuf));
             }
 
             return new DefaultRegisterBuilder()
@@ -360,7 +382,7 @@
             // TODO: need to implement MAC authentication mechanism
 
             // serialize map records
-            DefaultLispMapRecord.MapRecordWriter writer = new DefaultLispMapRecord.MapRecordWriter();
+            MapRecordWriter writer = new MapRecordWriter();
             List<LispMapRecord> records = message.getMapRecords();
 
             for (int i = 0; i < records.size(); i++) {
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapReply.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapReply.java
index 220bf7e..f422740 100644
--- a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapReply.java
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapReply.java
@@ -185,12 +185,22 @@
 
         @Override
         public ReplyBuilder withMapRecords(List<LispMapRecord> mapRecords) {
-            this.mapRecords = ImmutableList.copyOf(mapRecords);
+
+            if (this.mapRecords != null) {
+                this.mapRecords = ImmutableList.copyOf(mapRecords);
+            } else {
+                this.mapRecords = Lists.newArrayList();
+            }
             return this;
         }
 
         @Override
         public LispMapReply build() {
+
+            if (mapRecords == null) {
+                mapRecords = Lists.newArrayList();
+            }
+
             return new DefaultLispMapReply(nonce, recordCount, probe, etr, security, mapRecords);
         }
     }
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRequest.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRequest.java
index 45e85bf..b62eed6 100644
--- a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRequest.java
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRequest.java
@@ -28,6 +28,8 @@
 import java.util.List;
 
 import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
 import static org.onosproject.lisp.msg.types.LispAfiAddress.AfiAddressWriter;
 import static org.onosproject.lisp.msg.protocols.LispEidRecord.EidRecordWriter;
 
@@ -179,8 +181,6 @@
         return Objects.equal(nonce, that.nonce) &&
                 Objects.equal(recordCount, that.recordCount) &&
                 Objects.equal(sourceEid, that.sourceEid) &&
-                Objects.equal(itrRlocs, that.itrRlocs) &&
-                Objects.equal(eidRecords, that.eidRecords) &&
                 Objects.equal(authoritative, that.authoritative) &&
                 Objects.equal(mapDataPresent, that.mapDataPresent) &&
                 Objects.equal(probe, that.probe) &&
@@ -191,8 +191,8 @@
 
     @Override
     public int hashCode() {
-        return Objects.hashCode(nonce, recordCount, sourceEid, itrRlocs, eidRecords,
-                authoritative, mapDataPresent, probe, smr, pitr, smrInvoked);
+        return Objects.hashCode(nonce, recordCount, sourceEid, authoritative,
+                mapDataPresent, probe, smr, pitr, smrInvoked);
     }
 
     public static final class DefaultRequestBuilder implements RequestBuilder {
@@ -270,18 +270,33 @@
 
         @Override
         public RequestBuilder withItrRlocs(List<LispAfiAddress> itrRlocs) {
-            this.itrRlocs = ImmutableList.copyOf(itrRlocs);
+
+            if (itrRlocs != null) {
+                this.itrRlocs = ImmutableList.copyOf(itrRlocs);
+            } else {
+                this.itrRlocs = Lists.newArrayList();
+            }
+
             return this;
         }
 
         @Override
         public RequestBuilder withEidRecords(List<LispEidRecord> records) {
-            this.eidRecords = ImmutableList.copyOf(records);
+
+            if (records != null) {
+                this.eidRecords = ImmutableList.copyOf(records);
+            } else {
+                this.eidRecords = Lists.newArrayList();
+            }
             return this;
         }
 
         @Override
         public LispMapRequest build() {
+
+            checkNotNull(sourceEid, "Must have a source EID");
+            checkArgument((itrRlocs != null) && (itrRlocs.size() > 0), "Must have an ITR RLOC entry");
+
             return new DefaultLispMapRequest(nonce, recordCount, sourceEid, itrRlocs,
                     eidRecords, authoritative, mapDataPresent, probe, smr, pitr, smrInvoked);
         }
@@ -331,10 +346,10 @@
             // let's skip reserved field, only obtains ITR counter value
             // assume that first 3 bits are all set as 0,
             // remain 5 bits represent Itr Rloc Counter (IRC)
-            int irc = byteBuf.readUnsignedShort();
+            int irc = byteBuf.readUnsignedByte();
 
             // record count -> 8 bits
-            int recordCount = byteBuf.readUnsignedShort();
+            int recordCount = byteBuf.readUnsignedByte();
 
             // nonce -> 64 bits
             long nonce = byteBuf.readLong();
@@ -387,8 +402,6 @@
         private static final int ENABLE_BIT = 1;
         private static final int DISABLE_BIT = 0;
 
-        private static final int UNUSED_ZERO = 0;
-
         @Override
         public void writeTo(ByteBuf byteBuf, LispMapRequest message) throws LispWriterException {
 
@@ -435,8 +448,8 @@
 
             byteBuf.writeByte((byte) (pitr + smrInvoked));
 
-            // TODO: ITR RLOC count
-            byteBuf.writeByte((byte) UNUSED_ZERO);
+            // ITR Rloc count
+            byteBuf.writeByte((byte) message.getItrRlocs().size());
 
             // record count
             byteBuf.writeByte(message.getRecordCount());
diff --git a/protocols/lisp/msg/src/test/java/org/onosproject/lisp/msg/protocols/DefaultLispLocatorRecordTest.java b/protocols/lisp/msg/src/test/java/org/onosproject/lisp/msg/protocols/DefaultLispLocatorRecordTest.java
index 7b99612..99dcfcf 100644
--- a/protocols/lisp/msg/src/test/java/org/onosproject/lisp/msg/protocols/DefaultLispLocatorRecordTest.java
+++ b/protocols/lisp/msg/src/test/java/org/onosproject/lisp/msg/protocols/DefaultLispLocatorRecordTest.java
@@ -16,11 +16,19 @@
 package org.onosproject.lisp.msg.protocols;
 
 import com.google.common.testing.EqualsTester;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
 import org.junit.Before;
 import org.junit.Test;
+import org.onlab.packet.IpAddress;
+import org.onosproject.lisp.msg.exceptions.LispParseError;
+import org.onosproject.lisp.msg.exceptions.LispReaderException;
+import org.onosproject.lisp.msg.exceptions.LispWriterException;
+import org.onosproject.lisp.msg.types.LispIpv4Address;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
+import static org.onosproject.lisp.msg.protocols.DefaultLispLocatorRecord.*;
 
 /**
  * Unit tests for DefaultLispLocatorRecord class.
@@ -35,7 +43,9 @@
     public void setup() {
 
         LispLocatorRecord.LocatorRecordBuilder builder1 =
-                    new DefaultLispLocatorRecord.DefaultLocatorRecordBuilder();
+                    new DefaultLocatorRecordBuilder();
+
+        LispIpv4Address ipv4Locator1 = new LispIpv4Address(IpAddress.valueOf("192.168.1.1"));
 
         record1 = builder1
                         .withPriority((byte) 0x01)
@@ -45,10 +55,11 @@
                         .withLocalLocator(true)
                         .withRlocProbed(false)
                         .withRouted(true)
+                        .withLocatorAfi(ipv4Locator1)
                         .build();
 
         LispLocatorRecord.LocatorRecordBuilder builder2 =
-                    new DefaultLispLocatorRecord.DefaultLocatorRecordBuilder();
+                    new DefaultLocatorRecordBuilder();
 
         sameAsRecord1 = builder2
                         .withPriority((byte) 0x01)
@@ -58,10 +69,13 @@
                         .withLocalLocator(true)
                         .withRlocProbed(false)
                         .withRouted(true)
+                        .withLocatorAfi(ipv4Locator1)
                         .build();
 
         LispLocatorRecord.LocatorRecordBuilder builder3 =
-                    new DefaultLispLocatorRecord.DefaultLocatorRecordBuilder();
+                    new DefaultLocatorRecordBuilder();
+
+        LispIpv4Address ipv4Locator2 = new LispIpv4Address(IpAddress.valueOf("192.168.1.2"));
 
         record2 = builder3
                         .withPriority((byte) 0x02)
@@ -71,6 +85,7 @@
                         .withLocalLocator(false)
                         .withRlocProbed(true)
                         .withRouted(false)
+                        .withLocatorAfi(ipv4Locator2)
                         .build();
     }
 
@@ -85,6 +100,8 @@
     public void testConstruction() {
         DefaultLispLocatorRecord record = (DefaultLispLocatorRecord) record1;
 
+        LispIpv4Address ipv4Locator = new LispIpv4Address(IpAddress.valueOf("192.168.1.1"));
+
         assertThat(record.getPriority(), is((byte) 0x01));
         assertThat(record.getWeight(), is((byte) 0x01));
         assertThat(record.getMulticastPriority(), is((byte) 0x01));
@@ -92,5 +109,20 @@
         assertThat(record.isLocalLocator(), is(true));
         assertThat(record.isRlocProbed(), is(false));
         assertThat(record.isRouted(), is(true));
+        assertThat(record.getLocatorAfi(), is(ipv4Locator));
+    }
+
+    @Test
+    public void testSerialization() throws LispReaderException, LispWriterException, LispParseError {
+        ByteBuf byteBuf = Unpooled.buffer();
+
+        LocatorRecordWriter writer = new LocatorRecordWriter();
+        writer.writeTo(byteBuf, record1);
+
+        LocatorRecordReader reader = new LocatorRecordReader();
+        LispLocatorRecord deserialized = reader.readFrom(byteBuf);
+
+        new EqualsTester()
+                .addEqualityGroup(record1, deserialized).testEquals();
     }
 }
diff --git a/protocols/lisp/msg/src/test/java/org/onosproject/lisp/msg/protocols/DefaultLispMapNotifyTest.java b/protocols/lisp/msg/src/test/java/org/onosproject/lisp/msg/protocols/DefaultLispMapNotifyTest.java
index 26d8ff0..819da3d 100644
--- a/protocols/lisp/msg/src/test/java/org/onosproject/lisp/msg/protocols/DefaultLispMapNotifyTest.java
+++ b/protocols/lisp/msg/src/test/java/org/onosproject/lisp/msg/protocols/DefaultLispMapNotifyTest.java
@@ -16,11 +16,17 @@
 package org.onosproject.lisp.msg.protocols;
 
 import com.google.common.testing.EqualsTester;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
 import org.junit.Before;
 import org.junit.Test;
+import org.onosproject.lisp.msg.exceptions.LispParseError;
+import org.onosproject.lisp.msg.exceptions.LispReaderException;
+import org.onosproject.lisp.msg.exceptions.LispWriterException;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
+import static org.onosproject.lisp.msg.protocols.DefaultLispMapNotify.*;
 
 /**
  * Unit tests for DefaultLispMapNotify class.
@@ -35,25 +41,25 @@
     public void setup() {
 
         LispMapNotify.NotifyBuilder builder1 =
-                        new DefaultLispMapNotify.DefaultNotifyBuilder();
+                        new DefaultNotifyBuilder();
 
         notify1 = builder1
                         .withKeyId((short) 1)
                         .withNonce(1L)
-                        .withRecordCount((byte) 0x01)
+                        .withRecordCount((byte) 0)
                         .build();
 
         LispMapNotify.NotifyBuilder builder2 =
-                        new DefaultLispMapNotify.DefaultNotifyBuilder();
+                        new DefaultNotifyBuilder();
 
         sameAsNotify1 = builder2
                         .withKeyId((short) 1)
                         .withNonce(1L)
-                        .withRecordCount((byte) 0x01)
+                        .withRecordCount((byte) 0)
                         .build();
 
         LispMapNotify.NotifyBuilder builder3 =
-                        new DefaultLispMapNotify.DefaultNotifyBuilder();
+                        new DefaultNotifyBuilder();
 
         notify2 = builder3
                         .withKeyId((short) 2)
@@ -75,6 +81,20 @@
 
         assertThat(notify.getKeyId(), is((short) 1));
         assertThat(notify.getNonce(), is(1L));
-        assertThat(notify.getRecordCount(), is((byte) 0x01));
+        assertThat(notify.getRecordCount(), is((byte) 0));
+    }
+
+    @Test
+    public void testSerialization() throws LispReaderException, LispWriterException, LispParseError {
+        ByteBuf byteBuf = Unpooled.buffer();
+
+        NotifyWriter writer = new NotifyWriter();
+        writer.writeTo(byteBuf, notify1);
+
+        NotifyReader reader = new NotifyReader();
+        LispMapNotify deserialized = reader.readFrom(byteBuf);
+
+        new EqualsTester()
+                .addEqualityGroup(notify1, deserialized).testEquals();
     }
 }
diff --git a/protocols/lisp/msg/src/test/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRecordTest.java b/protocols/lisp/msg/src/test/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRecordTest.java
index 1c85b11..25ce27f 100644
--- a/protocols/lisp/msg/src/test/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRecordTest.java
+++ b/protocols/lisp/msg/src/test/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRecordTest.java
@@ -16,11 +16,19 @@
 package org.onosproject.lisp.msg.protocols;
 
 import com.google.common.testing.EqualsTester;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
 import org.junit.Before;
 import org.junit.Test;
+import org.onlab.packet.IpAddress;
+import org.onosproject.lisp.msg.exceptions.LispParseError;
+import org.onosproject.lisp.msg.exceptions.LispReaderException;
+import org.onosproject.lisp.msg.exceptions.LispWriterException;
+import org.onosproject.lisp.msg.types.LispIpv4Address;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
+import static org.onosproject.lisp.msg.protocols.DefaultLispMapRecord.*;
 
 /**
  * Unit tests for DefaultLispMapRecord class.
@@ -35,29 +43,37 @@
     public void setup() {
 
         LispMapRecord.MapRecordBuilder builder1 =
-                        new DefaultLispMapRecord.DefaultMapRecordBuilder();
+                        new DefaultMapRecordBuilder();
+
+        LispIpv4Address ipv4Locator1 = new LispIpv4Address(IpAddress.valueOf("192.168.1.1"));
 
         record1 = builder1
                         .withRecordTtl(100)
                         .withAuthoritative(true)
-                        .withLocatorCount(100)
+                        .withLocatorCount(0)
                         .withMapVersionNumber((short) 1)
                         .withMaskLength((byte) 0x01)
+                        .withAction(LispMapReplyAction.NativelyForward)
+                        .withEidPrefixAfi(ipv4Locator1)
                         .build();
 
         LispMapRecord.MapRecordBuilder builder2 =
-                        new DefaultLispMapRecord.DefaultMapRecordBuilder();
+                        new DefaultMapRecordBuilder();
 
         sameAsRecord1 = builder2
                         .withRecordTtl(100)
                         .withAuthoritative(true)
-                        .withLocatorCount(100)
+                        .withLocatorCount(0)
                         .withMapVersionNumber((short) 1)
                         .withMaskLength((byte) 0x01)
+                        .withAction(LispMapReplyAction.NativelyForward)
+                        .withEidPrefixAfi(ipv4Locator1)
                         .build();
 
         LispMapRecord.MapRecordBuilder builder3 =
-                        new DefaultLispMapRecord.DefaultMapRecordBuilder();
+                        new DefaultMapRecordBuilder();
+
+        LispIpv4Address ipv4Locator2 = new LispIpv4Address(IpAddress.valueOf("192.168.1.2"));
 
         record2 = builder3
                         .withRecordTtl(200)
@@ -65,6 +81,8 @@
                         .withLocatorCount(200)
                         .withMapVersionNumber((short) 2)
                         .withMaskLength((byte) 0x02)
+                        .withAction(LispMapReplyAction.Drop)
+                        .withEidPrefixAfi(ipv4Locator2)
                         .build();
     }
 
@@ -79,10 +97,28 @@
     public void testConstruction() {
         DefaultLispMapRecord record = (DefaultLispMapRecord) record1;
 
+        LispIpv4Address ipv4Locator = new LispIpv4Address(IpAddress.valueOf("192.168.1.1"));
+
         assertThat(record.getRecordTtl(), is(100));
         assertThat(record.isAuthoritative(), is(true));
-        assertThat(record.getLocatorCount(), is(100));
+        assertThat(record.getLocatorCount(), is(0));
         assertThat(record.getMapVersionNumber(), is((short) 1));
         assertThat(record.getMaskLength(), is((byte) 0x01));
+        assertThat(record.getAction(), is(LispMapReplyAction.NativelyForward));
+        assertThat(record.getEidPrefixAfi(), is(ipv4Locator));
+    }
+
+    @Test
+    public void testSerialization() throws LispReaderException, LispWriterException, LispParseError {
+        ByteBuf byteBuf = Unpooled.buffer();
+
+        MapRecordWriter writer = new MapRecordWriter();
+        writer.writeTo(byteBuf, record1);
+
+        MapRecordReader reader = new MapRecordReader();
+        LispMapRecord deserialized = reader.readFrom(byteBuf);
+
+        new EqualsTester()
+                .addEqualityGroup(record1, deserialized).testEquals();
     }
 }
diff --git a/protocols/lisp/msg/src/test/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRegisterTest.java b/protocols/lisp/msg/src/test/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRegisterTest.java
index 1b0a5a4..f7c5e49 100644
--- a/protocols/lisp/msg/src/test/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRegisterTest.java
+++ b/protocols/lisp/msg/src/test/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRegisterTest.java
@@ -16,8 +16,15 @@
 package org.onosproject.lisp.msg.protocols;
 
 import com.google.common.testing.EqualsTester;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
 import org.junit.Before;
 import org.junit.Test;
+import org.onosproject.lisp.msg.exceptions.LispParseError;
+import org.onosproject.lisp.msg.exceptions.LispReaderException;
+import org.onosproject.lisp.msg.exceptions.LispWriterException;
+import org.onosproject.lisp.msg.protocols.DefaultLispMapRegister.RegisterReader;
+import org.onosproject.lisp.msg.protocols.DefaultLispMapRegister.RegisterWriter;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
@@ -42,7 +49,7 @@
                         .withIsWantMapNotify(false)
                         .withKeyId((short) 1)
                         .withNonce(1L)
-                        .withRecordCount((byte) 0x01)
+                        .withRecordCount((byte) 0)
                         .build();
 
         LispMapRegister.RegisterBuilder builder2 =
@@ -53,7 +60,7 @@
                         .withIsWantMapNotify(false)
                         .withKeyId((short) 1)
                         .withNonce(1L)
-                        .withRecordCount((byte) 0x01)
+                        .withRecordCount((byte) 0)
                         .build();
 
         LispMapRegister.RegisterBuilder builder3 =
@@ -83,6 +90,20 @@
         assertThat(register.isWantMapNotify(), is(false));
         assertThat(register.getKeyId(), is((short) 1));
         assertThat(register.getNonce(), is(1L));
-        assertThat(register.getRecordCount(), is((byte) 0x01));
+        assertThat(register.getRecordCount(), is((byte) 0));
+    }
+
+    @Test
+    public void testSerialization() throws LispReaderException, LispWriterException, LispParseError {
+        ByteBuf byteBuf = Unpooled.buffer();
+
+        RegisterWriter writer = new RegisterWriter();
+        writer.writeTo(byteBuf, register1);
+
+        RegisterReader reader = new RegisterReader();
+        LispMapRegister deserialized = reader.readFrom(byteBuf);
+
+        new EqualsTester()
+                .addEqualityGroup(register1, deserialized).testEquals();
     }
 }
diff --git a/protocols/lisp/msg/src/test/java/org/onosproject/lisp/msg/protocols/DefaultLispMapReplyTest.java b/protocols/lisp/msg/src/test/java/org/onosproject/lisp/msg/protocols/DefaultLispMapReplyTest.java
index 7b530d2..5b3c899 100644
--- a/protocols/lisp/msg/src/test/java/org/onosproject/lisp/msg/protocols/DefaultLispMapReplyTest.java
+++ b/protocols/lisp/msg/src/test/java/org/onosproject/lisp/msg/protocols/DefaultLispMapReplyTest.java
@@ -16,8 +16,15 @@
 package org.onosproject.lisp.msg.protocols;
 
 import com.google.common.testing.EqualsTester;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
 import org.junit.Before;
 import org.junit.Test;
+import org.onosproject.lisp.msg.exceptions.LispParseError;
+import org.onosproject.lisp.msg.exceptions.LispReaderException;
+import org.onosproject.lisp.msg.exceptions.LispWriterException;
+import org.onosproject.lisp.msg.protocols.DefaultLispMapReply.ReplyReader;
+import org.onosproject.lisp.msg.protocols.DefaultLispMapReply.ReplyWriter;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
@@ -42,7 +49,7 @@
                         .withIsProbe(false)
                         .withIsSecurity(true)
                         .withNonce(1L)
-                        .withRecordCount((byte) 0x01)
+                        .withRecordCount((byte) 0)
                         .build();
 
         LispMapReply.ReplyBuilder builder2 =
@@ -53,7 +60,7 @@
                         .withIsProbe(false)
                         .withIsSecurity(true)
                         .withNonce(1L)
-                        .withRecordCount((byte) 0x01)
+                        .withRecordCount((byte) 0)
                         .build();
 
         LispMapReply.ReplyBuilder builder3 =
@@ -82,6 +89,19 @@
         assertThat(reply.isProbe(), is(false));
         assertThat(reply.isSecurity(), is(true));
         assertThat(reply.getNonce(), is(1L));
-        assertThat(reply.getRecordCount(), is((byte) 0x01));
+        assertThat(reply.getRecordCount(), is((byte) 0));
+    }
+
+    @Test
+    public void testSerialization() throws LispReaderException, LispWriterException, LispParseError {
+        ByteBuf byteBuf = Unpooled.buffer();
+        ReplyWriter writer = new ReplyWriter();
+        writer.writeTo(byteBuf, reply1);
+
+        ReplyReader reader = new ReplyReader();
+        LispMapReply deserialized = reader.readFrom(byteBuf);
+
+        new EqualsTester()
+                .addEqualityGroup(reply1, deserialized).testEquals();
     }
 }
diff --git a/protocols/lisp/msg/src/test/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRequestTest.java b/protocols/lisp/msg/src/test/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRequestTest.java
index 155c6a6..088c4f8 100644
--- a/protocols/lisp/msg/src/test/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRequestTest.java
+++ b/protocols/lisp/msg/src/test/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRequestTest.java
@@ -15,12 +15,24 @@
  */
 package org.onosproject.lisp.msg.protocols;
 
+import com.google.common.collect.ImmutableList;
 import com.google.common.testing.EqualsTester;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
 import org.junit.Before;
 import org.junit.Test;
+import org.onlab.packet.IpAddress;
+import org.onosproject.lisp.msg.exceptions.LispParseError;
+import org.onosproject.lisp.msg.exceptions.LispReaderException;
+import org.onosproject.lisp.msg.exceptions.LispWriterException;
+import org.onosproject.lisp.msg.types.LispAfiAddress;
+import org.onosproject.lisp.msg.types.LispIpv4Address;
+
+import java.util.List;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
+import static org.onosproject.lisp.msg.protocols.DefaultLispMapRequest.*;
 
 /**
  * Unit tests for DefaultLispMapRequest class.
@@ -34,8 +46,14 @@
     @Before
     public void setup() {
 
-        LispMapRequest.RequestBuilder builder1 =
-                        new DefaultLispMapRequest.DefaultRequestBuilder();
+        RequestBuilder builder1 = new DefaultRequestBuilder();
+
+        LispIpv4Address ipv4Eid1 = new LispIpv4Address(IpAddress.valueOf("192.168.1.1"));
+
+        LispIpv4Address ipv4Rloc1 = new LispIpv4Address(IpAddress.valueOf("10.1.1.1"));
+        LispIpv4Address ipv4Rloc2 = new LispIpv4Address(IpAddress.valueOf("10.1.1.2"));
+
+        List<LispAfiAddress> rlocs1 = ImmutableList.of(ipv4Rloc1, ipv4Rloc2);
 
         request1 = builder1
                         .withIsAuthoritative(true)
@@ -44,12 +62,13 @@
                         .withIsProbe(false)
                         .withIsSmr(true)
                         .withIsSmrInvoked(false)
+                        .withSourceEid(ipv4Eid1)
+                        .withItrRlocs(rlocs1)
                         .withNonce(1L)
-                        .withRecordCount((byte) 0x01)
+                        .withRecordCount((byte) 0)
                         .build();
 
-        LispMapRequest.RequestBuilder builder2 =
-                        new DefaultLispMapRequest.DefaultRequestBuilder();
+        RequestBuilder builder2 = new DefaultRequestBuilder();
 
         sameAsRequest1 = builder2
                         .withIsAuthoritative(true)
@@ -58,12 +77,20 @@
                         .withIsProbe(false)
                         .withIsSmr(true)
                         .withIsSmrInvoked(false)
+                        .withSourceEid(ipv4Eid1)
+                        .withItrRlocs(rlocs1)
                         .withNonce(1L)
-                        .withRecordCount((byte) 0x01)
+                        .withRecordCount((byte) 0)
                         .build();
 
-        LispMapRequest.RequestBuilder builder3 =
-                        new DefaultLispMapRequest.DefaultRequestBuilder();
+        RequestBuilder builder3 = new DefaultRequestBuilder();
+
+        LispIpv4Address ipv4Eid2 = new LispIpv4Address(IpAddress.valueOf("192.168.1.2"));
+
+        LispIpv4Address ipv4Rloc3 = new LispIpv4Address(IpAddress.valueOf("10.1.1.1"));
+        LispIpv4Address ipv4Rloc4 = new LispIpv4Address(IpAddress.valueOf("10.1.1.2"));
+
+        List<LispAfiAddress> rlocs2 = ImmutableList.of(ipv4Rloc3, ipv4Rloc4);
 
         request2 = builder3
                         .withIsAuthoritative(false)
@@ -72,6 +99,8 @@
                         .withIsProbe(true)
                         .withIsSmr(false)
                         .withIsSmrInvoked(true)
+                        .withSourceEid(ipv4Eid2)
+                        .withItrRlocs(rlocs2)
                         .withNonce(2L)
                         .withRecordCount((byte) 0x02)
                         .build();
@@ -95,6 +124,19 @@
         assertThat(request.isSmr(), is(true));
         assertThat(request.isSmrInvoked(), is(false));
         assertThat(request.getNonce(), is(1L));
-        assertThat(request.getRecordCount(), is((byte) 0x01));
+        assertThat(request.getRecordCount(), is((byte) 0));
+    }
+
+    @Test
+    public void testSerialization() throws LispReaderException, LispWriterException, LispParseError {
+        ByteBuf byteBuf = Unpooled.buffer();
+        RequestWriter writer = new RequestWriter();
+        writer.writeTo(byteBuf, request1);
+
+        RequestReader reader = new RequestReader();
+        LispMapRequest deserialized = reader.readFrom(byteBuf);
+
+        new EqualsTester()
+                .addEqualityGroup(request1, deserialized).testEquals();
     }
 }
diff --git a/utils/misc/src/main/java/org/onlab/util/ByteOperator.java b/utils/misc/src/main/java/org/onlab/util/ByteOperator.java
index 4d30ce7..170b48c 100644
--- a/utils/misc/src/main/java/org/onlab/util/ByteOperator.java
+++ b/utils/misc/src/main/java/org/onlab/util/ByteOperator.java
@@ -61,7 +61,7 @@
      * @param decimal decimal formatted integer
      * @return hex formatted integer
      */
-    private static int getHex(int decimal) {
+    public static int getHex(int decimal) {
         return Integer.valueOf(String.valueOf(decimal), 16);
     }
 }