Fixed reading of operational state of lisp
authorJan Srnicek <[email protected]>
Wed, 21 Sep 2016 13:02:12 +0000 (15:02 +0200)
committerMaros Marsalek <[email protected]>
Wed, 21 Sep 2016 13:38:13 +0000 (13:38 +0000)
Rejecting of empty locator-sets
Added revert of searched key to match vpp address
order
Ignoring helper data returned by dumps

Change-Id: I5ec74f48dc373099b5fe516553d769c20e4a98f8
Signed-off-by: Jan Srnicek <[email protected]>
lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/LocalMappingCustomizer.java
lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/MapResolverCustomizer.java
lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/RemoteMappingCustomizer.java
lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/LocatorSetCustomizer.java
lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/translate/write/LocatorSetCustomizerTest.java
vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/v3po/util/TranslateUtils.java
vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/v3po/util/TranslateUtilsTest.java

index f2a8a85..1262aaa 100755 (executable)
@@ -37,10 +37,10 @@ import io.fd.honeycomb.translate.read.ReadContext;
 import io.fd.honeycomb.translate.read.ReadFailedException;
 import io.fd.honeycomb.translate.spi.read.ListReaderCustomizer;
 import io.fd.honeycomb.translate.util.RWUtils;
-import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer;
-import io.fd.honeycomb.translate.v3po.util.NamingContext;
 import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager;
 import io.fd.honeycomb.translate.util.read.cache.exceptions.execution.DumpExecutionFailedException;
+import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer;
+import io.fd.honeycomb.translate.v3po.util.NamingContext;
 import java.util.Collections;
 import java.util.List;
 import java.util.stream.Collectors;
@@ -154,10 +154,17 @@ public class LocalMappingCustomizer
             throws ReadFailedException {
 
         checkState(id.firstKeyOf(VniTable.class) != null, "Parent VNI table not specified");
+        final long vni = id.firstKeyOf(VniTable.class).getVirtualNetworkIdentifier();
+
+        if (vni == 0) {
+            // ignoring default vni mapping
+            // its not relevant for us and we also don't store mapping for such eid's
+            // such mapping is used to create helper local mappings to process remote ones
+            return Collections.emptyList();
+        }
 
         //request for all local mappings
         final MappingsDumpParams dumpParams = new MappingsDumpParamsBuilder()
-                .setVni(Long.valueOf(id.firstKeyOf(VniTable.class).getVirtualNetworkIdentifier()).intValue())
                 .setFilter(FilterType.LOCAL)
                 .setEidSet(QuantityType.ALL)
                 .build();
@@ -172,11 +179,14 @@ public class LocalMappingCustomizer
 
         if (replyOptional.isPresent()) {
             LOG.debug("Valid dump loaded");
-            return replyOptional.get().lispEidTableDetails.stream().map(a -> new LocalMappingKey(
-                    new MappingId(
-                            localMappingContext.getId(
-                                    getArrayAsEidLocal(valueOf(a.eidType), a.eid),
-                                    context.getMappingContext()))))
+            return replyOptional.get().lispEidTableDetails.stream()
+                    //filtering with vni to skip help local mappings that are created in vpp to handle remote mappings(vpp feature)
+                    .filter(a -> a.vni == vni)
+                    .map(a -> new LocalMappingKey(
+                            new MappingId(
+                                    localMappingContext.getId(
+                                            getArrayAsEidLocal(valueOf(a.eidType), a.eid),
+                                            context.getMappingContext()))))
                     .collect(Collectors.toList());
         } else {
             LOG.debug("No data dumped");
index 57dd831..9e98193 100755 (executable)
 
 package io.fd.honeycomb.lisp.translate.read;
 
+import static io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor.NO_PARAMS;
 import static io.fd.honeycomb.translate.v3po.util.TranslateUtils.arrayToIpAddress;
 import static io.fd.honeycomb.translate.v3po.util.TranslateUtils.byteToBoolean;
-import static io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor.NO_PARAMS;
+import static io.fd.honeycomb.translate.v3po.util.TranslateUtils.reverseAddress;
 
 import com.google.common.base.Optional;
 import io.fd.honeycomb.lisp.translate.read.dump.check.MapResolverDumpCheck;
@@ -26,9 +27,9 @@ import io.fd.honeycomb.lisp.translate.read.dump.executor.MapResolversDumpExecuto
 import io.fd.honeycomb.translate.read.ReadContext;
 import io.fd.honeycomb.translate.read.ReadFailedException;
 import io.fd.honeycomb.translate.spi.read.ListReaderCustomizer;
-import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer;
 import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager;
 import io.fd.honeycomb.translate.util.read.cache.exceptions.execution.DumpExecutionFailedException;
+import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer;
 import java.util.Collections;
 import java.util.List;
 import java.util.stream.Collectors;
@@ -85,13 +86,15 @@ public class MapResolverCustomizer extends FutureJVppCustomizer
         }
 
         final MapResolverKey key = id.firstKeyOf(MapResolver.class);
-        final IpAddress address = key.getIpAddress();
+        //revert searched key to match vpp's reversed order ip's
+        final IpAddress address = reverseAddress(key.getIpAddress());
         final LispMapResolverDetailsReplyDump dump = dumpOptional.get();
 
         //cannot use RWUtils.singleItemCollector(),there is some problem with generic params binding
         java.util.Optional<LispMapResolverDetails> mapResolverOptional =
                 dump.lispMapResolverDetails.stream()
-                        .filter(a -> address.equals(arrayToIpAddress(byteToBoolean(a.isIpv6), a.ipAddress)))
+                        .filter(a -> address
+                                .equals(arrayToIpAddress(byteToBoolean(a.isIpv6), a.ipAddress)))
                         .findFirst();
 
         if (mapResolverOptional.isPresent()) {
index 6b41e2d..a34fedd 100755 (executable)
@@ -115,6 +115,7 @@ public class RemoteMappingCustomizer extends FutureJVppCustomizer
                 .setEidType(EidConverter.getEidType(eid))
                 .setEid(EidConverter.getEidAsByteArray(eid))
                 .setPrefixLength(EidConverter.getPrefixLength(eid))
+                .setFilter(FilterType.REMOTE)
                 .build();
 
         LOG.debug("Dumping data for LocalMappings(id={})", id);
@@ -158,10 +159,17 @@ public class RemoteMappingCustomizer extends FutureJVppCustomizer
             throws ReadFailedException {
 
         checkState(id.firstKeyOf(VniTable.class) != null, "Parent VNI table not specified");
+        final int vni = id.firstKeyOf(VniTable.class).getVirtualNetworkIdentifier().intValue();
+
+        if (vni == 0) {
+            // ignoring default vni mapping
+            // its not relevant for us and we also don't store mapping for such eid's
+            // such mapping is used to create helper local mappings to process remote ones
+            return Collections.emptyList();
+        }
 
         //requesting all remote with specific vni
         final MappingsDumpParams dumpParams = new MappingsDumpParamsBuilder()
-                .setVni(Long.valueOf(id.firstKeyOf(VniTable.class).getVirtualNetworkIdentifier()).intValue())
                 .setEidSet(QuantityType.ALL)
                 .setFilter(FilterType.REMOTE)
                 .build();
@@ -179,6 +187,7 @@ public class RemoteMappingCustomizer extends FutureJVppCustomizer
             return replyOptional.get()
                     .lispEidTableDetails
                     .stream()
+                    .filter(a -> a.vni == vni)
                     .map(detail -> new RemoteMappingKey(
                             new MappingId(
                                     remoteMappingContext.getId(
index 152210b..a533881 100755 (executable)
@@ -17,6 +17,7 @@
 package io.fd.honeycomb.lisp.translate.write;
 
 import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
 import static io.fd.honeycomb.translate.v3po.util.TranslateUtils.getReply;
 import static java.nio.charset.StandardCharsets.UTF_8;
 
@@ -26,19 +27,21 @@ import io.fd.honeycomb.lisp.translate.read.dump.executor.LocatorSetsDumpExecutor
 import io.fd.honeycomb.translate.ModificationCache;
 import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer;
 import io.fd.honeycomb.translate.util.RWUtils;
-import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer;
-import io.fd.honeycomb.translate.v3po.util.NamingContext;
-import io.fd.honeycomb.translate.v3po.util.TranslateUtils;
 import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager;
 import io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor;
 import io.fd.honeycomb.translate.util.read.cache.exceptions.execution.DumpExecutionFailedException;
+import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer;
+import io.fd.honeycomb.translate.v3po.util.NamingContext;
+import io.fd.honeycomb.translate.v3po.util.TranslateUtils;
 import io.fd.honeycomb.translate.write.WriteContext;
 import io.fd.honeycomb.translate.write.WriteFailedException;
 import java.io.UnsupportedEncodingException;
+import java.util.List;
 import java.util.concurrent.TimeoutException;
 import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.locator.sets.grouping.locator.sets.LocatorSet;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.locator.sets.grouping.locator.sets.LocatorSetKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.locator.sets.grouping.locator.sets.locator.set.Interface;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.openvpp.jvpp.VppBaseCallException;
 import org.openvpp.jvpp.core.dto.LispAddDelLocatorSet;
@@ -76,7 +79,8 @@ public class LocatorSetCustomizer extends FutureJVppCustomizer
 
         final String locatorSetName = dataAfter.getName();
         checkNotNull(locatorSetName, "LocatorSet name is null");
-
+        checkState(isNonEmptyLocatorSet(writeContext.readAfter(id).get()),
+                "Creating empty locator-sets is not allowed");
         // TODO VPP-323 check and fill mapping when api returns index of created locator set
         // checkState(!locatorSetContext.containsIndex(locatorSetName, writeContext.getMappingContext()),
         //         "Locator set with name %s allready defined", locatorSetName);
@@ -98,6 +102,11 @@ public class LocatorSetCustomizer extends FutureJVppCustomizer
         }
     }
 
+    private boolean isNonEmptyLocatorSet(final LocatorSet locatorSet) {
+        final List<Interface> locators = locatorSet.getInterface();
+        return locators != null && !locators.isEmpty();
+    }
+
     @Override
     public void updateCurrentAttributes(@Nonnull InstanceIdentifier<LocatorSet> id,
                                         @Nonnull LocatorSet dataBefore,
index 7193089..9ed1d53 100755 (executable)
@@ -24,6 +24,7 @@ import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableList;
 import io.fd.honeycomb.translate.MappingContext;
 import io.fd.honeycomb.translate.ModificationCache;
@@ -31,13 +32,18 @@ import io.fd.honeycomb.translate.v3po.util.NamingContext;
 import io.fd.honeycomb.translate.write.WriteContext;
 import io.fd.honeycomb.translate.write.WriteFailedException;
 import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.locator.sets.grouping.LocatorSets;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.locator.sets.grouping.locator.sets.LocatorSet;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.locator.sets.grouping.locator.sets.LocatorSetBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.locator.sets.grouping.locator.sets.LocatorSetKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.locator.sets.grouping.locator.sets.locator.set.InterfaceBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.openvpp.jvpp.core.dto.LispAddDelLocatorSet;
 import org.openvpp.jvpp.core.dto.LispAddDelLocatorSetReply;
 import org.openvpp.jvpp.core.dto.LispLocatorSetDetails;
@@ -81,8 +87,13 @@ public class LocatorSetCustomizerTest {
 
         LocatorSet locatorSet = new LocatorSetBuilder()
                 .setName("Locator")
+                .setInterface(Arrays.asList(new InterfaceBuilder().build()))
                 .build();
 
+        InstanceIdentifier<LocatorSet> validId =
+                InstanceIdentifier.create(LocatorSets.class).child(LocatorSet.class, new LocatorSetKey("Locator"));
+
+
         ArgumentCaptor<LispAddDelLocatorSet> locatorSetCaptor = ArgumentCaptor.forClass(LispAddDelLocatorSet.class);
 
         LispAddDelLocatorSetReply fakeReply = new LispAddDelLocatorSetReply();
@@ -91,6 +102,7 @@ public class LocatorSetCustomizerTest {
         completeFuture.complete(fakeReply);
 
         when(fakeJvpp.lispAddDelLocatorSet(any(LispAddDelLocatorSet.class))).thenReturn(completeFuture);
+        when(context.readAfter(validId)).thenReturn(Optional.of(locatorSet));
 
         final LispLocatorSetDetailsReplyDump reply = new LispLocatorSetDetailsReplyDump();
         LispLocatorSetDetails details = new LispLocatorSetDetails();
@@ -99,7 +111,7 @@ public class LocatorSetCustomizerTest {
 
         cache.put(io.fd.honeycomb.lisp.translate.read.LocatorSetCustomizer.LOCATOR_SETS_CACHE_ID, reply);
 
-        new LocatorSetCustomizer(fakeJvpp, locatorSetContext).writeCurrentAttributes(null, locatorSet, context);
+        new LocatorSetCustomizer(fakeJvpp, locatorSetContext).writeCurrentAttributes(validId, locatorSet, context);
 
         verify(fakeJvpp, times(1)).lispAddDelLocatorSet(locatorSetCaptor.capture());
 
index 95b0774..c1f17ea 100644 (file)
@@ -59,14 +59,14 @@ public final class TranslateUtils {
 
     public static <REP extends JVppReply<?>> REP getReplyForWrite(@Nonnull Future<REP> future,
                                                                   @Nonnull final InstanceIdentifier<?> replyType)
-        throws VppBaseCallException, WriteTimeoutException {
+            throws VppBaseCallException, WriteTimeoutException {
         return getReplyForWrite(future, replyType, DEFAULT_TIMEOUT_IN_SECONDS);
     }
 
     public static <REP extends JVppReply<?>> REP getReplyForWrite(@Nonnull Future<REP> future,
                                                                   @Nonnull final InstanceIdentifier<?> replyType,
                                                                   @Nonnegative final int timeoutInSeconds)
-        throws VppBaseCallException, WriteTimeoutException {
+            throws VppBaseCallException, WriteTimeoutException {
         try {
             return getReply(future, timeoutInSeconds);
         } catch (TimeoutException e) {
@@ -76,14 +76,14 @@ public final class TranslateUtils {
 
     public static <REP extends JVppReply<?>> REP getReplyForRead(@Nonnull Future<REP> future,
                                                                  @Nonnull final InstanceIdentifier<?> replyType)
-        throws VppBaseCallException, ReadTimeoutException {
+            throws VppBaseCallException, ReadTimeoutException {
         return getReplyForRead(future, replyType, DEFAULT_TIMEOUT_IN_SECONDS);
     }
 
     public static <REP extends JVppReply<?>> REP getReplyForRead(@Nonnull Future<REP> future,
                                                                  @Nonnull final InstanceIdentifier<?> replyType,
                                                                  @Nonnegative final int timeoutInSeconds)
-        throws VppBaseCallException, ReadTimeoutException {
+            throws VppBaseCallException, ReadTimeoutException {
         try {
             return getReply(future, timeoutInSeconds);
         } catch (TimeoutException e) {
@@ -92,13 +92,13 @@ public final class TranslateUtils {
     }
 
     public static <REP extends JVppReply<?>> REP getReply(@Nonnull Future<REP> future)
-        throws TimeoutException, VppBaseCallException {
+            throws TimeoutException, VppBaseCallException {
         return getReply(future, DEFAULT_TIMEOUT_IN_SECONDS);
     }
 
     public static <REP extends JVppReply<?>> REP getReply(@Nonnull Future<REP> future,
                                                           @Nonnegative final int timeoutInSeconds)
-        throws TimeoutException, VppBaseCallException {
+            throws TimeoutException, VppBaseCallException {
         try {
             checkArgument(timeoutInSeconds > 0, "Timeout cannot be < 0");
             return future.get(timeoutInSeconds, TimeUnit.SECONDS);
@@ -195,19 +195,19 @@ public final class TranslateUtils {
         //splits address and add ommited zeros for easier parsing
         List<String> segments = Arrays.asList(ipv6Addr.getValue().split(":"))
                 .stream()
-                .map(segment ->  StringUtils.repeat('0',4-segment.length())+segment)
+                .map(segment -> StringUtils.repeat('0', 4 - segment.length()) + segment)
                 .collect(Collectors.toList());
 
         byte index = 0;
         for (String segment : segments) {
 
-            String firstPart =segment.substring(0, 2);
+            String firstPart = segment.substring(0, 2);
             String secondPart = segment.substring(2);
 
             //first part should be ommited
-            if("00".equals(firstPart)){
+            if ("00".equals(firstPart)) {
                 index++;
-            }else{
+            } else {
                 retval[index++] = ((byte) Short.parseShort(firstPart, 16));
             }
 
@@ -312,16 +312,16 @@ public final class TranslateUtils {
 
     /**
      * Converts MAC string to byte array
-     * */
-    public static byte[] macToByteArray(String mac){
-        checkNotNull(mac,"MAC cannot be null");
+     */
+    public static byte[] macToByteArray(String mac) {
+        checkNotNull(mac, "MAC cannot be null");
 
-        mac = mac.replace(":","");
+        mac = mac.replace(":", "");
 
         try {
             return Hex.decodeHex(mac.toCharArray());
         } catch (DecoderException e) {
-            throw new IllegalArgumentException("Unable to convert mac",e);
+            throw new IllegalArgumentException("Unable to convert mac", e);
         }
     }
 
@@ -331,7 +331,7 @@ public final class TranslateUtils {
     public static boolean isIpv6(IpAddress address) {
         checkNotNull(address, "Address cannot be null");
 
-                checkState(!(address.getIpv4Address() == null && address.getIpv6Address() == null), "Invalid address");
+        checkState(!(address.getIpv4Address() == null && address.getIpv6Address() == null), "Invalid address");
         return address.getIpv6Address() != null;
     }
 
@@ -431,19 +431,19 @@ public final class TranslateUtils {
 
     private static byte[] parseMacLikeString(final List<String> strings) {
         return strings.stream().limit(6).map(TranslateUtils::parseHexByte).collect(
-            () -> new byte[strings.size()],
-            new BiConsumer<byte[], Byte>() {
+                () -> new byte[strings.size()],
+                new BiConsumer<byte[], Byte>() {
 
-                private int i = -1;
+                    private int i = -1;
 
-                @Override
-                public void accept(final byte[] bytes, final Byte aByte) {
-                    bytes[++i] = aByte;
-                }
-            },
-            (bytes, bytes2) -> {
-                throw new UnsupportedOperationException("Parallel collect not supported");
-            });
+                    @Override
+                    public void accept(final byte[] bytes, final Byte aByte) {
+                        bytes[++i] = aByte;
+                    }
+                },
+                (bytes, bytes2) -> {
+                    throw new UnsupportedOperationException("Parallel collect not supported");
+                });
     }
 
     public static byte parseHexByte(final String aByte) {
@@ -458,8 +458,8 @@ public final class TranslateUtils {
      */
     public static byte booleanToByte(@Nullable final Boolean value) {
         return value != null && value
-            ? (byte) 1
-            : (byte) 0;
+                ? (byte) 1
+                : (byte) 0;
     }
 
     /**
@@ -494,4 +494,9 @@ public final class TranslateUtils {
 
         return reversed;
     }
+
+    public static IpAddress reverseAddress(@Nonnull final IpAddress address) {
+        //arrayToIpAdddress internaly reverts order
+        return arrayToIpAddress(isIpv6(address), ipAddressToArray(address));
+    }
 }
index a55c305..3b7efbf 100644 (file)
@@ -1,5 +1,6 @@
 package io.fd.honeycomb.translate.v3po.util;
 
+import static io.fd.honeycomb.translate.v3po.util.TranslateUtils.reverseAddress;
 import static io.fd.honeycomb.translate.v3po.util.TranslateUtils.reverseBytes;
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
@@ -14,8 +15,11 @@ import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 import org.junit.Test;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6AddressNoZone;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
 import org.opendaylight.yangtools.yang.binding.DataContainer;
@@ -66,7 +70,7 @@ public class TranslateUtilsTest {
     public void testIpv4NoZone() throws Exception {
         final Ipv4AddressNoZone ipv4Addr = new Ipv4AddressNoZone("192.168.1.1");
         byte[] bytes = TranslateUtils.ipv4AddressNoZoneToArray(ipv4Addr);
-        assertEquals((byte)192, bytes[0]);
+        assertEquals((byte) 192, bytes[0]);
         // Simulating the magic of VPP
         bytes = reverseBytes(bytes);
         final Ipv4AddressNoZone ipv4AddressNoZone = TranslateUtils.arrayToIpv4AddressNoZone(bytes);
@@ -138,37 +142,37 @@ public class TranslateUtilsTest {
     }
 
     @Test
-    public void testIpv6NoZone(){
+    public void testIpv6NoZone() {
         final Ipv6AddressNoZone ipv6Addr = new Ipv6AddressNoZone("3ffe:1900:4545:3:200:f8ff:fe21:67cf");
         byte[] bytes = TranslateUtils.ipv6AddressNoZoneToArray(ipv6Addr);
-        assertEquals((byte)63,bytes[0]);
+        assertEquals((byte) 63, bytes[0]);
 
         bytes = reverseBytes(bytes);
         final Ipv6AddressNoZone ivp6AddressNoZone = TranslateUtils.arrayToIpv6AddressNoZone(bytes);
-        assertEquals(ipv6Addr,ivp6AddressNoZone);
+        assertEquals(ipv6Addr, ivp6AddressNoZone);
     }
 
     @Test
-    public void testByteArrayToMacUnseparated(){
+    public void testByteArrayToMacUnseparated() {
         byte[] address = TranslateUtils.parseMac("aa:bb:cc:dd:ee:ff");
 
         String converted = TranslateUtils.byteArrayToMacUnseparated(address);
 
-        assertEquals("aabbccddeeff",converted);
+        assertEquals("aabbccddeeff", converted);
     }
 
     @Test
-    public void testByteArrayToMacSeparated(){
+    public void testByteArrayToMacSeparated() {
         byte[] address = TranslateUtils.parseMac("aa:bb:cc:dd:ee:ff");
 
         String converted = TranslateUtils.byteArrayToMacSeparated(address);
 
-        assertEquals("aa:bb:cc:dd:ee:ff",converted);
+        assertEquals("aa:bb:cc:dd:ee:ff", converted);
     }
 
     @Test(expected = IllegalArgumentException.class)
-    public void testByteArrayToMacUnseparatedIllegal(){
-        TranslateUtils.byteArrayToMacUnseparated(new byte[]{54,26,87,32,14});
+    public void testByteArrayToMacUnseparatedIllegal() {
+        TranslateUtils.byteArrayToMacUnseparated(new byte[]{54, 26, 87, 32, 14});
     }
 
     @Test(expected = IllegalArgumentException.class)
@@ -195,4 +199,13 @@ public class TranslateUtilsTest {
         assertEquals(24, TranslateUtils.extractPrefix(new Ipv4Prefix("192.168.2.1/24")));
         assertEquals(48, TranslateUtils.extractPrefix(new Ipv6Prefix("3ffe:1900:4545:3:200:f8ff:fe21:67cf/48")));
     }
+
+    @Test
+    public void testRevertAddress() {
+        assertEquals("1.2.168.192",
+                reverseAddress(new IpAddress(new Ipv4Address("192.168.2.1"))).getIpv4Address().getValue());
+        assertEquals("3473:7003:2e8a::a385:b80d:120",
+                reverseAddress(new IpAddress(new Ipv6Address("2001:db8:85a3:0:0:8a2e:370:7334"))).getIpv6Address()
+                        .getValue());
+    }
 }
\ No newline at end of file