HC2VPP-384: Validation support for L3 module 43/17743/9
authorTibor Král <[email protected]>
Thu, 21 Feb 2019 08:48:36 +0000 (09:48 +0100)
committerTibor Král <[email protected]>
Thu, 28 Mar 2019 12:46:05 +0000 (13:46 +0100)
Change-Id: I9f4a856dc70a7ac2a3f8e103143ad15f05402f24
Signed-off-by: Tibor Král <[email protected]>
28 files changed:
l3/impl/src/main/java/io/fd/hc2vpp/l3/write/factory/Ipv4WriterFactory.java
l3/impl/src/main/java/io/fd/hc2vpp/l3/write/factory/Ipv6WriterFactory.java
l3/impl/src/main/java/io/fd/hc2vpp/l3/write/factory/ProxyArpWriterFactory.java
l3/impl/src/main/java/io/fd/hc2vpp/l3/write/factory/SubInterfaceIpv4WriterFactory.java
l3/impl/src/main/java/io/fd/hc2vpp/l3/write/factory/SubInterfaceIpv6WriterFactory.java
l3/impl/src/main/java/io/fd/hc2vpp/l3/write/ipv4/Ipv4AddressCustomizer.java
l3/impl/src/main/java/io/fd/hc2vpp/l3/write/ipv4/Ipv4AddressValidator.java [new file with mode: 0644]
l3/impl/src/main/java/io/fd/hc2vpp/l3/write/ipv4/Ipv4NeighbourValidator.java [new file with mode: 0644]
l3/impl/src/main/java/io/fd/hc2vpp/l3/write/ipv4/ProxyArpValidator.java [new file with mode: 0644]
l3/impl/src/main/java/io/fd/hc2vpp/l3/write/ipv4/ProxyRangeValidator.java [new file with mode: 0644]
l3/impl/src/main/java/io/fd/hc2vpp/l3/write/ipv4/subinterface/SubInterfaceIpv4AddressCustomizer.java
l3/impl/src/main/java/io/fd/hc2vpp/l3/write/ipv4/subinterface/SubInterfaceIpv4AddressValidator.java [new file with mode: 0644]
l3/impl/src/main/java/io/fd/hc2vpp/l3/write/ipv4/subinterface/SubInterfaceIpv4NeighbourValidator.java [new file with mode: 0644]
l3/impl/src/main/java/io/fd/hc2vpp/l3/write/ipv6/Ipv6AddressCustomizer.java
l3/impl/src/main/java/io/fd/hc2vpp/l3/write/ipv6/Ipv6AddressValidator.java [new file with mode: 0644]
l3/impl/src/main/java/io/fd/hc2vpp/l3/write/ipv6/Ipv6NeighbourCustomizer.java
l3/impl/src/main/java/io/fd/hc2vpp/l3/write/ipv6/Ipv6NeighbourValidator.java [new file with mode: 0644]
l3/impl/src/main/java/io/fd/hc2vpp/l3/write/ipv6/nd/NdProxyCustomizer.java
l3/impl/src/main/java/io/fd/hc2vpp/l3/write/ipv6/nd/NdProxyValidator.java [new file with mode: 0644]
l3/impl/src/main/java/io/fd/hc2vpp/l3/write/ipv6/subinterface/SubInterfaceIpv6AddressCustomizer.java
l3/impl/src/main/java/io/fd/hc2vpp/l3/write/ipv6/subinterface/SubInterfaceIpv6AddressValidator.java [new file with mode: 0644]
l3/impl/src/main/java/io/fd/hc2vpp/l3/write/ipv6/subinterface/SubInterfaceIpv6NeighbourValidator.java [new file with mode: 0644]
l3/impl/src/test/java/io/fd/hc2vpp/l3/write/ipv4/Ipv4AddressCustomizerTest.java
l3/impl/src/test/java/io/fd/hc2vpp/l3/write/ipv4/Ipv4AddressValidatorTest.java [new file with mode: 0644]
l3/impl/src/test/java/io/fd/hc2vpp/l3/write/ipv4/Ipv4NeighbourCustomizerTest.java
l3/impl/src/test/java/io/fd/hc2vpp/l3/write/ipv4/Ipv4NeighbourValidatorTest.java [new file with mode: 0644]
l3/impl/src/test/java/io/fd/hc2vpp/l3/write/ipv4/SubInterfaceIpv4AddressValidatorTest.java [new file with mode: 0644]
l3/impl/src/test/java/io/fd/hc2vpp/l3/write/ipv6/Ipv6NeighbourValidatorTest.java [new file with mode: 0644]

index 536dab3..ed6ef5e 100644 (file)
@@ -24,8 +24,10 @@ import com.google.inject.Inject;
 import com.google.inject.name.Named;
 import io.fd.hc2vpp.common.translate.util.NamingContext;
 import io.fd.hc2vpp.l3.write.ipv4.Ipv4AddressCustomizer;
+import io.fd.hc2vpp.l3.write.ipv4.Ipv4AddressValidator;
 import io.fd.hc2vpp.l3.write.ipv4.Ipv4Customizer;
 import io.fd.hc2vpp.l3.write.ipv4.Ipv4NeighbourCustomizer;
+import io.fd.hc2vpp.l3.write.ipv4.Ipv4NeighbourValidator;
 import io.fd.honeycomb.translate.impl.write.GenericListWriter;
 import io.fd.honeycomb.translate.impl.write.GenericWriter;
 import io.fd.honeycomb.translate.write.WriterFactory;
@@ -60,11 +62,11 @@ public class Ipv4WriterFactory implements WriterFactory {
                 ImmutableSet.of(IFC_ID, VPP_IFC_AUG_ID.child(Routing.class)));
         //  Address(after Ipv4) =
         final InstanceIdentifier<Address> ipv4AddressId = ipv4Id.child(Address.class);
-        registry.addAfter(new GenericListWriter<>(ipv4AddressId, new Ipv4AddressCustomizer(jvpp, ifcNamingContext)),
+        registry.addAfter(new GenericListWriter<>(ipv4AddressId, new Ipv4AddressCustomizer(jvpp, ifcNamingContext),
+                        new Ipv4AddressValidator(ifcNamingContext)),
                 ipv4Id);
         //  Neighbor(after ipv4Address)
         registry.addAfter(new GenericListWriter<>(ipv4Id.child(Neighbor.class), new Ipv4NeighbourCustomizer(jvpp,
-                ifcNamingContext)), ipv4AddressId);
+                ifcNamingContext), new Ipv4NeighbourValidator(ifcNamingContext)), ipv4AddressId);
     }
-
 }
index ad1a42c..2ed80a7 100644 (file)
@@ -24,9 +24,12 @@ import com.google.inject.Inject;
 import com.google.inject.name.Named;
 import io.fd.hc2vpp.common.translate.util.NamingContext;
 import io.fd.hc2vpp.l3.write.ipv6.Ipv6AddressCustomizer;
+import io.fd.hc2vpp.l3.write.ipv6.Ipv6AddressValidator;
 import io.fd.hc2vpp.l3.write.ipv6.Ipv6Customizer;
 import io.fd.hc2vpp.l3.write.ipv6.Ipv6NeighbourCustomizer;
+import io.fd.hc2vpp.l3.write.ipv6.Ipv6NeighbourValidator;
 import io.fd.hc2vpp.l3.write.ipv6.nd.NdProxyCustomizer;
+import io.fd.hc2vpp.l3.write.ipv6.nd.NdProxyValidator;
 import io.fd.honeycomb.translate.impl.write.GenericListWriter;
 import io.fd.honeycomb.translate.impl.write.GenericWriter;
 import io.fd.honeycomb.translate.write.WriterFactory;
@@ -68,14 +71,17 @@ public class Ipv6WriterFactory implements WriterFactory {
 
         final InstanceIdentifier<Address>
                 ipv6AddressId = ipv6Id.child(Address.class);
-        registry.addAfter(new GenericListWriter<>(ipv6AddressId, new Ipv6AddressCustomizer(jvpp, ifcNamingContext)),
+        registry.addAfter(new GenericListWriter<>(ipv6AddressId, new Ipv6AddressCustomizer(jvpp, ifcNamingContext),
+                        new Ipv6AddressValidator(ifcNamingContext)),
                 ipv6Id);
 
         registry.addAfter(new GenericListWriter<>(ipv6Id.child(Neighbor.class),
-                new Ipv6NeighbourCustomizer(jvpp, ifcNamingContext)), ipv6AddressId);
+                        new Ipv6NeighbourCustomizer(jvpp, ifcNamingContext), new Ipv6NeighbourValidator(ifcNamingContext)),
+                ipv6AddressId);
         //     ND Proxy
         final InstanceIdentifier<NdProxy> ndProxyId =
-            ipv6Id.augmentation(NdProxyIp6Augmentation.class).child(NdProxies.class).child(NdProxy.class);
-        registry.addAfter(new GenericListWriter<>(ndProxyId, new NdProxyCustomizer(jvpp, ifcNamingContext)), ipv6Id);
+                ipv6Id.augmentation(NdProxyIp6Augmentation.class).child(NdProxies.class).child(NdProxy.class);
+        registry.addAfter(new GenericListWriter<>(ndProxyId, new NdProxyCustomizer(jvpp, ifcNamingContext),
+                new NdProxyValidator(ifcNamingContext)), ipv6Id);
     }
 }
index 22109c3..b2c6c5c 100644 (file)
@@ -21,7 +21,9 @@ import com.google.inject.Inject;
 import com.google.inject.name.Named;
 import io.fd.hc2vpp.common.translate.util.NamingContext;
 import io.fd.hc2vpp.l3.write.ipv4.ProxyArpCustomizer;
+import io.fd.hc2vpp.l3.write.ipv4.ProxyArpValidator;
 import io.fd.hc2vpp.l3.write.ipv4.ProxyRangeCustomizer;
+import io.fd.hc2vpp.l3.write.ipv4.ProxyRangeValidator;
 import io.fd.honeycomb.translate.impl.write.GenericListWriter;
 import io.fd.honeycomb.translate.impl.write.GenericWriter;
 import io.fd.honeycomb.translate.write.WriterFactory;
@@ -38,11 +40,11 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 public final class ProxyArpWriterFactory implements WriterFactory {
 
     public static final InstanceIdentifier<ProxyRange> PROXY_RANGE_IID =
-        InstanceIdentifier.create(ProxyRanges.class).child(ProxyRange.class);
+            InstanceIdentifier.create(ProxyRanges.class).child(ProxyRange.class);
     private static final InstanceIdentifier<Interface>
-        IFC_ID = InstanceIdentifier.create(Interfaces.class).child(Interface.class);
+            IFC_ID = InstanceIdentifier.create(Interfaces.class).child(Interface.class);
     private static final InstanceIdentifier<ProxyArp> PROXY_ARP_IID =
-        IFC_ID.augmentation(ProxyArpInterfaceAugmentation.class).child(ProxyArp.class);
+            IFC_ID.augmentation(ProxyArpInterfaceAugmentation.class).child(ProxyArp.class);
 
     private final FutureJVppCore jvpp;
     private final NamingContext ifcNamingContext;
@@ -58,13 +60,15 @@ public final class ProxyArpWriterFactory implements WriterFactory {
     public void init(final ModifiableWriterRegistryBuilder registry) {
         // proxy-arp
         //  proxy-range =
-        registry.add(new GenericListWriter<>(PROXY_RANGE_IID, new ProxyRangeCustomizer(jvpp)));
+        registry.add(
+                new GenericListWriter<>(PROXY_RANGE_IID, new ProxyRangeCustomizer(jvpp), new ProxyRangeValidator()));
 
         // interfaces
         //  interface
         //   proxy-arp-interface-augmentation
         //    proxy-arp =
-        registry.addAfter(new GenericWriter<>(PROXY_ARP_IID, new ProxyArpCustomizer(jvpp, ifcNamingContext)),
-            Sets.newHashSet(PROXY_RANGE_IID, IFC_ID));
+        registry.addAfter(new GenericWriter<>(PROXY_ARP_IID, new ProxyArpCustomizer(jvpp, ifcNamingContext),
+                        new ProxyArpValidator(ifcNamingContext)),
+                Sets.newHashSet(PROXY_RANGE_IID, IFC_ID));
     }
 }
index f5d7dc5..831b160 100644 (file)
@@ -25,7 +25,9 @@ import com.google.inject.Inject;
 import com.google.inject.name.Named;
 import io.fd.hc2vpp.common.translate.util.NamingContext;
 import io.fd.hc2vpp.l3.write.ipv4.subinterface.SubInterfaceIpv4AddressCustomizer;
+import io.fd.hc2vpp.l3.write.ipv4.subinterface.SubInterfaceIpv4AddressValidator;
 import io.fd.hc2vpp.l3.write.ipv4.subinterface.SubInterfaceIpv4NeighbourCustomizer;
+import io.fd.hc2vpp.l3.write.ipv4.subinterface.SubInterfaceIpv4NeighbourValidator;
 import io.fd.honeycomb.translate.impl.write.GenericListWriter;
 import io.fd.honeycomb.translate.write.WriterFactory;
 import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder;
@@ -38,7 +40,7 @@ import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.su
 import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.routing.attributes.Routing;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
-public class SubInterfaceIpv4WriterFactory implements WriterFactory{
+public class SubInterfaceIpv4WriterFactory implements WriterFactory {
 
     @Inject
     private FutureJVppCore jvpp;
@@ -55,11 +57,13 @@ public class SubInterfaceIpv4WriterFactory implements WriterFactory{
         //   Ipv4(handled after L2 and L2/rewrite is done) =
         final InstanceIdentifier<Address> ipv4SubifcAddressId = SUB_IFC_ID.child(Ipv4.class).child(Address.class);
         registry.addAfter(new GenericListWriter<>(ipv4SubifcAddressId,
-                        new SubInterfaceIpv4AddressCustomizer(jvpp, ifcNamingContext)),
+                        new SubInterfaceIpv4AddressCustomizer(jvpp, ifcNamingContext),
+                        new SubInterfaceIpv4AddressValidator(ifcNamingContext)),
                 ImmutableSet.of(rewriteId, SUB_IFC_ID.child(Routing.class)));
         final InstanceIdentifier<Neighbor> ipv4NeighborId = SUB_IFC_ID.child(Ipv4.class).child(Neighbor.class);
         registry.addAfter(new GenericListWriter<>(ipv4NeighborId,
-                new SubInterfaceIpv4NeighbourCustomizer(jvpp, ifcNamingContext)), rewriteId);
+                new SubInterfaceIpv4NeighbourCustomizer(jvpp, ifcNamingContext),
+                new SubInterfaceIpv4NeighbourValidator(ifcNamingContext)), rewriteId);
 
     }
 }
index 4e1c679..a8a8e1d 100644 (file)
@@ -25,7 +25,9 @@ import com.google.inject.Inject;
 import com.google.inject.name.Named;
 import io.fd.hc2vpp.common.translate.util.NamingContext;
 import io.fd.hc2vpp.l3.write.ipv6.subinterface.SubInterfaceIpv6AddressCustomizer;
+import io.fd.hc2vpp.l3.write.ipv6.subinterface.SubInterfaceIpv6AddressValidator;
 import io.fd.hc2vpp.l3.write.ipv6.subinterface.SubInterfaceIpv6NeighbourCustomizer;
+import io.fd.hc2vpp.l3.write.ipv6.subinterface.SubInterfaceIpv6NeighbourValidator;
 import io.fd.honeycomb.translate.impl.write.GenericListWriter;
 import io.fd.honeycomb.translate.write.WriterFactory;
 import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder;
@@ -56,12 +58,14 @@ public class SubInterfaceIpv6WriterFactory implements WriterFactory {
                 ipv6SubifcAddressId = SUB_IFC_ID.child(Ipv6.class)
                 .child(org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.ip6.attributes.ipv6.Address.class);
         registry.addAfter(new GenericListWriter<>(ipv6SubifcAddressId,
-                new SubInterfaceIpv6AddressCustomizer(jvpp, ifcNamingContext)), ImmutableSet
+                new SubInterfaceIpv6AddressCustomizer(jvpp, ifcNamingContext),
+                new SubInterfaceIpv6AddressValidator(ifcNamingContext)), ImmutableSet
                 .of(rewriteId, SUB_IFC_ID.child(Routing.class)));
         final InstanceIdentifier<org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.ip6.attributes.ipv6.Neighbor>
                 ipv6NeighborId = SUB_IFC_ID.child(Ipv6.class)
                 .child(org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.ip6.attributes.ipv6.Neighbor.class);
         registry.addAfter(new GenericListWriter<>(ipv6NeighborId,
-                new SubInterfaceIpv6NeighbourCustomizer(jvpp, ifcNamingContext)), rewriteId);
+                new SubInterfaceIpv6NeighbourCustomizer(jvpp, ifcNamingContext),
+                new SubInterfaceIpv6NeighbourValidator(ifcNamingContext)), rewriteId);
     }
 }
index c3d5871..bb664c8 100644 (file)
@@ -16,8 +16,6 @@
 
 package io.fd.hc2vpp.l3.write.ipv4;
 
-import static com.google.common.base.Preconditions.checkNotNull;
-
 import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer;
 import io.fd.hc2vpp.common.translate.util.NamingContext;
 import io.fd.hc2vpp.l3.utils.ip.write.IpWriter;
@@ -49,7 +47,7 @@ public class Ipv4AddressCustomizer extends FutureJVppCustomizer
     public Ipv4AddressCustomizer(@Nonnull final FutureJVppCore futureJVppCore,
                                  @Nonnull final NamingContext interfaceContext) {
         super(futureJVppCore);
-        this.interfaceContext = checkNotNull(interfaceContext, "Interface context cannot be null");
+        this.interfaceContext = interfaceContext;
     }
 
     @Override
@@ -79,11 +77,8 @@ public class Ipv4AddressCustomizer extends FutureJVppCustomizer
 
         if (subnet instanceof PrefixLength) {
             setPrefixLengthSubnet(add, id, interfaceName, interfaceIndex, address, (PrefixLength) subnet);
-        } else if (subnet instanceof Netmask) {
-            setNetmaskSubnet(add, id, interfaceName, interfaceIndex, address, (Netmask) subnet);
         } else {
-            LOG.error("Unable to handle subnet of type {}", subnet);
-            throw new WriteFailedException(id, "Unable to handle subnet of type " + subnet.getClass());
+            setNetmaskSubnet(add, id, interfaceName, interfaceIndex, address, (Netmask) subnet);
         }
     }
 
@@ -96,8 +91,6 @@ public class Ipv4AddressCustomizer extends FutureJVppCustomizer
                 interfaceName, interfaceIndex, subnet, address);
 
         final DottedQuad netmask = subnet.getNetmask();
-        checkNotNull(netmask, "netmask value should not be null");
-
         final byte subnetLength = getSubnetMaskLength(netmask.getValue());
         addDelAddress(getFutureJVpp(), add, id, interfaceIndex, address.getIp(), subnetLength);
     }
diff --git a/l3/impl/src/main/java/io/fd/hc2vpp/l3/write/ipv4/Ipv4AddressValidator.java b/l3/impl/src/main/java/io/fd/hc2vpp/l3/write/ipv4/Ipv4AddressValidator.java
new file mode 100644 (file)
index 0000000..ae73052
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.hc2vpp.l3.write.ipv4;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.honeycomb.translate.write.DataValidationFailedException;
+import io.fd.honeycomb.translate.write.Validator;
+import io.fd.honeycomb.translate.write.WriteContext;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.Subnet;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.Netmask;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.PrefixLength;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class Ipv4AddressValidator implements Validator<Address> {
+
+    public Ipv4AddressValidator(@Nonnull final NamingContext interfaceContext) {
+
+        checkNotNull(interfaceContext, "Interface context cannot be null");
+    }
+
+    @Override
+    public void validateWrite(@Nonnull final InstanceIdentifier<Address> id, @Nonnull final Address dataAfter,
+                              @Nonnull final WriteContext writeContext)
+            throws DataValidationFailedException.CreateValidationFailedException {
+        checkAddress(dataAfter);
+    }
+
+    @Override
+    public void validateDelete(@Nonnull final InstanceIdentifier<Address> id, @Nonnull final Address dataBefore,
+                               @Nonnull final WriteContext writeContext)
+            throws DataValidationFailedException.DeleteValidationFailedException {
+        checkAddress(dataBefore);
+    }
+
+    private void checkAddress(final Address address) {
+        Subnet subnet = address.getSubnet();
+        if (subnet instanceof Netmask) {
+            checkNotNull(((Netmask) subnet).getNetmask(), "netmask value should not be null");
+        } else if (subnet instanceof PrefixLength == false) {
+            throw new IllegalArgumentException("Unable to handle subnet of type " + subnet);
+        }
+    }
+}
diff --git a/l3/impl/src/main/java/io/fd/hc2vpp/l3/write/ipv4/Ipv4NeighbourValidator.java b/l3/impl/src/main/java/io/fd/hc2vpp/l3/write/ipv4/Ipv4NeighbourValidator.java
new file mode 100644 (file)
index 0000000..b31695f
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.hc2vpp.l3.write.ipv4;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.honeycomb.translate.write.DataValidationFailedException;
+import io.fd.honeycomb.translate.write.Validator;
+import io.fd.honeycomb.translate.write.WriteContext;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Neighbor;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class Ipv4NeighbourValidator implements Validator<Neighbor> {
+
+    public Ipv4NeighbourValidator(final NamingContext ifcNamingContext) {
+        checkNotNull(ifcNamingContext, "Interface context cannot be null");
+    }
+
+    @Override
+    public void validateWrite(@Nonnull final InstanceIdentifier<Neighbor> id, @Nonnull final Neighbor dataAfter,
+                              @Nonnull final WriteContext writeContext)
+            throws DataValidationFailedException.CreateValidationFailedException {
+        checkNeighborData(id, dataAfter);
+
+    }
+
+    @Override
+    public void validateDelete(@Nonnull final InstanceIdentifier<Neighbor> id, @Nonnull final Neighbor dataBefore,
+                               @Nonnull final WriteContext writeContext)
+            throws DataValidationFailedException.DeleteValidationFailedException {
+        checkNeighborData(id, dataBefore);
+    }
+
+    private void checkNeighborData(final InstanceIdentifier<Neighbor> id, final Neighbor data) {
+        checkArgument(id.firstKeyOf(Interface.class) != null, "No parent interface key found");
+        checkNotNull(data.getIp(), "Neighbor IP address cannot be null");
+        checkNotNull(data.getLinkLayerAddress(), "Neighbor MAC acddress cannot be null");
+    }
+}
diff --git a/l3/impl/src/main/java/io/fd/hc2vpp/l3/write/ipv4/ProxyArpValidator.java b/l3/impl/src/main/java/io/fd/hc2vpp/l3/write/ipv4/ProxyArpValidator.java
new file mode 100644 (file)
index 0000000..84baf82
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.hc2vpp.l3.write.ipv4;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.honeycomb.translate.write.DataValidationFailedException;
+import io.fd.honeycomb.translate.write.Validator;
+import io.fd.honeycomb.translate.write.WriteContext;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.proxy.arp.rev180703.interfaces._interface.ProxyArp;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class ProxyArpValidator implements Validator<ProxyArp> {
+
+    public ProxyArpValidator(final NamingContext ifcNamingContext) {
+        checkNotNull(ifcNamingContext, "Interface context cannot be null");
+    }
+
+    @Override
+    public void validateWrite(@Nonnull final InstanceIdentifier<ProxyArp> id, @Nonnull final ProxyArp dataAfter,
+                              @Nonnull final WriteContext writeContext)
+            throws DataValidationFailedException.CreateValidationFailedException {
+        // there is nothing to validate yet
+    }
+
+    @Override
+    public void validateDelete(@Nonnull final InstanceIdentifier<ProxyArp> id, @Nonnull final ProxyArp dataBefore,
+                               @Nonnull final WriteContext writeContext)
+            throws DataValidationFailedException.DeleteValidationFailedException {
+        // there is nothing to validate yet
+    }
+}
diff --git a/l3/impl/src/main/java/io/fd/hc2vpp/l3/write/ipv4/ProxyRangeValidator.java b/l3/impl/src/main/java/io/fd/hc2vpp/l3/write/ipv4/ProxyRangeValidator.java
new file mode 100644 (file)
index 0000000..81376b6
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.hc2vpp.l3.write.ipv4;
+
+import io.fd.honeycomb.translate.write.DataValidationFailedException;
+import io.fd.honeycomb.translate.write.Validator;
+import io.fd.honeycomb.translate.write.WriteContext;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.proxy.arp.rev180703.proxy.ranges.ProxyRange;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class ProxyRangeValidator implements Validator<ProxyRange> {
+    @Override
+    public void validateWrite(@Nonnull final InstanceIdentifier<ProxyRange> id, @Nonnull final ProxyRange dataAfter,
+                              @Nonnull final WriteContext writeContext)
+            throws DataValidationFailedException.CreateValidationFailedException {
+        // there is nothing to validate yet
+    }
+
+    @Override
+    public void validateDelete(@Nonnull final InstanceIdentifier<ProxyRange> id, @Nonnull final ProxyRange dataBefore,
+                               @Nonnull final WriteContext writeContext)
+            throws DataValidationFailedException.DeleteValidationFailedException {
+        // there is nothing to validate yet
+    }
+}
index 91cd413..8cb9b8a 100644 (file)
@@ -16,8 +16,6 @@
 
 package io.fd.hc2vpp.l3.write.ipv4.subinterface;
 
-import static com.google.common.base.Preconditions.checkNotNull;
-
 import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer;
 import io.fd.hc2vpp.common.translate.util.NamingContext;
 import io.fd.hc2vpp.l3.utils.ip.write.IpWriter;
@@ -53,7 +51,7 @@ public class SubInterfaceIpv4AddressCustomizer extends FutureJVppCustomizer
     public SubInterfaceIpv4AddressCustomizer(@Nonnull final FutureJVppCore futureJVppCore,
                                              @Nonnull final NamingContext interfaceContext) {
         super(futureJVppCore);
-        this.interfaceContext = checkNotNull(interfaceContext, "interface context should not be null");
+        this.interfaceContext = interfaceContext;
     }
 
     @Override
@@ -79,11 +77,8 @@ public class SubInterfaceIpv4AddressCustomizer extends FutureJVppCustomizer
 
         if (subnet instanceof PrefixLength) {
             setPrefixLengthSubnet(add, id, interfaceName, subInterfaceIndex, address, (PrefixLength) subnet);
-        } else if (subnet instanceof Netmask) {
-            setNetmaskSubnet(add, id, interfaceName, subInterfaceIndex, address, (Netmask) subnet);
         } else {
-            LOG.error("Unable to handle subnet of type {}", subnet.getClass());
-            throw new WriteFailedException(id, "Unable to handle subnet of type " + subnet.getClass());
+            setNetmaskSubnet(add, id, interfaceName, subInterfaceIndex, address, (Netmask) subnet);
         }
     }
 
@@ -103,7 +98,6 @@ public class SubInterfaceIpv4AddressCustomizer extends FutureJVppCustomizer
                 subInterfaceName, subInterfaceIndex, subnet, address);
 
         final DottedQuad netmask = subnet.getNetmask();
-        checkNotNull(netmask, "netmask value should not be null");
 
         final byte subnetLength = getSubnetMaskLength(netmask.getValue());
         addDelAddress(getFutureJVpp(), add, id, subInterfaceIndex, address.getIp(), subnetLength);
diff --git a/l3/impl/src/main/java/io/fd/hc2vpp/l3/write/ipv4/subinterface/SubInterfaceIpv4AddressValidator.java b/l3/impl/src/main/java/io/fd/hc2vpp/l3/write/ipv4/subinterface/SubInterfaceIpv4AddressValidator.java
new file mode 100644 (file)
index 0000000..c062e57
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.hc2vpp.l3.write.ipv4.subinterface;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.honeycomb.translate.write.DataValidationFailedException;
+import io.fd.honeycomb.translate.write.Validator;
+import io.fd.honeycomb.translate.write.WriteContext;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.ip4.attributes.ipv4.Address;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.ip4.attributes.ipv4.address.Subnet;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.ip4.attributes.ipv4.address.subnet.Netmask;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.ip4.attributes.ipv4.address.subnet.PrefixLength;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DottedQuad;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SubInterfaceIpv4AddressValidator implements Validator<Address> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceIpv4AddressValidator.class);
+
+    public SubInterfaceIpv4AddressValidator(final NamingContext ifcNamingContext) {
+        checkNotNull(ifcNamingContext, "interface context should not be null");
+    }
+
+    @Override
+    public void validateWrite(@Nonnull final InstanceIdentifier<Address> id, @Nonnull final Address dataAfter,
+                              @Nonnull final WriteContext writeContext)
+            throws DataValidationFailedException.CreateValidationFailedException {
+        checkAddress(dataAfter);
+    }
+
+    @Override
+    public void validateDelete(@Nonnull final InstanceIdentifier<Address> id, @Nonnull final Address dataBefore,
+                               @Nonnull final WriteContext writeContext)
+            throws DataValidationFailedException.DeleteValidationFailedException {
+        checkAddress(dataBefore);
+    }
+
+    private void checkAddress(final Address data) {
+        Subnet subnet = checkNotNull(data.getSubnet(), "Subnet should not be null");
+
+        if (subnet instanceof Netmask) {
+            checkNetmask(((Netmask) subnet).getNetmask());
+        } else if (!(subnet instanceof PrefixLength)) {
+            LOG.error("Unable to handle subnet of type {}", subnet);
+            throw new IllegalArgumentException("Unable to handle subnet of type " + subnet.getClass());
+        }
+    }
+
+    private void checkNetmask(final DottedQuad netmask) {
+        checkNotNull(netmask, "netmask value should not be null");
+    }
+}
diff --git a/l3/impl/src/main/java/io/fd/hc2vpp/l3/write/ipv4/subinterface/SubInterfaceIpv4NeighbourValidator.java b/l3/impl/src/main/java/io/fd/hc2vpp/l3/write/ipv4/subinterface/SubInterfaceIpv4NeighbourValidator.java
new file mode 100644 (file)
index 0000000..626338b
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.hc2vpp.l3.write.ipv4.subinterface;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.honeycomb.translate.write.DataValidationFailedException;
+import io.fd.honeycomb.translate.write.Validator;
+import io.fd.honeycomb.translate.write.WriteContext;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.ip4.attributes.ipv4.Neighbor;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class SubInterfaceIpv4NeighbourValidator implements Validator<Neighbor> {
+    public SubInterfaceIpv4NeighbourValidator(final NamingContext ifcNamingContext) {
+        checkNotNull(ifcNamingContext, "interface context should not be null");
+    }
+
+    @Override
+    public void validateWrite(@Nonnull final InstanceIdentifier<Neighbor> id, @Nonnull final Neighbor dataAfter,
+                              @Nonnull final WriteContext writeContext)
+            throws DataValidationFailedException.CreateValidationFailedException {
+        // there is nothing to validate yet
+    }
+
+    @Override
+    public void validateDelete(@Nonnull final InstanceIdentifier<Neighbor> id, @Nonnull final Neighbor dataBefore,
+                               @Nonnull final WriteContext writeContext)
+            throws DataValidationFailedException.DeleteValidationFailedException {
+        // there is nothing to validate yet
+    }
+}
index 4dd8d56..b3980b4 100644 (file)
@@ -16,8 +16,6 @@
 
 package io.fd.hc2vpp.l3.write.ipv6;
 
-import static com.google.common.base.Preconditions.checkNotNull;
-
 import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer;
 import io.fd.hc2vpp.common.translate.util.NamingContext;
 import io.fd.hc2vpp.l3.utils.ip.write.IpWriter;
@@ -45,7 +43,7 @@ public class Ipv6AddressCustomizer extends FutureJVppCustomizer
     public Ipv6AddressCustomizer(@Nonnull final FutureJVppCore futureJVppCore,
                                  @Nonnull final NamingContext interfaceContext) {
         super(futureJVppCore);
-        this.interfaceContext = checkNotNull(interfaceContext, "Interface context cannot be null");
+        this.interfaceContext = interfaceContext;
     }
 
     @Override
diff --git a/l3/impl/src/main/java/io/fd/hc2vpp/l3/write/ipv6/Ipv6AddressValidator.java b/l3/impl/src/main/java/io/fd/hc2vpp/l3/write/ipv6/Ipv6AddressValidator.java
new file mode 100644 (file)
index 0000000..28f4550
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.hc2vpp.l3.write.ipv6;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.honeycomb.translate.write.DataValidationFailedException;
+import io.fd.honeycomb.translate.write.Validator;
+import io.fd.honeycomb.translate.write.WriteContext;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv6.Address;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class Ipv6AddressValidator implements Validator<Address> {
+
+    public Ipv6AddressValidator(final NamingContext ifcNamingContext) {
+        checkNotNull(ifcNamingContext, "Interface context cannot be null");
+    }
+
+    @Override
+    public void validateWrite(@Nonnull final InstanceIdentifier<Address> id, @Nonnull final Address dataAfter,
+                              @Nonnull final WriteContext writeContext)
+            throws DataValidationFailedException.CreateValidationFailedException {
+        // there is nothing to validate yet
+    }
+
+    @Override
+    public void validateDelete(@Nonnull final InstanceIdentifier<Address> id, @Nonnull final Address dataBefore,
+                               @Nonnull final WriteContext writeContext)
+            throws DataValidationFailedException.DeleteValidationFailedException {
+        // there is nothing to validate yet
+    }
+}
index 09376d6..8c5fa9e 100644 (file)
@@ -16,8 +16,6 @@
 
 package io.fd.hc2vpp.l3.write.ipv6;
 
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.base.Preconditions.checkState;
 
 import io.fd.hc2vpp.common.translate.util.AddressTranslator;
@@ -58,9 +56,6 @@ public class Ipv6NeighbourCustomizer extends FutureJVppCustomizer
                                        @Nonnull WriteContext writeContext)
             throws WriteFailedException {
 
-        checkNotNull(dataAfter, "Cannot write null neighbour");
-        checkArgument(id.firstKeyOf(Interface.class) != null, "No parent interface key found");
-
         LOG.debug("Processing request for Neighbour write");
         String interfaceName = id.firstKeyOf(Interface.class).getName();
         MappingContext mappingContext = writeContext.getMappingContext();
@@ -78,9 +73,6 @@ public class Ipv6NeighbourCustomizer extends FutureJVppCustomizer
                                         @Nonnull WriteContext writeContext)
             throws WriteFailedException {
 
-        checkNotNull(dataBefore, "Cannot delete null neighbour");
-        checkArgument(id.firstKeyOf(Interface.class) != null, "No parent interface key found");
-
         LOG.debug("Processing request for Neighbour delete");
         String interfaceName = id.firstKeyOf(Interface.class).getName();
         MappingContext mappingContext = writeContext.getMappingContext();
@@ -89,7 +81,6 @@ public class Ipv6NeighbourCustomizer extends FutureJVppCustomizer
                 "Mapping does not contains mapping for provider interface name %s", interfaceName);
 
         LOG.debug("Parent interface[{}] index found", interfaceName);
-
         addDelNeighbourAndReply(id, false, interfaceContext.getIndex(interfaceName, mappingContext), dataBefore);
         LOG.debug("Neighbour {} successfully deleted", id);
     }
diff --git a/l3/impl/src/main/java/io/fd/hc2vpp/l3/write/ipv6/Ipv6NeighbourValidator.java b/l3/impl/src/main/java/io/fd/hc2vpp/l3/write/ipv6/Ipv6NeighbourValidator.java
new file mode 100644 (file)
index 0000000..f132ead
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.hc2vpp.l3.write.ipv6;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.honeycomb.translate.write.DataValidationFailedException;
+import io.fd.honeycomb.translate.write.Validator;
+import io.fd.honeycomb.translate.write.WriteContext;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv6.Neighbor;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class Ipv6NeighbourValidator implements Validator<Neighbor> {
+
+    final NamingContext interfaceContext;
+
+    public Ipv6NeighbourValidator(final NamingContext ifcNamingContext) {
+        interfaceContext = checkNotNull(ifcNamingContext, "Interface context cannot be null");
+    }
+
+    @Override
+    public void validateWrite(@Nonnull final InstanceIdentifier<Neighbor> id, @Nonnull final Neighbor dataAfter,
+                              @Nonnull final WriteContext writeContext)
+            throws DataValidationFailedException.CreateValidationFailedException {
+        testNeighbor(id, dataAfter);
+    }
+
+    @Override
+    public void validateDelete(@Nonnull final InstanceIdentifier<Neighbor> id, @Nonnull final Neighbor dataBefore,
+                               @Nonnull final WriteContext writeContext)
+            throws DataValidationFailedException.DeleteValidationFailedException {
+        testNeighbor(id, dataBefore);
+    }
+
+    private void testNeighbor(final InstanceIdentifier<Neighbor> id, final Neighbor data) {
+        checkArgument(id.firstKeyOf(Interface.class) != null, "No parent interface key found");
+        checkNotNull(data.getIp(), "Neighbor IP address cannot be null");
+        checkNotNull(data.getLinkLayerAddress(), "Neighbor MAC acddress cannot be null");
+    }
+}
index 545c75c..12ea73c 100644 (file)
@@ -16,8 +16,6 @@
 
 package io.fd.hc2vpp.l3.write.ipv6.nd;
 
-import static com.google.common.base.Preconditions.checkNotNull;
-
 import io.fd.hc2vpp.common.translate.util.AddressTranslator;
 import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer;
 import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer;
@@ -38,7 +36,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public final class NdProxyCustomizer extends FutureJVppCustomizer
-    implements ListWriterCustomizer<NdProxy, NdProxyKey>, AddressTranslator, JvppReplyConsumer {
+        implements ListWriterCustomizer<NdProxy, NdProxyKey>, AddressTranslator, JvppReplyConsumer {
 
     private static final Logger LOG = LoggerFactory.getLogger(NdProxyCustomizer.class);
     private final NamingContext interfaceContext;
@@ -46,7 +44,7 @@ public final class NdProxyCustomizer extends FutureJVppCustomizer
     public NdProxyCustomizer(@Nonnull final FutureJVppCore futureJVppCore,
                              @Nonnull final NamingContext interfaceContext) {
         super(futureJVppCore);
-        this.interfaceContext = checkNotNull(interfaceContext, "Interface context cannot be null");
+        this.interfaceContext = interfaceContext;
     }
 
     @Override
@@ -66,12 +64,12 @@ public final class NdProxyCustomizer extends FutureJVppCustomizer
         final int swIfIndex = interfaceContext.getIndex(interfaceName, writeContext.getMappingContext());
         addDelNdProxy(id, swIfIndex, dataBefore.getAddress(), false);
         LOG.debug("ND proxy was successfully removed from interface {}(id={}): {}", interfaceName, swIfIndex,
-            dataBefore);
+                dataBefore);
     }
 
     private void addDelNdProxy(final InstanceIdentifier<NdProxy> id, final int swIfIndex,
                                final Ipv6AddressNoZone address, final boolean add)
-        throws WriteFailedException {
+            throws WriteFailedException {
 
         final byte[] addressBytes = ipv6AddressNoZoneToArray(address);
 
diff --git a/l3/impl/src/main/java/io/fd/hc2vpp/l3/write/ipv6/nd/NdProxyValidator.java b/l3/impl/src/main/java/io/fd/hc2vpp/l3/write/ipv6/nd/NdProxyValidator.java
new file mode 100644 (file)
index 0000000..c20252e
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.hc2vpp.l3.write.ipv6.nd;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.honeycomb.translate.write.DataValidationFailedException;
+import io.fd.honeycomb.translate.write.Validator;
+import io.fd.honeycomb.translate.write.WriteContext;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.nd.proxy.rev170315.interfaces._interface.ipv6.nd.proxies.NdProxy;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class NdProxyValidator implements Validator<NdProxy> {
+
+    public NdProxyValidator(final NamingContext ifcNamingContext) {
+        checkNotNull(ifcNamingContext, "Interface context cannot be null");
+    }
+
+    @Override
+    public void validateWrite(@Nonnull final InstanceIdentifier<NdProxy> id, @Nonnull final NdProxy dataAfter,
+                              @Nonnull final WriteContext writeContext)
+            throws DataValidationFailedException.CreateValidationFailedException {
+        // there is nothing to validate yet
+    }
+
+    @Override
+    public void validateDelete(@Nonnull final InstanceIdentifier<NdProxy> id, @Nonnull final NdProxy dataBefore,
+                               @Nonnull final WriteContext writeContext)
+            throws DataValidationFailedException.DeleteValidationFailedException {
+        // there is nothing to validate yet
+    }
+}
index 3ae30f5..8ea8ced 100644 (file)
@@ -17,8 +17,6 @@
 package io.fd.hc2vpp.l3.write.ipv6.subinterface;
 
 
-import static com.google.common.base.Preconditions.checkNotNull;
-
 import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer;
 import io.fd.hc2vpp.common.translate.util.NamingContext;
 import io.fd.hc2vpp.l3.utils.ip.write.IpWriter;
@@ -39,7 +37,7 @@ public class SubInterfaceIpv6AddressCustomizer extends FutureJVppCustomizer
     public SubInterfaceIpv6AddressCustomizer(@Nonnull final FutureJVppCore futureJVppCore,
                                              @Nonnull final NamingContext interfaceContext) {
         super(futureJVppCore);
-        this.interfaceContext = checkNotNull(interfaceContext, "interface context should not be null");
+        this.interfaceContext = interfaceContext;
     }
 
     @Override
diff --git a/l3/impl/src/main/java/io/fd/hc2vpp/l3/write/ipv6/subinterface/SubInterfaceIpv6AddressValidator.java b/l3/impl/src/main/java/io/fd/hc2vpp/l3/write/ipv6/subinterface/SubInterfaceIpv6AddressValidator.java
new file mode 100644 (file)
index 0000000..42d7869
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.hc2vpp.l3.write.ipv6.subinterface;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.honeycomb.translate.write.DataValidationFailedException;
+import io.fd.honeycomb.translate.write.Validator;
+import io.fd.honeycomb.translate.write.WriteContext;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.ip6.attributes.ipv6.Address;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class SubInterfaceIpv6AddressValidator implements Validator<Address> {
+
+    public SubInterfaceIpv6AddressValidator(final NamingContext ifcNamingContext) {
+        checkNotNull(ifcNamingContext, "interface context should not be null");
+    }
+
+    @Override
+    public void validateWrite(@Nonnull final InstanceIdentifier<Address> id, @Nonnull final Address dataAfter,
+                              @Nonnull final WriteContext writeContext)
+            throws DataValidationFailedException.CreateValidationFailedException {
+        // there is nothing to validate yet
+    }
+
+    @Override
+    public void validateDelete(@Nonnull final InstanceIdentifier<Address> id, @Nonnull final Address dataBefore,
+                               @Nonnull final WriteContext writeContext)
+            throws DataValidationFailedException.DeleteValidationFailedException {
+        // there is nothing to validate yet
+    }
+}
diff --git a/l3/impl/src/main/java/io/fd/hc2vpp/l3/write/ipv6/subinterface/SubInterfaceIpv6NeighbourValidator.java b/l3/impl/src/main/java/io/fd/hc2vpp/l3/write/ipv6/subinterface/SubInterfaceIpv6NeighbourValidator.java
new file mode 100644 (file)
index 0000000..0207b14
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.hc2vpp.l3.write.ipv6.subinterface;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.honeycomb.translate.write.DataValidationFailedException;
+import io.fd.honeycomb.translate.write.Validator;
+import io.fd.honeycomb.translate.write.WriteContext;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.ip6.attributes.ipv6.Neighbor;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class SubInterfaceIpv6NeighbourValidator implements Validator<Neighbor> {
+
+    public SubInterfaceIpv6NeighbourValidator(final NamingContext ifcNamingContext) {
+        checkNotNull(ifcNamingContext, "interface context should not be null");
+    }
+
+    @Override
+    public void validateWrite(@Nonnull final InstanceIdentifier<Neighbor> id, @Nonnull final Neighbor dataAfter,
+                              @Nonnull final WriteContext writeContext)
+            throws DataValidationFailedException.CreateValidationFailedException {
+        // there is nothing to validate yet
+    }
+
+    @Override
+    public void validateDelete(@Nonnull final InstanceIdentifier<Neighbor> id, @Nonnull final Neighbor dataBefore,
+                               @Nonnull final WriteContext writeContext)
+            throws DataValidationFailedException.DeleteValidationFailedException {
+        // there is nothing to validate yet
+    }
+}
index 292fbdf..9e91e9e 100644 (file)
@@ -58,7 +58,7 @@ public class Ipv4AddressCustomizerTest extends WriterCustomizerTest {
     private NamingContext interfaceContext;
     private Ipv4AddressCustomizer customizer;
 
-    private static InstanceIdentifier<Address> getAddressId(final String ifaceName) {
+    static InstanceIdentifier<Address> getAddressId(final String ifaceName) {
         return InstanceIdentifier.builder(Interfaces.class)
                 .child(Interface.class, new InterfaceKey(ifaceName))
                 .augmentation(Interface1.class)
@@ -83,7 +83,8 @@ public class Ipv4AddressCustomizerTest extends WriterCustomizerTest {
     }
 
     private void whenSwInterfaceAddDelAddressThenSuccess() {
-        doReturn(future(new SwInterfaceAddDelAddressReply())).when(api).swInterfaceAddDelAddress(any(SwInterfaceAddDelAddress.class));
+        doReturn(future(new SwInterfaceAddDelAddressReply())).when(api)
+                .swInterfaceAddDelAddress(any(SwInterfaceAddDelAddress.class));
     }
 
     private void whenSwInterfaceAddDelAddressThenFailure() {
@@ -130,7 +131,7 @@ public class Ipv4AddressCustomizerTest extends WriterCustomizerTest {
         fail("WriteFailedException was expected");
     }
 
-    @Test(expected =  UnsupportedOperationException.class)
+    @Test(expected = UnsupportedOperationException.class)
     public void testUpdate() throws Exception {
         final Address data = mock(Address.class);
         customizer.updateCurrentAttributes(getAddressId(IFACE_NAME), data, data, writeContext);
@@ -206,7 +207,7 @@ public class Ipv4AddressCustomizerTest extends WriterCustomizerTest {
         } catch (WriteFailedException e) {
             assertTrue(e.getCause() instanceof VppBaseCallException);
             verify(api).swInterfaceAddDelAddress(generateSwInterfaceAddDelAddressRequest(new byte[]{-64, -88, 2, 1},
-                (byte) 1, (byte) expectedPrefixLength));
+                    (byte) 1, (byte) expectedPrefixLength));
             return;
         }
         fail("WriteFailedException was expec16ted");
@@ -226,7 +227,7 @@ public class Ipv4AddressCustomizerTest extends WriterCustomizerTest {
         customizer.writeCurrentAttributes(id, data, writeContext);
 
         verify(api).swInterfaceAddDelAddress(generateSwInterfaceAddDelAddressRequest(new byte[]{-64, -88, 2, 1},
-            (byte) 1, (byte) expectedPrefixLength));
+                (byte) 1, (byte) expectedPrefixLength));
     }
 
     private void testSingleIllegalNetmask(final String stringMask) throws Exception {
diff --git a/l3/impl/src/test/java/io/fd/hc2vpp/l3/write/ipv4/Ipv4AddressValidatorTest.java b/l3/impl/src/test/java/io/fd/hc2vpp/l3/write/ipv4/Ipv4AddressValidatorTest.java
new file mode 100644 (file)
index 0000000..5b7d56e
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.hc2vpp.l3.write.ipv4;
+
+import static org.mockito.MockitoAnnotations.initMocks;
+
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.honeycomb.translate.write.DataValidationFailedException;
+import io.fd.honeycomb.translate.write.WriteContext;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+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.ip.rev140616.interfaces._interface.ipv4.Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.AddressBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.Subnet;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.Netmask;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.NetmaskBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.PrefixLength;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.PrefixLengthBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DottedQuad;
+
+public class Ipv4AddressValidatorTest {
+
+    private Ipv4AddressValidator validator;
+    private static final String IFC_NAME = "tapTest";
+    private static final String IP_ADDR = "192.168.2.1";
+
+    @Mock
+    private WriteContext writeContext;
+
+    @Before
+    public void setUp() {
+        initMocks(this);
+        NamingContext ifcContext = new NamingContext("testInterfaceContext", "testInterfaceContext");
+        validator = new Ipv4AddressValidator(ifcContext);
+    }
+
+    @Test
+    public void testWriteSuccessful()
+            throws DataValidationFailedException.CreateValidationFailedException {
+        PrefixLength length = new PrefixLengthBuilder().setPrefixLength(new Integer(24).shortValue()).build();
+        validator.validateWrite(Ipv4AddressCustomizerTest.getAddressId(IFC_NAME), createAddress(length), writeContext);
+    }
+
+    @Test
+    public void testDeleteSuccessful()
+            throws DataValidationFailedException.DeleteValidationFailedException {
+        PrefixLength length = new PrefixLengthBuilder().setPrefixLength(new Integer(24).shortValue()).build();
+        validator.validateDelete(Ipv4AddressCustomizerTest.getAddressId(IFC_NAME), createAddress(length), writeContext);
+    }
+
+    @Test
+    public void testWriteNetmaskSuccessful()
+            throws DataValidationFailedException.CreateValidationFailedException {
+        Netmask netmask = new NetmaskBuilder().setNetmask(new DottedQuad(IP_ADDR)).build();
+        validator.validateWrite(Ipv4AddressCustomizerTest.getAddressId(IFC_NAME), createAddress(netmask), writeContext);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testWriteNetmaskFailed()
+            throws DataValidationFailedException.CreateValidationFailedException {
+        validator.validateWrite(Ipv4AddressCustomizerTest.getAddressId(IFC_NAME), createAddress(null), writeContext);
+    }
+
+    private Address createAddress(Subnet subnet) {
+        Ipv4AddressNoZone noZoneIp = new Ipv4AddressNoZone(new Ipv4Address(IP_ADDR));
+        return new AddressBuilder().setIp(noZoneIp).setSubnet(subnet).build();
+    }
+}
index 4c400f7..0202938 100644 (file)
@@ -56,8 +56,8 @@ public class Ipv4NeighbourCustomizerTest extends WriterCustomizerTest implements
     private static final String IFACE_NAME = "parent";
     private static final int IFACE_ID = 5;
     private static final InstanceIdentifier<Neighbor> IID =
-        InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IFACE_NAME))
-            .augmentation(Interface1.class).child(Ipv4.class).child(Neighbor.class);
+            InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IFACE_NAME))
+                    .augmentation(Interface1.class).child(Ipv4.class).child(Neighbor.class);
 
     private Ipv4NeighbourCustomizer customizer;
 
@@ -86,6 +86,7 @@ public class Ipv4NeighbourCustomizerTest extends WriterCustomizerTest implements
         }
         fail("WriteFailedException expected");
     }
+
     @Test(expected = UnsupportedOperationException.class)
     public void testUpdateCurrentAttributes() throws WriteFailedException {
         customizer.updateCurrentAttributes(IID, getData(), getData(), writeContext);
@@ -125,6 +126,7 @@ public class Ipv4NeighbourCustomizerTest extends WriterCustomizerTest implements
         final PhysAddress mac = new PhysAddress("aa:bb:cc:ee:11:22");
         return new NeighborBuilder().setIp(noZoneIp).setLinkLayerAddress(mac).build();
     }
+
     private IpNeighborAddDel getExpectedRequest(final boolean isAdd) {
         final IpNeighborAddDel request = new IpNeighborAddDel();
         request.neighbor = new IpNeighbor();
@@ -142,4 +144,4 @@ public class Ipv4NeighbourCustomizerTest extends WriterCustomizerTest implements
         request.neighbor.swIfIndex = IFACE_ID;
         return request;
     }
-}
\ No newline at end of file
+}
diff --git a/l3/impl/src/test/java/io/fd/hc2vpp/l3/write/ipv4/Ipv4NeighbourValidatorTest.java b/l3/impl/src/test/java/io/fd/hc2vpp/l3/write/ipv4/Ipv4NeighbourValidatorTest.java
new file mode 100644 (file)
index 0000000..20826bb
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.hc2vpp.l3.write.ipv4;
+
+import static org.mockito.MockitoAnnotations.initMocks;
+
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.honeycomb.translate.write.DataValidationFailedException;
+import io.fd.honeycomb.translate.write.WriteContext;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+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.interfaces.rev140508.Interfaces;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface1;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Neighbor;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.NeighborBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class Ipv4NeighbourValidatorTest {
+
+    private Ipv4NeighbourValidator validator;
+    private static final String IFACE_NAME = "parent";
+    private static final String MAC_ADDR = "aa:bb:cc:ee:11:22";
+    private static final String IP_ADDR = "192.168.2.1";
+
+    private static final InstanceIdentifier<Neighbor> IID =
+            InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IFACE_NAME))
+                    .augmentation(Interface1.class).child(Ipv4.class).child(Neighbor.class);
+
+    @Mock
+    private WriteContext writeContext;
+
+    @Before
+    public void setUp() {
+        initMocks(this);
+        NamingContext ifcContext = new NamingContext("testInterfaceContext", "testInterfaceContext");
+        validator = new Ipv4NeighbourValidator(ifcContext);
+    }
+
+    @Test
+    public void testWriteSuccessful()
+            throws DataValidationFailedException.CreateValidationFailedException {
+        validator.validateWrite(IID, getNeighbor(IP_ADDR, MAC_ADDR), writeContext);
+    }
+
+    @Test
+    public void testDeleteSuccessful()
+            throws DataValidationFailedException.DeleteValidationFailedException {
+        validator.validateDelete(IID, getNeighbor(IP_ADDR, MAC_ADDR), writeContext);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testWriteFailedMissingIP()
+            throws DataValidationFailedException.CreateValidationFailedException {
+        validator.validateWrite(IID, getNeighbor("", MAC_ADDR), writeContext);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testWriteFailedMissingMAC()
+            throws DataValidationFailedException.CreateValidationFailedException {
+        validator.validateWrite(IID, getNeighbor(IP_ADDR, ""), writeContext);
+    }
+
+    private Neighbor getNeighbor(String ipAddress, String macAddr) {
+        final Ipv4AddressNoZone noZoneIp = ipAddress.isEmpty()
+                ? null
+                : new Ipv4AddressNoZone(new Ipv4Address(ipAddress));
+        final PhysAddress mac = macAddr.isEmpty()
+                ? null
+                : new PhysAddress(macAddr);
+        return new NeighborBuilder().setIp(noZoneIp).setLinkLayerAddress(mac).build();
+    }
+}
diff --git a/l3/impl/src/test/java/io/fd/hc2vpp/l3/write/ipv4/SubInterfaceIpv4AddressValidatorTest.java b/l3/impl/src/test/java/io/fd/hc2vpp/l3/write/ipv4/SubInterfaceIpv4AddressValidatorTest.java
new file mode 100644 (file)
index 0000000..1070227
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.hc2vpp.l3.write.ipv4;
+
+import static org.mockito.MockitoAnnotations.initMocks;
+
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.hc2vpp.l3.write.ipv4.subinterface.SubInterfaceIpv4AddressValidator;
+import io.fd.honeycomb.translate.write.DataValidationFailedException;
+import io.fd.honeycomb.translate.write.WriteContext;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.SubinterfaceAugmentation;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.interfaces._interface.SubInterfaces;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.interfaces._interface.sub.interfaces.SubInterface;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.interfaces._interface.sub.interfaces.SubInterfaceKey;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.ip4.attributes.ipv4.Address;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.ip4.attributes.ipv4.AddressBuilder;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.ip4.attributes.ipv4.address.Subnet;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.ip4.attributes.ipv4.address.subnet.Netmask;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.ip4.attributes.ipv4.address.subnet.NetmaskBuilder;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.ip4.attributes.ipv4.address.subnet.PrefixLength;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.ip4.attributes.ipv4.address.subnet.PrefixLengthBuilder;
+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.interfaces.rev140508.Interfaces;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DottedQuad;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class SubInterfaceIpv4AddressValidatorTest {
+
+    private SubInterfaceIpv4AddressValidator validator;
+    private static final String IFC_NAME = "eth0";
+    private static final long SUBIF_ID = 1;
+    private static final String IP_ADDR = "192.168.2.1";
+    private static final InstanceIdentifier<Address> IID =
+            InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IFC_NAME))
+                    .augmentation(SubinterfaceAugmentation.class).child(SubInterfaces.class)
+                    .child(SubInterface.class, new SubInterfaceKey(SUBIF_ID)).child(
+                    org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.ip4.attributes.Ipv4.class)
+                    .child(Address.class);
+
+    @Mock
+    private WriteContext writeContext;
+
+    @Before
+    public void setUp() {
+        initMocks(this);
+        NamingContext ifcContext = new NamingContext("testInterfaceContext", "testInterfaceContext");
+        validator = new SubInterfaceIpv4AddressValidator(ifcContext);
+    }
+
+    @Test
+    public void testWriteSuccessful()
+            throws DataValidationFailedException.CreateValidationFailedException {
+        PrefixLength length = new PrefixLengthBuilder().setPrefixLength(new Integer(24).shortValue()).build();
+        validator.validateWrite(IID, createAddress(length), writeContext);
+    }
+
+    @Test
+    public void testDeleteSuccessful()
+            throws DataValidationFailedException.DeleteValidationFailedException {
+        PrefixLength length = new PrefixLengthBuilder().setPrefixLength(new Integer(24).shortValue()).build();
+        validator.validateDelete(IID, createAddress(length), writeContext);
+    }
+
+    @Test
+    public void testWriteNetmaskSuccessful()
+            throws DataValidationFailedException.CreateValidationFailedException {
+        Netmask netmask = new NetmaskBuilder().setNetmask(new DottedQuad(IP_ADDR)).build();
+        validator.validateWrite(IID, createAddress(netmask), writeContext);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testWriteNetmaskFailed()
+            throws DataValidationFailedException.CreateValidationFailedException {
+        validator.validateWrite(IID, createAddress(null), writeContext);
+    }
+
+    private Address createAddress(Subnet subnet) {
+        Ipv4AddressNoZone noZoneIp = new Ipv4AddressNoZone(new Ipv4Address(IP_ADDR));
+        return new AddressBuilder().setIp(noZoneIp).setSubnet(subnet).build();
+    }
+}
diff --git a/l3/impl/src/test/java/io/fd/hc2vpp/l3/write/ipv6/Ipv6NeighbourValidatorTest.java b/l3/impl/src/test/java/io/fd/hc2vpp/l3/write/ipv6/Ipv6NeighbourValidatorTest.java
new file mode 100644 (file)
index 0000000..9464625
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.hc2vpp.l3.write.ipv6;
+
+import static org.mockito.MockitoAnnotations.initMocks;
+
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.honeycomb.translate.write.DataValidationFailedException;
+import io.fd.honeycomb.translate.write.WriteContext;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+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.interfaces.rev140508.Interfaces;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface1;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv6;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv6.Neighbor;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv6.NeighborBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class Ipv6NeighbourValidatorTest {
+
+    private Ipv6NeighbourValidator validator;
+    private static final String IFACE_NAME = "parent";
+    private static final String MAC_ADDR = "aa:bb:cc:ee:11:22";
+    private static final String IP_ADDR = "2001:0db8:0a0b:12f0:0000:0000:0000:0001";
+
+    private static final InstanceIdentifier<Neighbor> IID =
+            InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IFACE_NAME))
+                    .augmentation(Interface1.class).child(Ipv6.class).child(Neighbor.class);
+
+    @Mock
+    private WriteContext writeContext;
+
+    @Before
+    public void setUp() {
+        initMocks(this);
+        NamingContext ifcContext = new NamingContext("testInterfaceContext", "testInterfaceContext");
+        validator = new Ipv6NeighbourValidator(ifcContext);
+    }
+
+    @Test
+    public void testWriteSuccessful()
+            throws DataValidationFailedException.CreateValidationFailedException {
+        validator.validateWrite(IID, getNeighbor(IP_ADDR, MAC_ADDR), writeContext);
+    }
+
+    @Test
+    public void testDeleteSuccessful()
+            throws DataValidationFailedException.DeleteValidationFailedException {
+        validator.validateDelete(IID, getNeighbor(IP_ADDR, MAC_ADDR), writeContext);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testWriteFailedMissingIP()
+            throws DataValidationFailedException.CreateValidationFailedException {
+        validator.validateWrite(IID, getNeighbor("", MAC_ADDR), writeContext);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testWriteFailedMissingMAC()
+            throws DataValidationFailedException.CreateValidationFailedException {
+        validator.validateWrite(IID, getNeighbor(IP_ADDR, ""), writeContext);
+    }
+
+    private Neighbor getNeighbor(String ipAddress, String macAddr) {
+        final Ipv6AddressNoZone noZoneIp = ipAddress.isEmpty()
+                ? null
+                : new Ipv6AddressNoZone(new Ipv6Address(ipAddress));
+        final PhysAddress mac = macAddr.isEmpty()
+                ? null
+                : new PhysAddress(macAddr);
+        return new NeighborBuilder().setIp(noZoneIp).setLinkLayerAddress(mac).build();
+    }
+}