diff options
author | Tibor Král <tibor.kral@pantheon.tech> | 2019-05-14 12:19:44 +0200 |
---|---|---|
committer | Michal Cmarada <mcmarada@cisco.com> | 2019-05-27 08:25:05 +0200 |
commit | 5c416ebacf4baad25de6213661c3cdfff31c0482 (patch) | |
tree | d2fe4889f01e4adbdeb50ea83b47aa44102a5f49 | |
parent | 83206cb1b6b0a6a3bbe45d646ed69a5f2b587fed (diff) |
HC2VPP-381: Validation support for V3PO module
Change-Id: If288d97dce15bcc6924d4dd65c640a20920f094d
Signed-off-by: Tibor Král <tibor.kral@pantheon.tech>
57 files changed, 3094 insertions, 625 deletions
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/InterfacesWriterFactory.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/InterfacesWriterFactory.java index 3fbdb9f64..4e9f7b9cc 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/InterfacesWriterFactory.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/InterfacesWriterFactory.java @@ -22,20 +22,35 @@ import com.google.inject.name.Named; import io.fd.hc2vpp.common.translate.util.NamingContext; import io.fd.hc2vpp.v3po.DisabledInterfacesManager; import io.fd.hc2vpp.v3po.interfaces.AfPacketCustomizer; +import io.fd.hc2vpp.v3po.interfaces.AfPacketValidator; import io.fd.hc2vpp.v3po.interfaces.EthernetCustomizer; +import io.fd.hc2vpp.v3po.interfaces.EthernetValidator; import io.fd.hc2vpp.v3po.interfaces.GreCustomizer; +import io.fd.hc2vpp.v3po.interfaces.GreValidator; import io.fd.hc2vpp.v3po.interfaces.InterfaceCustomizer; import io.fd.hc2vpp.v3po.interfaces.InterfaceRoutingCustomizer; +import io.fd.hc2vpp.v3po.interfaces.InterfaceRoutingValidator; import io.fd.hc2vpp.v3po.interfaces.InterfaceUnnumberedCustomizer; +import io.fd.hc2vpp.v3po.interfaces.InterfaceUnnumberedValidator; +import io.fd.hc2vpp.v3po.interfaces.InterfaceValidator; import io.fd.hc2vpp.v3po.interfaces.InterfacesStatisticsCustomizer; +import io.fd.hc2vpp.v3po.interfaces.InterfacesStatisticsValidator; import io.fd.hc2vpp.v3po.interfaces.L2Customizer; +import io.fd.hc2vpp.v3po.interfaces.L2Validator; import io.fd.hc2vpp.v3po.interfaces.LoopbackCustomizer; +import io.fd.hc2vpp.v3po.interfaces.LoopbackValidator; import io.fd.hc2vpp.v3po.interfaces.TapV2Customizer; +import io.fd.hc2vpp.v3po.interfaces.TapV2Validator; import io.fd.hc2vpp.v3po.interfaces.VhostUserCustomizer; +import io.fd.hc2vpp.v3po.interfaces.VhostUserValidator; import io.fd.hc2vpp.v3po.interfaces.VxlanCustomizer; import io.fd.hc2vpp.v3po.interfaces.VxlanGpeCustomizer; +import io.fd.hc2vpp.v3po.interfaces.VxlanGpeValidator; +import io.fd.hc2vpp.v3po.interfaces.VxlanValidator; import io.fd.hc2vpp.v3po.interfaces.pbb.PbbRewriteCustomizer; +import io.fd.hc2vpp.v3po.interfaces.pbb.PbbRewriteValidator; import io.fd.hc2vpp.v3po.interfaces.span.MirroredInterfaceCustomizer; +import io.fd.hc2vpp.v3po.interfaces.span.MirroredInterfaceValidator; import io.fd.hc2vpp.v3po.interfacesstate.cache.InterfaceStatisticsManager; import io.fd.honeycomb.translate.impl.write.GenericListWriter; import io.fd.honeycomb.translate.impl.write.GenericWriter; @@ -98,9 +113,11 @@ public final class InterfacesWriterFactory implements WriterFactory { public void init(final ModifiableWriterRegistryBuilder registry) { // Interfaces registry.add(new GenericWriter<>(IFCS_ID.augmentation(VppInterfacesStatsAugmentation.class) - .child(Statistics.class), new InterfacesStatisticsCustomizer(statisticsManager))); + .child(Statistics.class), new InterfacesStatisticsCustomizer(statisticsManager), + new InterfacesStatisticsValidator(statisticsManager))); // Interface = - registry.add(new GenericListWriter<>(IFC_ID, new InterfaceCustomizer(jvpp, ifcNamingContext))); + registry.add(new GenericListWriter<>(IFC_ID, new InterfaceCustomizer(jvpp, ifcNamingContext), + new InterfaceValidator(ifcNamingContext))); // VppInterfaceAugmentation addVppInterfaceAgmentationWriters(IFC_ID, registry); @@ -111,47 +128,51 @@ public final class InterfacesWriterFactory implements WriterFactory { final ModifiableWriterRegistryBuilder registry) { // VhostUser(Needs to be executed before Interface customizer) = final InstanceIdentifier<VhostUser> vhostId = VPP_IFC_AUG_ID.child(VhostUser.class); - registry.addBefore(new GenericWriter<>(vhostId, new VhostUserCustomizer(jvpp, ifcNamingContext)), - ifcId); + registry.addBefore(new GenericWriter<>(vhostId, new VhostUserCustomizer(jvpp, ifcNamingContext), + new VhostUserValidator(ifcNamingContext)), ifcId); // AfPacket(Needs to be executed before Interface customizer) = final InstanceIdentifier<AfPacket> afpacketId = VPP_IFC_AUG_ID.child(AfPacket.class); - registry.addBefore(new GenericWriter<>(afpacketId, new AfPacketCustomizer(jvpp, ifcNamingContext)), - ifcId); + registry.addBefore(new GenericWriter<>(afpacketId, new AfPacketCustomizer(jvpp, ifcNamingContext), + new AfPacketValidator(ifcNamingContext)), ifcId); // Vxlan(Needs to be executed before Interface customizer) = final InstanceIdentifier<Vxlan> vxlanId = VPP_IFC_AUG_ID.child(Vxlan.class); - registry.addBefore(new GenericWriter<>(vxlanId, new VxlanCustomizer(jvpp, ifcNamingContext, ifcDisableContext)), + registry.addBefore(new GenericWriter<>(vxlanId, new VxlanCustomizer(jvpp, ifcNamingContext, ifcDisableContext), + new VxlanValidator(ifcNamingContext, ifcDisableContext)), ifcId); // VxlanGpe(Needs to be executed before Interface customizer) = final InstanceIdentifier<VxlanGpe> vxlanGpeId = VPP_IFC_AUG_ID.child(VxlanGpe.class); registry.addBefore(new GenericWriter<>(vxlanGpeId, - new VxlanGpeCustomizer(jvpp, ifcNamingContext, ifcDisableContext)), ifcId); + new VxlanGpeCustomizer(jvpp, ifcNamingContext, ifcDisableContext), + new VxlanGpeValidator(ifcNamingContext, ifcDisableContext)), ifcId); // TapV2(Needs to be executed before Interface customizer) = final InstanceIdentifier<TapV2> tapV2Id = VPP_IFC_AUG_ID.child(TapV2.class); - registry.addBefore(new GenericWriter<>(tapV2Id, new TapV2Customizer(jvpp, ifcNamingContext)), - ifcId); + registry.addBefore(new GenericWriter<>(tapV2Id, new TapV2Customizer(jvpp, ifcNamingContext), + new TapV2Validator(ifcNamingContext)), ifcId); // Loopback(Needs to be executed before Interface customizer) = final InstanceIdentifier<Loopback> loopbackId = VPP_IFC_AUG_ID.child(Loopback.class); - registry.addBefore(new GenericWriter<>(loopbackId, new LoopbackCustomizer(jvpp, ifcNamingContext)), - ifcId); + registry.addBefore(new GenericWriter<>(loopbackId, new LoopbackCustomizer(jvpp, ifcNamingContext), + new LoopbackValidator(ifcNamingContext)), ifcId); // Gre(Needs to be executed before Interface customizer) = final InstanceIdentifier<Gre> greId = VPP_IFC_AUG_ID.child(Gre.class); - registry.addBefore(new GenericWriter<>(greId, new GreCustomizer(jvpp, ifcNamingContext)), - ifcId); + registry.addBefore(new GenericWriter<>(greId, new GreCustomizer(jvpp, ifcNamingContext), + new GreValidator(ifcNamingContext)), ifcId); final Set<InstanceIdentifier<?>> specificIfcTypes = Sets.newHashSet(vhostId, afpacketId, vxlanId, vxlanGpeId, tapV2Id, loopbackId); // Ethernet = registry.add(new GenericWriter<>(VPP_IFC_AUG_ID.child(Ethernet.class), - new EthernetCustomizer(jvpp, ifcNamingContext))); + new EthernetCustomizer(jvpp, ifcNamingContext), new EthernetValidator(ifcNamingContext))); // Routing(Execute only after specific interface customizers) = registry.addAfter( new GenericWriter<>(VPP_IFC_AUG_ID.child(Routing.class), - new InterfaceRoutingCustomizer(jvpp, ifcNamingContext)), + new InterfaceRoutingCustomizer(jvpp, ifcNamingContext), + new InterfaceRoutingValidator(ifcNamingContext)), specificIfcTypes); // L2(Execute only after subinterface (and all other ifc types) = - registry.addAfter(new GenericWriter<>(L2_ID, new L2Customizer(jvpp, ifcNamingContext, bdNamingContext)), + registry.addAfter(new GenericWriter<>(L2_ID, new L2Customizer(jvpp, ifcNamingContext, bdNamingContext), + new L2Validator(ifcNamingContext, bdNamingContext)), SubinterfaceAugmentationWriterFactory.SUB_IFC_ID); // Span writers @@ -161,13 +182,15 @@ public final class InterfacesWriterFactory implements WriterFactory { .child(MirroredInterfaces.class) .child(MirroredInterface.class); registry.addAfter(new GenericWriter<>(mirroredIfcId, new MirroredInterfaceCustomizer(jvpp, ifcNamingContext, - id -> id.firstKeyOf(Interface.class).getName())), ifcId); + id -> id.firstKeyOf(Interface.class).getName()), + new MirroredInterfaceValidator(ifcNamingContext, id -> id.firstKeyOf(Interface.class).getName())), + ifcId); // Unnumbered = final InstanceIdentifier<Unnumbered> unnumberedId = IFC_ID.augmentation(InterfaceUnnumberedAugmentation.class).child(Unnumbered.class); - registry.addAfter(new GenericWriter<>(unnumberedId, new InterfaceUnnumberedCustomizer(jvpp, ifcNamingContext)), - ifcId); + registry.addAfter(new GenericWriter<>(unnumberedId, new InterfaceUnnumberedCustomizer(jvpp, ifcNamingContext), + new InterfaceUnnumberedValidator(ifcNamingContext)), ifcId); } private void addPbbAugmentationWriters(final InstanceIdentifier<Interface> ifcId, @@ -175,6 +198,7 @@ public final class InterfacesWriterFactory implements WriterFactory { final InstanceIdentifier<PbbRewrite> pbbRewriteId = ifcId.augmentation(PbbRewriteInterfaceAugmentation.class).child(PbbRewrite.class); - registry.add(new GenericWriter<>(pbbRewriteId, new PbbRewriteCustomizer(jvpp, ifcNamingContext))); + registry.add(new GenericWriter<>(pbbRewriteId, new PbbRewriteCustomizer(jvpp, ifcNamingContext), + new PbbRewriteValidator(ifcNamingContext))); } } diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/SubinterfaceAugmentationWriterFactory.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/SubinterfaceAugmentationWriterFactory.java index cdcd07000..237eab57a 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/SubinterfaceAugmentationWriterFactory.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/SubinterfaceAugmentationWriterFactory.java @@ -21,10 +21,15 @@ import com.google.inject.Inject; import com.google.inject.name.Named; import io.fd.hc2vpp.common.translate.util.NamingContext; import io.fd.hc2vpp.v3po.interfaces.RewriteCustomizer; +import io.fd.hc2vpp.v3po.interfaces.RewriteValidator; import io.fd.hc2vpp.v3po.interfaces.SubInterfaceCustomizer; import io.fd.hc2vpp.v3po.interfaces.SubInterfaceL2Customizer; +import io.fd.hc2vpp.v3po.interfaces.SubInterfaceL2Validator; import io.fd.hc2vpp.v3po.interfaces.SubInterfaceRoutingCustomizer; +import io.fd.hc2vpp.v3po.interfaces.SubInterfaceRoutingValidator; import io.fd.hc2vpp.v3po.interfaces.SubInterfaceUnnumberedCustomizer; +import io.fd.hc2vpp.v3po.interfaces.SubInterfaceUnnumberedValidator; +import io.fd.hc2vpp.v3po.interfaces.SubInterfaceValidator; import io.fd.hc2vpp.v3po.interfaces.span.MirroredInterfaceCustomizer; import io.fd.hc2vpp.v3po.util.SubInterfaceUtils; import io.fd.honeycomb.translate.impl.write.GenericListWriter; @@ -59,11 +64,11 @@ public final class SubinterfaceAugmentationWriterFactory implements WriterFactor private final NamingContext bdContext; public static final InstanceIdentifier<SubinterfaceAugmentation> SUB_IFC_AUG_ID = - InterfacesWriterFactory.IFC_ID.augmentation(SubinterfaceAugmentation.class); + InterfacesWriterFactory.IFC_ID.augmentation(SubinterfaceAugmentation.class); public static final InstanceIdentifier<SubInterface> SUB_IFC_ID = - SUB_IFC_AUG_ID.child(SubInterfaces.class).child(SubInterface.class); + SUB_IFC_AUG_ID.child(SubInterfaces.class).child(SubInterface.class); public static final InstanceIdentifier<L2> L2_ID = SUB_IFC_ID.child( - L2.class); + L2.class); @Inject public SubinterfaceAugmentationWriterFactory(final FutureJVppCore jvpp, @@ -79,31 +84,35 @@ public final class SubinterfaceAugmentationWriterFactory implements WriterFactor // Subinterfaces // Subinterface(Handle only after all interface related stuff gets processed) = registry.subtreeAddAfter( - // TODO HONEYCOMB-188 this customizer covers quite a lot of complex child nodes (maybe refactor ?) - Sets.newHashSet( - InstanceIdentifier.create(SubInterface.class).child(Tags.class), - InstanceIdentifier.create(SubInterface.class).child(Tags.class).child(Tag.class), - InstanceIdentifier.create(SubInterface.class).child(Tags.class).child(Tag.class).child( - Dot1qTag.class), - InstanceIdentifier.create(SubInterface.class).child(Match.class), - InstanceIdentifier.create(SubInterface.class).child(Match.class).child(VlanTagged.class)), - new GenericListWriter<>(SUB_IFC_ID, new SubInterfaceCustomizer(jvpp, ifcContext)), - InterfacesWriterFactory.IFC_ID); + // TODO HONEYCOMB-188 this customizer covers quite a lot of complex child nodes (maybe refactor ?) + Sets.newHashSet( + InstanceIdentifier.create(SubInterface.class).child(Tags.class), + InstanceIdentifier.create(SubInterface.class).child(Tags.class).child(Tag.class), + InstanceIdentifier.create(SubInterface.class).child(Tags.class).child(Tag.class).child( + Dot1qTag.class), + InstanceIdentifier.create(SubInterface.class).child(Match.class), + InstanceIdentifier.create(SubInterface.class).child(Match.class).child(VlanTagged.class)), + new GenericListWriter<>(SUB_IFC_ID, new SubInterfaceCustomizer(jvpp, ifcContext), + new SubInterfaceValidator(ifcContext)), + InterfacesWriterFactory.IFC_ID); // L2 = - registry.addAfter(new GenericWriter<>(L2_ID, new SubInterfaceL2Customizer(jvpp, ifcContext, bdContext)), - SUB_IFC_ID); + registry.addAfter(new GenericWriter<>(L2_ID, new SubInterfaceL2Customizer(jvpp, ifcContext, bdContext), + new SubInterfaceL2Validator(ifcContext, bdContext)), + SUB_IFC_ID); // Rewrite(also handles pushTags + pushTags/dot1qtag) = final InstanceIdentifier<Rewrite> rewriteId = L2_ID.child(Rewrite.class); registry.subtreeAddAfter( - Sets.newHashSet( - InstanceIdentifier.create(Rewrite.class).child(PushTags.class), - InstanceIdentifier.create(Rewrite.class).child(PushTags.class) - .child( - org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.dot1q.tag.Dot1qTag.class)), - new GenericWriter<>(rewriteId, new RewriteCustomizer(jvpp, ifcContext)), - L2_ID); + Sets.newHashSet( + InstanceIdentifier.create(Rewrite.class).child(PushTags.class), + InstanceIdentifier.create(Rewrite.class).child(PushTags.class) + .child( + org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.dot1q.tag.Dot1qTag.class)), + new GenericWriter<>(rewriteId, new RewriteCustomizer(jvpp, ifcContext), + new RewriteValidator(ifcContext)), + L2_ID); final InstanceIdentifier<Routing> routingId = SUB_IFC_ID.child(Routing.class); - registry.add(new GenericWriter<>(routingId, new SubInterfaceRoutingCustomizer(jvpp, ifcContext))); + registry.add(new GenericWriter<>(routingId, new SubInterfaceRoutingCustomizer(jvpp, ifcContext), + new SubInterfaceRoutingValidator(ifcContext))); final InstanceIdentifier<MirroredInterface> mirroredId = SUB_IFC_ID.augmentation(VppSubinterfaceSpanAugmentation.class) @@ -116,8 +125,9 @@ public final class SubinterfaceAugmentationWriterFactory implements WriterFactor // Unnumbered = final InstanceIdentifier<Unnumbered> unnumberedId = - SUB_IFC_ID.augmentation(SubinterfaceUnnumberedAugmentation.class).child(Unnumbered.class); - registry.addAfter(new GenericWriter<>(unnumberedId, new SubInterfaceUnnumberedCustomizer(jvpp, ifcContext)), - SUB_IFC_ID); + SUB_IFC_ID.augmentation(SubinterfaceUnnumberedAugmentation.class).child(Unnumbered.class); + registry.addAfter(new GenericWriter<>(unnumberedId, new SubInterfaceUnnumberedCustomizer(jvpp, ifcContext), + new SubInterfaceUnnumberedValidator(ifcContext)), + SUB_IFC_ID); } } diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/AfPacketCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/AfPacketCustomizer.java index ecb4f8c79..ea4220acd 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/AfPacketCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/AfPacketCustomizer.java @@ -16,9 +16,6 @@ package io.fd.hc2vpp.v3po.interfaces; -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - import io.fd.hc2vpp.common.translate.util.AbstractInterfaceTypeCustomizer; import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; import io.fd.hc2vpp.common.translate.util.MacTranslator; @@ -49,7 +46,7 @@ public class AfPacketCustomizer extends AbstractInterfaceTypeCustomizer<AfPacket public AfPacketCustomizer(@Nonnull final FutureJVppCore vppApi, @Nonnull final NamingContext interfaceContext) { super(vppApi); - this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); + this.interfaceContext = interfaceContext; } @Override @@ -92,12 +89,7 @@ public class AfPacketCustomizer extends AbstractInterfaceTypeCustomizer<AfPacket private AfPacketCreate getCreateRequest(@Nonnull final AfPacket afPacket) { final AfPacketCreate request = new AfPacketCreate(); - checkArgument(afPacket.getHostInterfaceName() != null, - "host-interface-name is mandatory for af-packet interface"); request.hostIfName = afPacket.getHostInterfaceName().getBytes(StandardCharsets.UTF_8); - checkArgument(request.hostIfName.length <= 64, - "Interface name for af_packet interface should not be longer than 64 bytes, but was %s", - request.hostIfName.length); final PhysAddress mac = afPacket.getMac(); if (mac == null) { request.useRandomHwAddr = 1; diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/AfPacketValidator.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/AfPacketValidator.java new file mode 100644 index 000000000..f76922cd0 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/AfPacketValidator.java @@ -0,0 +1,79 @@ +/* + * 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.v3po.interfaces; + +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.CreateValidationFailedException; +import io.fd.honeycomb.translate.write.DataValidationFailedException.DeleteValidationFailedException; +import io.fd.honeycomb.translate.write.DataValidationFailedException.UpdateValidationFailedException; +import io.fd.honeycomb.translate.write.Validator; +import io.fd.honeycomb.translate.write.WriteContext; +import java.nio.charset.StandardCharsets; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.AfPacket; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class AfPacketValidator implements Validator<AfPacket> { + + public AfPacketValidator(@Nonnull final NamingContext interfaceContext) { + checkNotNull(interfaceContext, "interfaceContext should not be null"); + } + + @Override + public void validateWrite(@Nonnull final InstanceIdentifier<AfPacket> id, @Nonnull final AfPacket dataAfter, + @Nonnull final WriteContext writeContext) + throws CreateValidationFailedException { + try { + validateAfPacket(dataAfter); + } catch (Exception e) { + throw new CreateValidationFailedException(id, dataAfter, e); + } + } + + @Override + public void validateUpdate(@Nonnull final InstanceIdentifier<AfPacket> id, @Nonnull final AfPacket dataBefore, + @Nonnull final AfPacket dataAfter, @Nonnull final WriteContext writeContext) + throws UpdateValidationFailedException { + try { + validateAfPacket(dataAfter); + } catch (Exception e) { + throw new UpdateValidationFailedException(id, dataBefore, dataAfter, e); + } + } + + @Override + public void validateDelete(@Nonnull final InstanceIdentifier<AfPacket> id, @Nonnull final AfPacket dataBefore, + @Nonnull final WriteContext writeContext) + throws DeleteValidationFailedException { + try { + validateAfPacket(dataBefore); + } catch (Exception e) { + throw new DeleteValidationFailedException(id, e); + } + } + + private void validateAfPacket(final AfPacket data) { + checkNotNull(data.getHostInterfaceName(), "host-interface-name is mandatory for af-packet interface"); + byte[] hostIfName = data.getHostInterfaceName().getBytes(StandardCharsets.UTF_8); + checkArgument(hostIfName.length <= 64, + "Interface name for af_packet interface should not be longer than 64 bytes, but was %s", + hostIfName.length); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/EthernetValidator.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/EthernetValidator.java new file mode 100644 index 000000000..e8fa32a17 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/EthernetValidator.java @@ -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.v3po.interfaces; + +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.v3po.rev190502.interfaces._interface.Ethernet; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class EthernetValidator implements Validator<Ethernet> { + + public EthernetValidator(final NamingContext interfaceContext) { + checkNotNull(interfaceContext, "interfaceContext should not be null"); + } + + @Override + public void validateWrite(@Nonnull final InstanceIdentifier<Ethernet> id, @Nonnull final Ethernet dataAfter, + @Nonnull final WriteContext writeContext) + throws DataValidationFailedException.CreateValidationFailedException { + checkNotNull(dataAfter.getMtu(), "MTU cannot be null"); + } + + @Override + public void validateUpdate(@Nonnull final InstanceIdentifier<Ethernet> id, @Nonnull final Ethernet dataBefore, + @Nonnull final Ethernet dataAfter, @Nonnull final WriteContext writeContext) + throws DataValidationFailedException.UpdateValidationFailedException { + checkNotNull(dataAfter.getMtu(), "MTU cannot be null"); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/GreCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/GreCustomizer.java index 3496fdd88..b13388102 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/GreCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/GreCustomizer.java @@ -16,8 +16,6 @@ package io.fd.hc2vpp.v3po.interfaces; -import static com.google.common.base.Preconditions.checkArgument; - import io.fd.hc2vpp.common.translate.util.AbstractInterfaceTypeCustomizer; import io.fd.hc2vpp.common.translate.util.AddressTranslator; import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; @@ -125,15 +123,7 @@ public class GreCustomizer extends AbstractInterfaceTypeCustomizer<Gre> implemen } private boolean isIpv6(final Gre gre) { - if (gre.getSrc().getIpv4AddressNoZone() == null) { - checkArgument(gre.getDst().getIpv4AddressNoZone() == null, "Inconsistent ip addresses: %s, %s", gre.getSrc(), - gre.getDst()); - return true; - } else { - checkArgument(gre.getDst().getIpv6AddressNoZone() == null, "Inconsistent ip addresses: %s, %s", gre.getSrc(), - gre.getDst()); - return false; - } + return gre.getSrc().getIpv4AddressNoZone() == null; } private void deleteGreTunnel(final InstanceIdentifier<Gre> id, final String swIfName, final Gre gre, diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/GreValidator.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/GreValidator.java new file mode 100644 index 000000000..9376ab87d --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/GreValidator.java @@ -0,0 +1,72 @@ +/* + * 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.v3po.interfaces; + +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.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.Gre; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class GreValidator implements Validator<Gre> { + + public GreValidator(final NamingContext interfaceContext) { + checkNotNull(interfaceContext, "interfaceContext should not be null"); + } + + @Override + public void validateWrite(@Nonnull final InstanceIdentifier<Gre> id, @Nonnull final Gre dataAfter, + @Nonnull final WriteContext writeContext) + throws DataValidationFailedException.CreateValidationFailedException { + try { + validateGre(dataAfter); + } catch (Exception e) { + throw new DataValidationFailedException.CreateValidationFailedException(id, dataAfter, e); + } + } + + @Override + public void validateDelete(@Nonnull final InstanceIdentifier<Gre> id, @Nonnull final Gre dataBefore, + @Nonnull final WriteContext writeContext) + throws DataValidationFailedException.DeleteValidationFailedException { + try { + validateGre(dataBefore); + } catch (Exception e) { + throw new DataValidationFailedException.DeleteValidationFailedException(id, e); + } + } + + private void validateGre(final Gre data) { + checkNotNull(data.getOuterFibId(), "Outer Fib ID cannot be null"); + checkNotNull(data.getSrc(), "Source cannot be null"); + checkNotNull(data.getDst(), "Destination cannot be null"); + if (data.getSrc().getIpv4AddressNoZone() == null) { + checkArgument(data.getDst().getIpv4AddressNoZone() == null, "Inconsistent ip addresses: %s, %s", + data.getSrc(), + data.getDst()); + } else { + checkArgument(data.getDst().getIpv6AddressNoZone() == null, "Inconsistent ip addresses: %s, %s", + data.getSrc(), + data.getDst()); + } + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/InterfaceRoutingCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/InterfaceRoutingCustomizer.java index 30885fc1e..e498e0cae 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/InterfaceRoutingCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/InterfaceRoutingCustomizer.java @@ -16,22 +16,14 @@ package io.fd.hc2vpp.v3po.interfaces; -import static com.google.common.base.Preconditions.checkState; - -import java.util.Optional; import io.fd.hc2vpp.common.translate.util.NamingContext; import io.fd.honeycomb.translate.spi.write.WriterCustomizer; -import io.fd.honeycomb.translate.util.RWUtils; import io.fd.honeycomb.translate.write.WriteContext; import io.fd.honeycomb.translate.write.WriteFailedException; import io.fd.jvpp.core.future.FutureJVppCore; -import java.util.List; import javax.annotation.Nonnull; import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.Routing; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.Interface; -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.Ipv6; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; public class InterfaceRoutingCustomizer extends RoutingCustomizer @@ -46,10 +38,6 @@ public class InterfaceRoutingCustomizer extends RoutingCustomizer public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Routing> id, @Nonnull final Routing dataAfter, @Nonnull final WriteContext writeContext) throws WriteFailedException { - - checkState(isAddressNotPresentForInterface(id, writeContext, true), - "Cannot change routing configuration, if address is present for interface"); - final String ifName = id.firstKeyOf(Interface.class).getName(); setRouting(id, ifName, dataAfter, writeContext); } @@ -59,9 +47,6 @@ public class InterfaceRoutingCustomizer extends RoutingCustomizer @Nonnull final Routing dataBefore, @Nonnull final Routing dataAfter, @Nonnull final WriteContext writeContext) throws WriteFailedException { - checkState(isAddressNotPresentForInterface(id, writeContext, true), - "Cannot change routing configuration, if address is present for interface"); - final String ifName = id.firstKeyOf(Interface.class).getName(); setRouting(id, ifName, dataAfter, writeContext); } @@ -70,35 +55,7 @@ public class InterfaceRoutingCustomizer extends RoutingCustomizer public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Routing> id, @Nonnull final Routing dataBefore, @Nonnull final WriteContext writeContext) throws WriteFailedException { - checkState(isAddressNotPresentForInterface(id, writeContext, false), - "Cannot change routing configuration, if address is present for interface"); - final String ifName = id.firstKeyOf(Interface.class).getName(); disableRouting(id, ifName, writeContext); } - - /** - * Returns true if interface does not have v4/v6 addresses configured - */ - private boolean isAddressNotPresentForInterface(@Nonnull final InstanceIdentifier<Routing> id, - @Nonnull final WriteContext ctx, - boolean checkBefore) { - final Optional<Interface> interfaceData = checkBefore - ? ctx.readBefore(RWUtils.cutId(id, Interface.class)) - : ctx.readAfter(RWUtils.cutId(id, Interface.class)); - - if (interfaceData.isPresent()) { - final java.util.Optional<Interface1> augData = java.util.Optional.of(interfaceData.get()) - .map(iface -> iface.augmentation(Interface1.class)); - - final boolean v4NotPresent = - augData.map(Interface1::getIpv4).map(Ipv4::getAddress).map(List::isEmpty).orElse(true); - - final boolean v6NotPresent = - augData.map(Interface1::getIpv6).map(Ipv6::getAddress).map(List::isEmpty).orElse(true); - - return v4NotPresent && v6NotPresent; - } - return true; - } } diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/InterfaceRoutingValidator.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/InterfaceRoutingValidator.java new file mode 100644 index 000000000..011772600 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/InterfaceRoutingValidator.java @@ -0,0 +1,118 @@ +/* + * 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.v3po.interfaces; + +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.NamingContext; +import io.fd.honeycomb.translate.util.RWUtils; +import io.fd.honeycomb.translate.write.DataValidationFailedException.CreateValidationFailedException; +import io.fd.honeycomb.translate.write.DataValidationFailedException.DeleteValidationFailedException; +import io.fd.honeycomb.translate.write.DataValidationFailedException.UpdateValidationFailedException; +import io.fd.honeycomb.translate.write.Validator; +import io.fd.honeycomb.translate.write.WriteContext; +import java.util.List; +import java.util.Optional; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.RoutingBaseAttributes; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.Routing; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.Interface; +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.Ipv6; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class InterfaceRoutingValidator implements Validator<Routing> { + + public InterfaceRoutingValidator(@Nonnull final NamingContext interfaceContext) { + checkNotNull(interfaceContext, "interfaceContext should not be null"); + } + + @Override + public void validateWrite(@Nonnull final InstanceIdentifier<Routing> id, @Nonnull final Routing dataAfter, + @Nonnull final WriteContext writeContext) + throws CreateValidationFailedException { + try { + checkVrfIds(dataAfter); + checkInterfaceAddressConf(id, writeContext, true); + } catch (Exception e) { + throw new CreateValidationFailedException(id, dataAfter, e); + } + } + + @Override + public void validateUpdate(@Nonnull final InstanceIdentifier<Routing> id, @Nonnull final Routing dataBefore, + @Nonnull final Routing dataAfter, @Nonnull final WriteContext writeContext) + throws UpdateValidationFailedException { + try { + checkVrfIds(dataAfter); + checkInterfaceAddressConf(id, writeContext, true); + } catch (Exception e) { + throw new UpdateValidationFailedException(id, dataBefore, dataAfter, e); + } + } + + @Override + public void validateDelete(@Nonnull final InstanceIdentifier<Routing> id, @Nonnull final Routing dataBefore, + @Nonnull final WriteContext writeContext) + throws DeleteValidationFailedException { + try { + checkVrfIds(dataBefore); + checkInterfaceAddressConf(id, writeContext, false); + } catch (Exception e) { + throw new DeleteValidationFailedException(id, e); + } + } + + private void checkVrfIds(final RoutingBaseAttributes data) { + checkArgument(data.getIpv4VrfId() != null || data.getIpv6VrfId() != null, "No vrf-id given"); + } + + private void checkInterfaceAddressConf(@Nonnull final InstanceIdentifier<Routing> id, + @Nonnull final WriteContext ctx, + boolean checkBefore) { + checkState(isAddressNotPresentForInterface(id, ctx, checkBefore), + "Cannot change routing configuration, if address is present for interface"); + } + + /** + * Returns true if interface does not have v4/v6 addresses configured + */ + private boolean isAddressNotPresentForInterface(@Nonnull final InstanceIdentifier<Routing> id, + @Nonnull final WriteContext ctx, + boolean checkBefore) { + final Optional<Interface> interfaceData = checkBefore + ? ctx.readBefore(RWUtils.cutId(id, Interface.class)) + : ctx.readAfter(RWUtils.cutId(id, Interface.class)); + + if (interfaceData.isPresent()) { + final java.util.Optional<Interface1> augData = java.util.Optional.of(interfaceData.get()) + .map(iface -> iface.augmentation(Interface1.class)); + + final boolean v4NotPresent = + augData.map(Interface1::getIpv4).map(Ipv4::getAddress).map(List::isEmpty).orElse(true); + + final boolean v6NotPresent = + augData.map(Interface1::getIpv6).map(Ipv6::getAddress).map(List::isEmpty).orElse(true); + + return v4NotPresent && v6NotPresent; + } + return true; + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/InterfaceUnnumberedValidator.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/InterfaceUnnumberedValidator.java new file mode 100644 index 000000000..0120582d1 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/InterfaceUnnumberedValidator.java @@ -0,0 +1,55 @@ +/* + * 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.v3po.interfaces; + +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.unnumbered.interfaces.rev180103.unnumbered.config.attributes.Unnumbered; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class InterfaceUnnumberedValidator implements Validator<Unnumbered> { + + public InterfaceUnnumberedValidator(final NamingContext interfaceContext) { + checkNotNull(interfaceContext, "interfaceContext should not be null"); + } + + @Override + public void validateWrite(@Nonnull final InstanceIdentifier<Unnumbered> id, @Nonnull final Unnumbered dataAfter, + @Nonnull final WriteContext writeContext) + throws DataValidationFailedException.CreateValidationFailedException { + checkNotNull(dataAfter.getUse(), "Use cannot be null"); + } + + @Override + public void validateUpdate(@Nonnull final InstanceIdentifier<Unnumbered> id, @Nonnull final Unnumbered dataBefore, + @Nonnull final Unnumbered dataAfter, @Nonnull final WriteContext writeContext) + throws DataValidationFailedException.UpdateValidationFailedException { + checkNotNull(dataAfter.getUse(), "Use cannot be null"); + } + + @Override + public void validateDelete(@Nonnull final InstanceIdentifier<Unnumbered> id, @Nonnull final Unnumbered dataBefore, + @Nonnull final WriteContext writeContext) + throws DataValidationFailedException.DeleteValidationFailedException { + checkNotNull(dataBefore.getUse(), "Use cannot be null"); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/InterfaceValidator.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/InterfaceValidator.java new file mode 100644 index 000000000..3e6ed638e --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/InterfaceValidator.java @@ -0,0 +1,74 @@ +/* + * 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.v3po.interfaces; + +import static com.google.common.base.Preconditions.checkNotNull; + +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.DataValidationFailedException.CreateValidationFailedException; +import io.fd.honeycomb.translate.write.DataValidationFailedException.DeleteValidationFailedException; +import io.fd.honeycomb.translate.write.DataValidationFailedException.UpdateValidationFailedException; +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.rev180220.interfaces.Interface; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class InterfaceValidator implements Validator<Interface> { + + public InterfaceValidator(final NamingContext interfaceContext) { + checkNotNull(interfaceContext, "interfaceContext should not be null"); + } + + @Override + public void validateWrite(@Nonnull final InstanceIdentifier<Interface> id, @Nonnull final Interface dataAfter, + @Nonnull final WriteContext writeContext) + throws CreateValidationFailedException { + try { + checkInterface(dataAfter); + } catch (Exception e) { + throw new CreateValidationFailedException(id, dataAfter, e); + } + } + + @Override + public void validateUpdate(@Nonnull final InstanceIdentifier<Interface> id, @Nonnull final Interface dataBefore, + @Nonnull final Interface dataAfter, @Nonnull final WriteContext writeContext) + throws UpdateValidationFailedException { + try { + checkInterface(dataAfter); + } catch (Exception e) { + throw new UpdateValidationFailedException(id, dataBefore, dataAfter, e); + } + } + + @Override + public void validateDelete(@Nonnull final InstanceIdentifier<Interface> id, @Nonnull final Interface dataBefore, + @Nonnull final WriteContext writeContext) + throws DeleteValidationFailedException { + try { + checkInterface(dataBefore); + } catch (Exception e) { + throw new DeleteValidationFailedException(id, e); + } + } + + private void checkInterface(final Interface data) { + checkNotNull(data.isEnabled(), "Enabled tag cannot be null"); + checkNotNull(data.getName(), "Name cannot be null"); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/InterfacesStatisticsCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/InterfacesStatisticsCustomizer.java index b67eccda3..e7ef14dc4 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/InterfacesStatisticsCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/InterfacesStatisticsCustomizer.java @@ -16,8 +16,6 @@ package io.fd.hc2vpp.v3po.interfaces; -import static com.google.common.base.Preconditions.checkNotNull; - import io.fd.hc2vpp.v3po.interfacesstate.cache.InterfaceStatisticsManager; import io.fd.honeycomb.translate.spi.write.WriterCustomizer; import io.fd.honeycomb.translate.write.WriteContext; @@ -26,13 +24,12 @@ import javax.annotation.Nonnull; import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces.Statistics; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -public class InterfacesStatisticsCustomizer implements - WriterCustomizer<Statistics> { +public class InterfacesStatisticsCustomizer implements WriterCustomizer<Statistics> { private final InterfaceStatisticsManager statisticsManager; public InterfacesStatisticsCustomizer(final InterfaceStatisticsManager statisticsManager) { - this.statisticsManager = checkNotNull(statisticsManager, "Statistics Collection Manager should not be null"); + this.statisticsManager = statisticsManager; } @Override diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/InterfacesStatisticsValidator.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/InterfacesStatisticsValidator.java new file mode 100644 index 000000000..00c58b5fc --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/InterfacesStatisticsValidator.java @@ -0,0 +1,55 @@ +/* + * 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.v3po.interfaces; + +import static com.google.common.base.Preconditions.checkNotNull; + +import io.fd.hc2vpp.v3po.interfacesstate.cache.InterfaceStatisticsManager; +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.v3po.rev190502.interfaces.Statistics; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class InterfacesStatisticsValidator implements Validator<Statistics> { + + public InterfacesStatisticsValidator(final InterfaceStatisticsManager statisticsManager) { + checkNotNull(statisticsManager, "Statistics Collection Manager should not be null"); + } + + @Override + public void validateWrite(@Nonnull final InstanceIdentifier<Statistics> id, @Nonnull final Statistics dataAfter, + @Nonnull final WriteContext writeContext) + throws DataValidationFailedException.CreateValidationFailedException { + // there is nothing to validate yet + } + + @Override + public void validateUpdate(@Nonnull final InstanceIdentifier<Statistics> id, @Nonnull final Statistics dataBefore, + @Nonnull final Statistics dataAfter, @Nonnull final WriteContext writeContext) + throws DataValidationFailedException.UpdateValidationFailedException { + // there is nothing to validate yet + } + + @Override + public void validateDelete(@Nonnull final InstanceIdentifier<Statistics> id, @Nonnull final Statistics dataBefore, + @Nonnull final WriteContext writeContext) + throws DataValidationFailedException.DeleteValidationFailedException { + // there is nothing to validate yet + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/L2Validator.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/L2Validator.java new file mode 100644 index 000000000..3c59bd98d --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/L2Validator.java @@ -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.v3po.interfaces; + +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.v3po.rev190502.interfaces._interface.L2; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class L2Validator implements Validator<L2> { + + public L2Validator(final NamingContext interfaceContext, + final NamingContext bridgeDomainContext) { + checkNotNull(interfaceContext, "interfaceContext should not be null"); + checkNotNull(bridgeDomainContext, "bridgeDomainContext should not be null"); + } + + @Override + public void validateWrite(@Nonnull final InstanceIdentifier<L2> id, @Nonnull final L2 dataAfter, + @Nonnull final WriteContext writeContext) + throws DataValidationFailedException.CreateValidationFailedException { + // there is nothing to validate yet + } + + @Override + public void validateUpdate(@Nonnull final InstanceIdentifier<L2> id, @Nonnull final L2 dataBefore, + @Nonnull final L2 dataAfter, + @Nonnull final WriteContext writeContext) + throws DataValidationFailedException.UpdateValidationFailedException { + // there is nothing to validate yet + } + + @Override + public void validateDelete(@Nonnull final InstanceIdentifier<L2> id, @Nonnull final L2 dataBefore, + @Nonnull final WriteContext writeContext) + throws DataValidationFailedException.DeleteValidationFailedException { + // there is nothing to validate yet + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/LoopbackValidator.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/LoopbackValidator.java new file mode 100644 index 000000000..57f1eb108 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/LoopbackValidator.java @@ -0,0 +1,55 @@ +/* + * 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.v3po.interfaces; + +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.v3po.rev190502.interfaces._interface.Loopback; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class LoopbackValidator implements Validator<Loopback> { + + public LoopbackValidator(final NamingContext interfaceContext) { + checkNotNull(interfaceContext, "interfaceContext should not be null"); + } + + @Override + public void validateWrite(@Nonnull final InstanceIdentifier<Loopback> id, @Nonnull final Loopback dataAfter, + @Nonnull final WriteContext writeContext) + throws DataValidationFailedException.CreateValidationFailedException { + // there is nothing to validate yet + } + + @Override + public void validateUpdate(@Nonnull final InstanceIdentifier<Loopback> id, @Nonnull final Loopback dataBefore, + @Nonnull final Loopback dataAfter, @Nonnull final WriteContext writeContext) + throws DataValidationFailedException.UpdateValidationFailedException { + // there is nothing to validate yet + } + + @Override + public void validateDelete(@Nonnull final InstanceIdentifier<Loopback> id, @Nonnull final Loopback dataBefore, + @Nonnull final WriteContext writeContext) + throws DataValidationFailedException.DeleteValidationFailedException { + // there is nothing to validate yet + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/RewriteCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/RewriteCustomizer.java index 2c350eb15..169dd9958 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/RewriteCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/RewriteCustomizer.java @@ -16,7 +16,6 @@ package io.fd.hc2vpp.v3po.interfaces; -import com.google.common.base.Preconditions; import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; @@ -55,7 +54,7 @@ public class RewriteCustomizer extends FutureJVppCustomizer public RewriteCustomizer(@Nonnull final FutureJVppCore futureJVppCore, @Nonnull final NamingContext interfaceContext) { super(futureJVppCore); - this.interfaceContext = Preconditions.checkNotNull(interfaceContext, "interfaceContext should not be null"); + this.interfaceContext = interfaceContext; } @Override diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/RewriteValidator.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/RewriteValidator.java new file mode 100644 index 000000000..e867a10f4 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/RewriteValidator.java @@ -0,0 +1,55 @@ +/* + * 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.v3po.interfaces; + +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.rewrite.attributes.Rewrite; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class RewriteValidator implements Validator<Rewrite> { + + public RewriteValidator(@Nonnull final NamingContext interfaceContext) { + checkNotNull(interfaceContext, "interfaceContext should not be null"); + } + + @Override + public void validateWrite(@Nonnull final InstanceIdentifier<Rewrite> id, @Nonnull final Rewrite dataAfter, + @Nonnull final WriteContext writeContext) + throws DataValidationFailedException.CreateValidationFailedException { + // there is nothing to validate yet + } + + @Override + public void validateUpdate(@Nonnull final InstanceIdentifier<Rewrite> id, @Nonnull final Rewrite dataBefore, + @Nonnull final Rewrite dataAfter, @Nonnull final WriteContext writeContext) + throws DataValidationFailedException.UpdateValidationFailedException { + // there is nothing to validate yet + } + + @Override + public void validateDelete(@Nonnull final InstanceIdentifier<Rewrite> id, @Nonnull final Rewrite dataBefore, + @Nonnull final WriteContext writeContext) + throws DataValidationFailedException.DeleteValidationFailedException { + // there is nothing to validate yet + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceCustomizer.java index d3688d8ea..881447543 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceCustomizer.java @@ -20,7 +20,6 @@ import static com.google.common.base.Preconditions.checkState; import static io.fd.hc2vpp.v3po.util.SubInterfaceUtils.getNumberOfTags; import static io.fd.hc2vpp.v3po.util.SubInterfaceUtils.getSubInterfaceName; -import com.google.common.base.Preconditions; import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; @@ -65,7 +64,7 @@ public class SubInterfaceCustomizer extends FutureJVppCustomizer public SubInterfaceCustomizer(@Nonnull final FutureJVppCore futureJVppCore, @Nonnull final NamingContext interfaceContext) { super(futureJVppCore); - this.interfaceContext = Preconditions.checkNotNull(interfaceContext, "interfaceContext should not be null"); + this.interfaceContext = interfaceContext; } @Override @@ -116,8 +115,8 @@ public class SubInterfaceCustomizer extends FutureJVppCustomizer // TODO HONEYCOMB-183 match should be mandatory final MatchType matchType = subInterface.getMatch().getMatchType(); request.exactMatch = booleanToByte( - matchType instanceof VlanTagged - && ((VlanTagged) matchType).getVlanTagged().isMatchExactTags() + matchType instanceof VlanTagged + && ((VlanTagged) matchType).getVlanTagged().isMatchExactTags() ); request.defaultSub = booleanToByte(matchType instanceof Default); if (numberOfTags > 0) { diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceL2Validator.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceL2Validator.java new file mode 100644 index 000000000..3a2ed5d0c --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceL2Validator.java @@ -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.v3po.interfaces; + +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.l2.config.attributes.L2; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class SubInterfaceL2Validator implements Validator<L2> { + + public SubInterfaceL2Validator(final NamingContext interfaceContext, + final NamingContext bridgeDomainContext) { + checkNotNull(interfaceContext, "interfaceContext should not be null"); + checkNotNull(bridgeDomainContext, "bridgeDomainContext should not be null"); + } + + @Override + public void validateWrite(@Nonnull final InstanceIdentifier<L2> id, @Nonnull final L2 dataAfter, + @Nonnull final WriteContext writeContext) + throws DataValidationFailedException.CreateValidationFailedException { + // there is nothing to validate yet + } + + @Override + public void validateUpdate(@Nonnull final InstanceIdentifier<L2> id, @Nonnull final L2 dataBefore, + @Nonnull final L2 dataAfter, + @Nonnull final WriteContext writeContext) + throws DataValidationFailedException.UpdateValidationFailedException { + // there is nothing to validate yet + } + + @Override + public void validateDelete(@Nonnull final InstanceIdentifier<L2> id, @Nonnull final L2 dataBefore, + @Nonnull final WriteContext writeContext) + throws DataValidationFailedException.DeleteValidationFailedException { + // there is nothing to validate yet + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceRoutingCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceRoutingCustomizer.java index fbaccfa1c..951944a57 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceRoutingCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceRoutingCustomizer.java @@ -16,21 +16,14 @@ package io.fd.hc2vpp.v3po.interfaces; -import static com.google.common.base.Preconditions.checkState; import static io.fd.hc2vpp.v3po.util.SubInterfaceUtils.subInterfaceFullNameConfig; -import java.util.Optional; import io.fd.hc2vpp.common.translate.util.NamingContext; import io.fd.honeycomb.translate.spi.write.WriterCustomizer; -import io.fd.honeycomb.translate.util.RWUtils; import io.fd.honeycomb.translate.write.WriteContext; import io.fd.honeycomb.translate.write.WriteFailedException; import io.fd.jvpp.core.future.FutureJVppCore; -import java.util.List; import javax.annotation.Nonnull; -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.sub._interface.ip4.attributes.Ipv4; -import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.ip6.attributes.Ipv6; 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; @@ -45,8 +38,6 @@ public class SubInterfaceRoutingCustomizer extends RoutingCustomizer implements public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Routing> instanceIdentifier, @Nonnull final Routing routing, @Nonnull final WriteContext writeContext) throws WriteFailedException { - checkState(isAddressNotPresentForSubInterface(instanceIdentifier, writeContext, true), - "Cannot change routing configuration, if address is present for sub-interface"); setRouting(instanceIdentifier, subInterfaceFullNameConfig(instanceIdentifier), routing, writeContext); } @@ -54,8 +45,6 @@ public class SubInterfaceRoutingCustomizer extends RoutingCustomizer implements public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<Routing> instanceIdentifier, @Nonnull final Routing routing, @Nonnull final Routing d1, @Nonnull final WriteContext writeContext) throws WriteFailedException { - checkState(isAddressNotPresentForSubInterface(instanceIdentifier, writeContext, true), - "Cannot change routing configuration, if address is present for sub-interface"); setRouting(instanceIdentifier, subInterfaceFullNameConfig(instanceIdentifier), routing, writeContext); } @@ -63,35 +52,6 @@ public class SubInterfaceRoutingCustomizer extends RoutingCustomizer implements public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Routing> instanceIdentifier, @Nonnull final Routing routing, @Nonnull final WriteContext writeContext) throws WriteFailedException { - checkState(isAddressNotPresentForSubInterface(instanceIdentifier, writeContext, false), - "Cannot change routing configuration, if address is present for sub-interface"); disableRouting(instanceIdentifier, subInterfaceFullNameConfig(instanceIdentifier), writeContext); } - - /** - * Returns true if interface does not have v4/v6 addresses configured - */ - private boolean isAddressNotPresentForSubInterface(@Nonnull final InstanceIdentifier<Routing> id, - @Nonnull final WriteContext ctx, - boolean checkBefore) { - final Optional<SubInterface> subInterfaceData = checkBefore - ? - ctx.readBefore(RWUtils.cutId(id, SubInterface.class)) - : - ctx.readAfter(RWUtils.cutId(id, SubInterface.class)); - - if (subInterfaceData.isPresent()) { - final SubInterface subInterface = subInterfaceData.get(); - - final boolean v4NotPresent = - java.util.Optional.ofNullable(subInterface.getIpv4()).map(Ipv4::getAddress).map(List::isEmpty) - .orElse(true); - - final boolean v6NotPresent = - java.util.Optional.ofNullable(subInterface.getIpv6()).map(Ipv6::getAddress).map(List::isEmpty) - .orElse(true); - return v4NotPresent && v6NotPresent; - } - return true; - } } diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceRoutingValidator.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceRoutingValidator.java new file mode 100644 index 000000000..85b864d14 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceRoutingValidator.java @@ -0,0 +1,110 @@ +/* + * 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.v3po.interfaces; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; + +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.util.RWUtils; +import io.fd.honeycomb.translate.write.DataValidationFailedException.CreateValidationFailedException; +import io.fd.honeycomb.translate.write.DataValidationFailedException.DeleteValidationFailedException; +import io.fd.honeycomb.translate.write.DataValidationFailedException.UpdateValidationFailedException; +import io.fd.honeycomb.translate.write.Validator; +import io.fd.honeycomb.translate.write.WriteContext; +import java.util.List; +import java.util.Optional; +import javax.annotation.Nonnull; +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.sub._interface.ip4.attributes.Ipv4; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.ip6.attributes.Ipv6; +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 SubInterfaceRoutingValidator implements Validator<Routing> { + + public SubInterfaceRoutingValidator(@Nonnull final NamingContext interfaceContext) { + checkNotNull(interfaceContext, "interfaceContext should not be null"); + } + + @Override + public void validateWrite(@Nonnull final InstanceIdentifier<Routing> id, @Nonnull final Routing dataAfter, + @Nonnull final WriteContext writeContext) + throws CreateValidationFailedException { + try { + checkInterfaceAddressConf(id, writeContext, true); + } catch (Exception e) { + throw new CreateValidationFailedException(id, dataAfter, e); + } + } + + @Override + public void validateUpdate(@Nonnull final InstanceIdentifier<Routing> id, @Nonnull final Routing dataBefore, + @Nonnull final Routing dataAfter, @Nonnull final WriteContext writeContext) + throws UpdateValidationFailedException { + try { + checkInterfaceAddressConf(id, writeContext, true); + } catch (Exception e) { + throw new UpdateValidationFailedException(id, dataBefore, dataAfter, e); + } + } + + @Override + public void validateDelete(@Nonnull final InstanceIdentifier<Routing> id, @Nonnull final Routing dataBefore, + @Nonnull final WriteContext writeContext) + throws DeleteValidationFailedException { + try { + checkInterfaceAddressConf(id, writeContext, false); + } catch (Exception e) { + throw new DeleteValidationFailedException(id, e); + } + } + + private void checkInterfaceAddressConf(@Nonnull final InstanceIdentifier<Routing> id, + @Nonnull final WriteContext ctx, + boolean checkBefore) { + checkState(isAddressNotPresentForSubInterface(id, ctx, checkBefore), + "Cannot change routing configuration, if address is present for sub-interface"); + } + + /** + * Returns true if interface does not have v4/v6 addresses configured + */ + private boolean isAddressNotPresentForSubInterface(@Nonnull final InstanceIdentifier<Routing> id, + @Nonnull final WriteContext ctx, + boolean checkBefore) { + final Optional<SubInterface> subInterfaceData = checkBefore + ? + ctx.readBefore(RWUtils.cutId(id, SubInterface.class)) + : + ctx.readAfter(RWUtils.cutId(id, SubInterface.class)); + + if (subInterfaceData.isPresent()) { + final SubInterface subInterface = subInterfaceData.get(); + + final boolean v4NotPresent = + java.util.Optional.ofNullable(subInterface.getIpv4()).map(Ipv4::getAddress).map(List::isEmpty) + .orElse(true); + + final boolean v6NotPresent = + java.util.Optional.ofNullable(subInterface.getIpv6()).map(Ipv6::getAddress).map(List::isEmpty) + .orElse(true); + return v4NotPresent && v6NotPresent; + } + return true; + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceUnnumberedValidator.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceUnnumberedValidator.java new file mode 100644 index 000000000..8cc565c5a --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceUnnumberedValidator.java @@ -0,0 +1,55 @@ +/* + * 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.v3po.interfaces; + +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.unnumbered.interfaces.rev180103.unnumbered.config.attributes.Unnumbered; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class SubInterfaceUnnumberedValidator implements Validator<Unnumbered> { + + public SubInterfaceUnnumberedValidator(final NamingContext interfaceContext) { + checkNotNull(interfaceContext, "interfaceContext should not be null"); + } + + @Override + public void validateWrite(@Nonnull final InstanceIdentifier<Unnumbered> id, @Nonnull final Unnumbered dataAfter, + @Nonnull final WriteContext writeContext) + throws DataValidationFailedException.CreateValidationFailedException { + checkNotNull(dataAfter.getUse()); + } + + @Override + public void validateUpdate(@Nonnull final InstanceIdentifier<Unnumbered> id, @Nonnull final Unnumbered dataBefore, + @Nonnull final Unnumbered dataAfter, @Nonnull final WriteContext writeContext) + throws DataValidationFailedException.UpdateValidationFailedException { + checkNotNull(dataAfter.getUse()); + } + + @Override + public void validateDelete(@Nonnull final InstanceIdentifier<Unnumbered> id, @Nonnull final Unnumbered dataBefore, + @Nonnull final WriteContext writeContext) + throws DataValidationFailedException.DeleteValidationFailedException { + checkNotNull(dataBefore.getUse()); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceValidator.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceValidator.java new file mode 100644 index 000000000..0f8a86232 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceValidator.java @@ -0,0 +1,62 @@ +/* + * 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.v3po.interfaces; + +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.interfaces._interface.sub.interfaces.SubInterface; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class SubInterfaceValidator implements Validator<SubInterface> { + + public SubInterfaceValidator(@Nonnull final NamingContext interfaceContext) { + checkNotNull(interfaceContext, "interfaceContext should not be null"); + } + + @Override + public void validateWrite(@Nonnull final InstanceIdentifier<SubInterface> id, @Nonnull final SubInterface dataAfter, + @Nonnull final WriteContext writeContext) + throws DataValidationFailedException.CreateValidationFailedException { + try { + checkSubInterface(dataAfter); + } catch (Exception e) { + throw new DataValidationFailedException.CreateValidationFailedException(id, dataAfter, e); + } + } + + @Override + public void validateUpdate(@Nonnull final InstanceIdentifier<SubInterface> id, + @Nonnull final SubInterface dataBefore, + @Nonnull final SubInterface dataAfter, @Nonnull final WriteContext writeContext) + throws DataValidationFailedException.UpdateValidationFailedException { + try { + checkSubInterface(dataAfter); + } catch (Exception e) { + throw new DataValidationFailedException.UpdateValidationFailedException(id, dataBefore, dataAfter, e); + } + } + + private void checkSubInterface(final SubInterface data) { + checkNotNull(data.getIdentifier(), "Identifier cannot be null"); + checkNotNull(data.getMatch(), "Match cannot be null"); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/TapV2Validator.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/TapV2Validator.java new file mode 100644 index 000000000..0d3c3efa6 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/TapV2Validator.java @@ -0,0 +1,55 @@ +/* + * 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.v3po.interfaces; + +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.v3po.rev190502.interfaces._interface.TapV2; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class TapV2Validator implements Validator<TapV2> { + + public TapV2Validator(final NamingContext interfaceContext) { + checkNotNull(interfaceContext, "interfaceContext should not be null"); + } + + @Override + public void validateWrite(@Nonnull final InstanceIdentifier<TapV2> id, @Nonnull final TapV2 dataAfter, + @Nonnull final WriteContext writeContext) + throws DataValidationFailedException.CreateValidationFailedException { + // there is nothing to validate yet + } + + @Override + public void validateUpdate(@Nonnull final InstanceIdentifier<TapV2> id, @Nonnull final TapV2 dataBefore, + @Nonnull final TapV2 dataAfter, @Nonnull final WriteContext writeContext) + throws DataValidationFailedException.UpdateValidationFailedException { + // there is nothing to validate yet + } + + @Override + public void validateDelete(@Nonnull final InstanceIdentifier<TapV2> id, @Nonnull final TapV2 dataBefore, + @Nonnull final WriteContext writeContext) + throws DataValidationFailedException.DeleteValidationFailedException { + // there is nothing to validate yet + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/VhostUserCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/VhostUserCustomizer.java index c009e712c..61ce5468c 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/VhostUserCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/VhostUserCustomizer.java @@ -16,7 +16,6 @@ package io.fd.hc2vpp.v3po.interfaces; -import com.google.common.base.Preconditions; import io.fd.hc2vpp.common.translate.util.AbstractInterfaceTypeCustomizer; import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; @@ -52,7 +51,7 @@ public class VhostUserCustomizer extends AbstractInterfaceTypeCustomizer<VhostUs public VhostUserCustomizer(@Nonnull final FutureJVppCore vppApi, @Nonnull final NamingContext interfaceContext) { super(vppApi); - this.interfaceContext = Preconditions.checkNotNull(interfaceContext, "interfaceContext should not be null"); + this.interfaceContext = interfaceContext; } @Override diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/VhostUserValidator.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/VhostUserValidator.java new file mode 100644 index 000000000..5526bbb22 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/VhostUserValidator.java @@ -0,0 +1,55 @@ +/* + * 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.v3po.interfaces; + +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.v3po.rev190502.interfaces._interface.VhostUser; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class VhostUserValidator implements Validator<VhostUser> { + + public VhostUserValidator(@Nonnull final NamingContext interfaceContext) { + checkNotNull(interfaceContext, "interfaceContext should not be null"); + } + + @Override + public void validateWrite(@Nonnull final InstanceIdentifier<VhostUser> id, @Nonnull final VhostUser dataAfter, + @Nonnull final WriteContext writeContext) + throws DataValidationFailedException.CreateValidationFailedException { + checkNotNull(dataAfter.getSocket(), "Socket cannot be null"); + } + + @Override + public void validateUpdate(@Nonnull final InstanceIdentifier<VhostUser> id, @Nonnull final VhostUser dataBefore, + @Nonnull final VhostUser dataAfter, @Nonnull final WriteContext writeContext) + throws DataValidationFailedException.UpdateValidationFailedException { + checkNotNull(dataAfter.getSocket(), "Socket cannot be null"); + } + + @Override + public void validateDelete(@Nonnull final InstanceIdentifier<VhostUser> id, @Nonnull final VhostUser dataBefore, + @Nonnull final WriteContext writeContext) + throws DataValidationFailedException.DeleteValidationFailedException { + // there is nothing to validate yet + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/VxlanCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/VxlanCustomizer.java index fba439460..638d7ec62 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/VxlanCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/VxlanCustomizer.java @@ -16,8 +16,6 @@ package io.fd.hc2vpp.v3po.interfaces; -import static com.google.common.base.Preconditions.checkArgument; - import io.fd.hc2vpp.common.translate.util.AbstractInterfaceTypeCustomizer; import io.fd.hc2vpp.common.translate.util.AddressTranslator; import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; @@ -49,8 +47,8 @@ public class VxlanCustomizer extends AbstractInterfaceTypeCustomizer<Vxlan> impl private final DisabledInterfacesManager interfaceDisableContext; public VxlanCustomizer(@Nonnull final FutureJVppCore vppApi, - @Nonnull final NamingContext interfaceNamingContext, - @Nonnull final DisabledInterfacesManager interfaceDisableContext) { + @Nonnull final NamingContext interfaceNamingContext, + @Nonnull final DisabledInterfacesManager interfaceDisableContext) { super(vppApi); this.interfaceNamingContext = interfaceNamingContext; this.interfaceDisableContext = interfaceDisableContext; @@ -63,29 +61,27 @@ public class VxlanCustomizer extends AbstractInterfaceTypeCustomizer<Vxlan> impl @Override protected final void writeInterface(@Nonnull final InstanceIdentifier<Vxlan> id, @Nonnull final Vxlan dataAfter, - @Nonnull final WriteContext writeContext) - throws WriteFailedException { + @Nonnull final WriteContext writeContext) + throws WriteFailedException { final String swIfName = id.firstKeyOf(Interface.class).getName(); createVxlanTunnel(id, swIfName, dataAfter, writeContext); } @Override public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Vxlan> id, @Nonnull final Vxlan dataBefore, - @Nonnull final WriteContext writeContext) - throws WriteFailedException { + @Nonnull final WriteContext writeContext) + throws WriteFailedException { final String swIfName = id.firstKeyOf(Interface.class).getName(); deleteVxlanTunnel(id, swIfName, dataBefore, writeContext); } private void createVxlanTunnel(final InstanceIdentifier<Vxlan> id, final String swIfName, final Vxlan vxlan, - final WriteContext writeContext) - throws WriteFailedException { + final WriteContext writeContext) + throws WriteFailedException { final byte isIpv6 = (byte) (isIpv6(vxlan) - ? 1 - : 0); + ? 1 + : 0); - checkArgument(vxlan.getEncapVrfId() != null && vxlan.getEncapVrfId().getValue() != null, - "encap-vrf-id is mandatory but was not given"); int encapVrfId = vxlan.getEncapVrfId().getValue().intValue(); int vni = vxlan.getVni().getValue().intValue(); @@ -98,8 +94,8 @@ public class VxlanCustomizer extends AbstractInterfaceTypeCustomizer<Vxlan> impl LOG.debug("Setting vxlan tunnel for interface: {}. Vxlan: {}", swIfName, vxlan); final CompletionStage<VxlanAddDelTunnelReply> vxlanAddDelTunnelReplyCompletionStage = - getFutureJVpp().vxlanAddDelTunnel(getVxlanTunnelRequest((byte) 1 /* is add */, vxlan.getSrc(), - vxlan.getDst(), encapVrfId, decapNext, vni, isIpv6)); + getFutureJVpp().vxlanAddDelTunnel(getVxlanTunnelRequest((byte) 1 /* is add */, vxlan.getSrc(), + vxlan.getDst(), encapVrfId, decapNext, vni, isIpv6)); final VxlanAddDelTunnelReply reply = getReplyForCreate(vxlanAddDelTunnelReplyCompletionStage.toCompletableFuture(), id, vxlan); @@ -131,25 +127,16 @@ public class VxlanCustomizer extends AbstractInterfaceTypeCustomizer<Vxlan> impl } private boolean isIpv6(final Vxlan vxlan) { - if (vxlan.getSrc().getIpv4AddressNoZone() == null) { - checkArgument(vxlan.getDst().getIpv4AddressNoZone() == null, "Inconsistent ip addresses: %s, %s", vxlan.getSrc(), - vxlan.getDst()); - return true; - } else { - checkArgument(vxlan.getDst().getIpv6AddressNoZone() == null, "Inconsistent ip addresses: %s, %s", vxlan.getSrc(), - vxlan.getDst()); - return false; - } + return vxlan.getSrc().getIpv4AddressNoZone() == null; + } private void deleteVxlanTunnel(final InstanceIdentifier<Vxlan> id, final String swIfName, final Vxlan vxlan, - final WriteContext writeContext) throws WriteFailedException { + final WriteContext writeContext) throws WriteFailedException { final byte isIpv6 = (byte) (isIpv6(vxlan) - ? 1 - : 0); + ? 1 + : 0); - checkArgument(vxlan.getEncapVrfId() != null && vxlan.getEncapVrfId().getValue() != null, - "encap-vrf-id is mandatory but was not given"); int encapVrfId = vxlan.getEncapVrfId().getValue().intValue(); int vni = vxlan.getVni().getValue().intValue(); @@ -162,8 +149,8 @@ public class VxlanCustomizer extends AbstractInterfaceTypeCustomizer<Vxlan> impl LOG.debug("Deleting vxlan tunnel for interface: {}. Vxlan: {}", swIfName, vxlan); final CompletionStage<VxlanAddDelTunnelReply> vxlanAddDelTunnelReplyCompletionStage = - getFutureJVpp().vxlanAddDelTunnel(getVxlanTunnelRequest((byte) 0 /* is add */, vxlan.getSrc(), - vxlan.getDst(), encapVrfId, decapNext, vni, isIpv6)); + getFutureJVpp().vxlanAddDelTunnel(getVxlanTunnelRequest((byte) 0 /* is add */, vxlan.getSrc(), + vxlan.getDst(), encapVrfId, decapNext, vni, isIpv6)); getReplyForDelete(vxlanAddDelTunnelReplyCompletionStage.toCompletableFuture(), id); LOG.debug("Vxlan tunnel deleted successfully for: {}, vxlan: {}", swIfName, vxlan); diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/VxlanGpeCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/VxlanGpeCustomizer.java index d61f50b09..b3629415b 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/VxlanGpeCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/VxlanGpeCustomizer.java @@ -16,8 +16,6 @@ package io.fd.hc2vpp.v3po.interfaces; -import static com.google.common.base.Preconditions.checkArgument; - import io.fd.hc2vpp.common.translate.util.AbstractInterfaceTypeCustomizer; import io.fd.hc2vpp.common.translate.util.AddressTranslator; import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; @@ -90,8 +88,9 @@ public class VxlanGpeCustomizer extends AbstractInterfaceTypeCustomizer<VxlanGpe LOG.debug("Setting VxlanGpe tunnel for interface: {}. VxlanGpe: {}", swIfName, vxlanGpe); final CompletionStage<VxlanGpeAddDelTunnelReply> VxlanGpeAddDelTunnelReplyCompletionStage = - getFutureJVpp().vxlanGpeAddDelTunnel(getVxlanGpeTunnelRequest((byte) 1 /* is add */, vxlanGpe.getLocal(), - vxlanGpe.getRemote(), vni, protocol, encapVrfId, decapVrfId, isIpv6)); + getFutureJVpp() + .vxlanGpeAddDelTunnel(getVxlanGpeTunnelRequest((byte) 1 /* is add */, vxlanGpe.getLocal(), + vxlanGpe.getRemote(), vni, protocol, encapVrfId, decapVrfId, isIpv6)); final VxlanGpeAddDelTunnelReply reply = getReplyForCreate(VxlanGpeAddDelTunnelReplyCompletionStage.toCompletableFuture(), id, vxlanGpe); @@ -115,17 +114,8 @@ public class VxlanGpeCustomizer extends AbstractInterfaceTypeCustomizer<VxlanGpe } private boolean isIpv6(final VxlanGpe vxlanGpe) { - if (vxlanGpe.getLocal().getIpv4AddressNoZone() == null) { - checkArgument(vxlanGpe.getRemote().getIpv4AddressNoZone() == null, "Inconsistent ip addresses: %s, %s", - vxlanGpe.getLocal(), - vxlanGpe.getRemote()); - return true; - } else { - checkArgument(vxlanGpe.getRemote().getIpv6AddressNoZone() == null, "Inconsistent ip addresses: %s, %s", - vxlanGpe.getLocal(), - vxlanGpe.getRemote()); - return false; - } + return vxlanGpe.getLocal().getIpv4AddressNoZone() == null; + } private void deleteVxlanGpeTunnel(final InstanceIdentifier<VxlanGpe> id, final String swIfName, @@ -143,8 +133,8 @@ public class VxlanGpeCustomizer extends AbstractInterfaceTypeCustomizer<VxlanGpe LOG.debug("Deleting VxlanGpe tunnel for interface: {}. VxlanGpe: {}", swIfName, vxlanGpe); final CompletionStage<VxlanGpeAddDelTunnelReply> VxlanGpeAddDelTunnelReplyCompletionStage = getFutureJVpp() - .vxlanGpeAddDelTunnel(getVxlanGpeTunnelRequest((byte) 0 /* is delete */, vxlanGpe.getLocal(), - vxlanGpe.getRemote(), vni, protocol, encapVrfId, decapVrfId, isIpv6)); + .vxlanGpeAddDelTunnel(getVxlanGpeTunnelRequest((byte) 0 /* is delete */, vxlanGpe.getLocal(), + vxlanGpe.getRemote(), vni, protocol, encapVrfId, decapVrfId, isIpv6)); getReplyForDelete(VxlanGpeAddDelTunnelReplyCompletionStage.toCompletableFuture(), id); final int index = interfaceNamingContext.getIndex(swIfName, writeContext.getMappingContext()); // Mark this interface as disabled to not include it in operational reads diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/VxlanGpeValidator.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/VxlanGpeValidator.java new file mode 100644 index 000000000..22b5365f5 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/VxlanGpeValidator.java @@ -0,0 +1,78 @@ +/* + * 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.v3po.interfaces; + +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.hc2vpp.v3po.DisabledInterfacesManager; +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.v3po.rev190502.interfaces._interface.VxlanGpe; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class VxlanGpeValidator implements Validator<VxlanGpe> { + + public VxlanGpeValidator(@Nonnull final NamingContext interfaceNamingContext, + @Nonnull final DisabledInterfacesManager interfaceDisableContext) { + checkNotNull(interfaceNamingContext, "interfaceContext should not be null"); + checkNotNull(interfaceDisableContext, "DisabledInterfacesManager should not be null"); + } + + @Override + public void validateWrite(@Nonnull final InstanceIdentifier<VxlanGpe> id, @Nonnull final VxlanGpe dataAfter, + @Nonnull final WriteContext writeContext) + throws DataValidationFailedException.CreateValidationFailedException { + try { + validateVxlanGpe(dataAfter); + } catch (Exception e) { + throw new DataValidationFailedException.CreateValidationFailedException(id, dataAfter, e); + } + } + + @Override + public void validateDelete(@Nonnull final InstanceIdentifier<VxlanGpe> id, @Nonnull final VxlanGpe dataBefore, + @Nonnull final WriteContext writeContext) + throws DataValidationFailedException.DeleteValidationFailedException { + try { + validateVxlanGpe(dataBefore); + } catch (Exception e) { + throw new DataValidationFailedException.DeleteValidationFailedException(id, e); + } + } + + private void validateVxlanGpe(final VxlanGpe data) { + checkNotNull(data.getLocal(), "Local address cannot be null"); + checkNotNull(data.getRemote(), "Remote address cannot be null"); + if (data.getLocal().getIpv4AddressNoZone() == null) { + checkArgument(data.getRemote().getIpv4AddressNoZone() == null, "Inconsistent ip addresses: %s, %s", + data.getLocal(), + data.getRemote()); + } else { + checkArgument(data.getRemote().getIpv6AddressNoZone() == null, "Inconsistent ip addresses: %s, %s", + data.getLocal(), + data.getRemote()); + } + checkNotNull(data.getEncapVrfId(), "encap-vrf-id is mandatory but was not given"); + checkNotNull(data.getDecapVrfId(), "decap-vrf-id is mandatory but was not given"); + checkNotNull(data.getVni(), "VNI cannot be null"); + checkNotNull(data.getNextProtocol(), "Next protocol cannot be null"); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/VxlanValidator.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/VxlanValidator.java new file mode 100644 index 000000000..1496a884a --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/VxlanValidator.java @@ -0,0 +1,79 @@ +/* + * 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.v3po.interfaces; + +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.hc2vpp.v3po.DisabledInterfacesManager; +import io.fd.honeycomb.translate.write.DataValidationFailedException.CreateValidationFailedException; +import io.fd.honeycomb.translate.write.DataValidationFailedException.DeleteValidationFailedException; +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.v3po.rev190502.interfaces._interface.Vxlan; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class VxlanValidator implements Validator<Vxlan> { + + public VxlanValidator(@Nonnull final NamingContext interfaceNamingContext, + @Nonnull final DisabledInterfacesManager disabledInterfacesManager) { + checkNotNull(interfaceNamingContext, "interfaceContext should not be null"); + checkNotNull(disabledInterfacesManager, "disabledInterfacesManager should not be null"); + } + + @Override + public void validateWrite(@Nonnull final InstanceIdentifier<Vxlan> id, @Nonnull final Vxlan dataAfter, + @Nonnull final WriteContext writeContext) + throws CreateValidationFailedException { + try { + validateVxlan(dataAfter); + } catch (Exception e) { + throw new CreateValidationFailedException(id, dataAfter, e); + } + } + + @Override + public void validateDelete(@Nonnull final InstanceIdentifier<Vxlan> id, @Nonnull final Vxlan dataBefore, + @Nonnull final WriteContext writeContext) + throws DeleteValidationFailedException { + try { + validateVxlan(dataBefore); + } catch (Exception e) { + throw new DeleteValidationFailedException(id, e); + } + } + + private void validateVxlan(final Vxlan data) { + + checkNotNull(data.getSrc(), "Source cannot be null"); + checkNotNull(data.getDst(), "Destination cannot be null"); + if (data.getSrc().getIpv4AddressNoZone() == null) { + checkArgument(data.getDst().getIpv4AddressNoZone() == null, "Inconsistent ip addresses: %s, %s", + data.getSrc(), + data.getDst()); + } else { + checkArgument(data.getDst().getIpv6AddressNoZone() == null, "Inconsistent ip addresses: %s, %s", + data.getSrc(), + data.getDst()); + } + checkArgument(data.getEncapVrfId() != null && data.getEncapVrfId().getValue() != null, + "encap-vrf-id is mandatory but was not given"); + checkNotNull(data.getVni(), "VNI cannot be null"); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/pbb/PbbRewriteCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/pbb/PbbRewriteCustomizer.java index 13fccf7dd..86622663d 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/pbb/PbbRewriteCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/pbb/PbbRewriteCustomizer.java @@ -16,8 +16,6 @@ package io.fd.hc2vpp.v3po.interfaces.pbb; -import static com.google.common.base.Preconditions.checkNotNull; - import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; import io.fd.hc2vpp.common.translate.util.MacTranslator; @@ -44,7 +42,7 @@ public class PbbRewriteCustomizer extends FutureJVppCustomizer public PbbRewriteCustomizer(@Nonnull final FutureJVppCore futureJVppCore, @Nonnull final NamingContext interfaceNamingContext) { super(futureJVppCore); - this.interfaceNamingContext = checkNotNull(interfaceNamingContext, "Interface naming context cannot be null"); + this.interfaceNamingContext = interfaceNamingContext; } @Override @@ -84,16 +82,16 @@ public class PbbRewriteCustomizer extends FutureJVppCustomizer private void setPbbRewrite(final InstanceIdentifier<PbbRewrite> id, final PbbRewrite data, final WriteContext writeContext, final boolean disable) throws TimeoutException, VppBaseCallException { - final String interfaceName = checkNotNull(id.firstKeyOf(Interface.class), "Interface key not found").getName(); + final String interfaceName = id.firstKeyOf(Interface.class).getName(); final L2InterfacePbbTagRewrite request = new L2InterfacePbbTagRewrite(); //checking all attributes in preconditions(pbb-rewrite is subcontainer, so there can't be mandatory statements) request.swIfIndex = interfaceNamingContext.getIndex(interfaceName, writeContext.getMappingContext()); - request.bDmac = parseMac(verifiedDestinationAddress(data)); - request.bSmac = parseMac(verifiedSourceAddress(data)); - request.bVlanid = verifiedBVlanId(data); - request.iSid = verifiedISid(data); + request.bDmac = parseMac(data.getDestinationAddress().getValue()); + request.bSmac = parseMac(data.getSourceAddress().getValue()); + request.bVlanid = data.getBVlanTagVlanId().shortValue(); + request.iSid = data.getITagIsid().intValue(); request.vtrOp = verifiedOperation(data, disable); //not sure whats gonna happen to this attribute, so its left optional for now @@ -104,27 +102,10 @@ public class PbbRewriteCustomizer extends FutureJVppCustomizer getReply(getFutureJVpp().l2InterfacePbbTagRewrite(request).toCompletableFuture()); } - private String verifiedDestinationAddress(final PbbRewrite data) { - return checkNotNull(data.getDestinationAddress(), "Destination address cannot be null").getValue(); - } - - private String verifiedSourceAddress(final PbbRewrite data) { - return checkNotNull(data.getSourceAddress(), "Destination address cannot be null").getValue(); - } - - private short verifiedBVlanId(final PbbRewrite data) { - return checkNotNull(data.getBVlanTagVlanId(), "BVlan id cannot be null").shortValue(); - } - - private int verifiedISid(final PbbRewrite data) { - return checkNotNull(data.getITagIsid(), "ISid cannot be null").intValue(); - } - // if disabled ,then uses non-public allowed value 0, which is equal to operation disable private int verifiedOperation(final PbbRewrite data, final boolean disable) { - return disable ? OPERATION_DISABLE - : checkNotNull(data.getInterfaceOperation(), "Operation cannot be null").getIntValue(); + : data.getInterfaceOperation().getIntValue(); } } diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/pbb/PbbRewriteValidator.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/pbb/PbbRewriteValidator.java new file mode 100644 index 000000000..e5ec7fc69 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/pbb/PbbRewriteValidator.java @@ -0,0 +1,82 @@ +/* + * 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.v3po.interfaces.pbb; + +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.pbb.rev161214.interfaces._interface.PbbRewrite; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.Interface; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class PbbRewriteValidator implements Validator<PbbRewrite> { + + + public PbbRewriteValidator(@Nonnull final NamingContext interfaceNamingContext) { + checkNotNull(interfaceNamingContext, "Interface naming context cannot be null"); + } + + @Override + public void validateWrite(@Nonnull final InstanceIdentifier<PbbRewrite> id, @Nonnull final PbbRewrite dataAfter, + @Nonnull final WriteContext writeContext) + throws DataValidationFailedException.CreateValidationFailedException { + try { + validatePbbRewrite(id, dataAfter, false); + } catch(Exception e) { + throw new DataValidationFailedException.CreateValidationFailedException(id, dataAfter, e); + } + } + + @Override + public void validateUpdate(@Nonnull final InstanceIdentifier<PbbRewrite> id, @Nonnull final PbbRewrite dataBefore, + @Nonnull final PbbRewrite dataAfter, @Nonnull final WriteContext writeContext) + throws DataValidationFailedException.UpdateValidationFailedException { + + try { + validatePbbRewrite(id, dataAfter, false); + } catch(Exception e) { + throw new DataValidationFailedException.UpdateValidationFailedException(id, dataBefore, dataAfter, e); + } + } + + @Override + public void validateDelete(@Nonnull final InstanceIdentifier<PbbRewrite> id, @Nonnull final PbbRewrite dataBefore, + @Nonnull final WriteContext writeContext) + throws DataValidationFailedException.DeleteValidationFailedException { + try { + validatePbbRewrite(id, dataBefore, true); + } catch(Exception e) { + throw new DataValidationFailedException.DeleteValidationFailedException(id, e); + } + } + + private void validatePbbRewrite(final InstanceIdentifier<PbbRewrite> id, @Nonnull final PbbRewrite data, + final boolean disable) { + checkNotNull(id.firstKeyOf(Interface.class), "Interface key not found"); + checkNotNull(data.getDestinationAddress(), "Destination address cannot be null"); + checkNotNull(data.getSourceAddress(), "Source address cannot be null"); + checkNotNull(data.getBVlanTagVlanId(), "BVlan id cannot be null"); + checkNotNull(data.getITagIsid(), "ISid cannot be null"); + if (disable) { + checkNotNull(data.getInterfaceOperation(), "Operation cannot be null"); + } + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/span/MirroredInterfaceValidator.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/span/MirroredInterfaceValidator.java new file mode 100644 index 000000000..f51ad6f0c --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/span/MirroredInterfaceValidator.java @@ -0,0 +1,79 @@ +/* + * 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.v3po.interfaces.span; + +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 java.util.function.Function; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.span.attributes.MirroredInterfaces; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.span.attributes.mirrored.interfaces.MirroredInterface; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class MirroredInterfaceValidator implements Validator<MirroredInterface> { + + public MirroredInterfaceValidator(@Nonnull final NamingContext ifcContext, + @Nonnull final Function<InstanceIdentifier<MirroredInterfaces>, String> destinationInterfaceNameExtractor) { + checkNotNull(ifcContext, "Interface naming context cannot be null"); + checkNotNull(destinationInterfaceNameExtractor, "Destination Interface Name extractor cannot be null"); + } + + @Override + public void validateWrite(@Nonnull final InstanceIdentifier<MirroredInterface> id, + @Nonnull final MirroredInterface dataAfter, + @Nonnull final WriteContext writeContext) + throws DataValidationFailedException.CreateValidationFailedException { + try { + checkMirroredInterfaceData(dataAfter); + } catch (Exception e) { + throw new DataValidationFailedException.CreateValidationFailedException(id, dataAfter, e); + } + } + + @Override + public void validateUpdate(@Nonnull final InstanceIdentifier<MirroredInterface> id, + @Nonnull final MirroredInterface dataBefore, + @Nonnull final MirroredInterface dataAfter, @Nonnull final WriteContext writeContext) + throws DataValidationFailedException.UpdateValidationFailedException { + try { + checkMirroredInterfaceData(dataAfter); + } catch (Exception e) { + throw new DataValidationFailedException.UpdateValidationFailedException(id, dataBefore, dataAfter, e); + } + } + + @Override + public void validateDelete(@Nonnull final InstanceIdentifier<MirroredInterface> id, + @Nonnull final MirroredInterface dataBefore, + @Nonnull final WriteContext writeContext) + throws DataValidationFailedException.DeleteValidationFailedException { + try { + checkMirroredInterfaceData(dataBefore); + } catch (Exception e) { + throw new DataValidationFailedException.DeleteValidationFailedException(id, e); + } + } + + private void checkMirroredInterfaceData(final MirroredInterface data) { + checkNotNull(data.getIfaceRef(), "IfaceRef cannot be null"); + checkNotNull(data.getState(), "State cannot be null"); + } +} diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/AfPacketValidatorTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/AfPacketValidatorTest.java new file mode 100644 index 000000000..ebdc770fe --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/AfPacketValidatorTest.java @@ -0,0 +1,88 @@ +/* + * 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.v3po.interfaces; + +import static org.mockito.MockitoAnnotations.initMocks; + +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.DataValidationFailedException.CreateValidationFailedException; +import io.fd.honeycomb.translate.write.DataValidationFailedException.DeleteValidationFailedException; +import io.fd.honeycomb.translate.write.DataValidationFailedException.UpdateValidationFailedException; +import io.fd.honeycomb.translate.write.WriteContext; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.VppInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.AfPacket; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.AfPacketBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.Interfaces; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.InterfaceKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class AfPacketValidatorTest { + + private AfPacketValidator validator; + + @Mock + private WriteContext writeContext; + + private final String IFACE_NAME = "veth1"; + private final InstanceIdentifier<AfPacket> ID = + InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IFACE_NAME)) + .augmentation(VppInterfaceAugmentation.class).child(AfPacket.class); + + @Before + public void setUp() { + initMocks(this); + NamingContext ifcContext = new NamingContext("testInterfaceContext", "testInterfaceContext"); + validator = new AfPacketValidator(ifcContext); + } + + @Test + public void testWriteSuccessful() throws CreateValidationFailedException { + validator.validateWrite(ID, afPacket(IFACE_NAME), writeContext); + } + + @Test(expected = CreateValidationFailedException.class) + public void testWriteFailedNoHostName() throws CreateValidationFailedException { + validator.validateWrite(ID, afPacket(null), writeContext); + } + + @Test(expected = IllegalArgumentException.class) + public void testWriteFailedLongHostName() throws CreateValidationFailedException { + validator.validateWrite(ID, + afPacket(IntStream.range(1, 64).boxed().map(i -> i.toString()).collect(Collectors.joining(","))), + writeContext); + } + + @Test + public void testUpdateSuccessful() throws UpdateValidationFailedException { + validator.validateUpdate(ID, afPacket(IFACE_NAME), afPacket(IFACE_NAME), writeContext); + } + + @Test + public void testDeleteSuccessful() throws DeleteValidationFailedException { + validator.validateDelete(ID, afPacket(IFACE_NAME), writeContext); + } + + private AfPacket afPacket(String name) { + return new AfPacketBuilder().setHostInterfaceName(name).build(); + } +} diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/EthernetCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/EthernetCustomizerTest.java index 18ec6614d..f7befc4e9 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/EthernetCustomizerTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/EthernetCustomizerTest.java @@ -29,7 +29,6 @@ import io.fd.jvpp.core.dto.HwInterfaceSetMtuReply; import org.junit.Test; import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.VppInterfaceAugmentation; import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.Ethernet; -import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.EthernetBuilder; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev180703.EthernetCsmacd; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.Interfaces; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.Interface; @@ -57,7 +56,7 @@ public class EthernetCustomizerTest extends WriterCustomizerTest { public void testWrite() throws WriteFailedException { when(api.hwInterfaceSetMtu(any())).thenReturn(future(new HwInterfaceSetMtuReply())); final int mtu = 1234; - customizer.writeCurrentAttributes(IF_IID, ethernet(mtu), writeContext); + customizer.writeCurrentAttributes(IF_IID, EthernetValidatorTest.ethernet(mtu), writeContext); verify(api).hwInterfaceSetMtu(mtuSetRequest(mtu)); } @@ -65,7 +64,7 @@ public class EthernetCustomizerTest extends WriterCustomizerTest { public void testUpdate() throws WriteFailedException { when(api.hwInterfaceSetMtu(any())).thenReturn(future(new HwInterfaceSetMtuReply())); final int mtu = 5678; - customizer.updateCurrentAttributes(IF_IID, mock(Ethernet.class), ethernet(mtu), writeContext); + customizer.updateCurrentAttributes(IF_IID, mock(Ethernet.class), EthernetValidatorTest.ethernet(mtu), writeContext); verify(api).hwInterfaceSetMtu(mtuSetRequest(mtu)); } @@ -80,11 +79,4 @@ public class EthernetCustomizerTest extends WriterCustomizerTest { public void testDelete() throws WriteFailedException { customizer.deleteCurrentAttributes(IF_IID, mock(Ethernet.class), writeContext); } - - private static Ethernet ethernet(final int mtu) { - final EthernetBuilder ethernet = new EthernetBuilder(); - ethernet.setMtu(mtu); - return ethernet.build(); - } - } diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/EthernetValidatorTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/EthernetValidatorTest.java new file mode 100644 index 000000000..ce639d22f --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/EthernetValidatorTest.java @@ -0,0 +1,76 @@ +/* + * 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.v3po.interfaces; + +import static org.mockito.MockitoAnnotations.initMocks; + +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.DataValidationFailedException.CreateValidationFailedException; +import io.fd.honeycomb.translate.write.DataValidationFailedException.UpdateValidationFailedException; +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.v3po.rev190502.VppInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.Ethernet; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.EthernetBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.Interfaces; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.InterfaceKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class EthernetValidatorTest { + + private EthernetValidator validator; + + @Mock + private WriteContext writeContext; + + private static final String IF_NAME = "eth0"; + private static final int IF_MTU = 1234; + private static final InstanceIdentifier<Ethernet> ID = + InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IF_NAME)).augmentation( + VppInterfaceAugmentation.class).child(Ethernet.class); + + @Before + public void setUp() { + initMocks(this); + NamingContext ifcContext = new NamingContext("testInterfaceContext", "testInterfaceContext"); + validator = new EthernetValidator(ifcContext); + } + + @Test + public void testWriteSuccessful() throws CreateValidationFailedException { + validator.validateWrite(ID, ethernet(IF_MTU), writeContext); + } + + @Test(expected = NullPointerException.class) + public void testWriteFailedNoMTU() throws CreateValidationFailedException { + validator.validateWrite(ID, ethernet(null), writeContext); + } + + @Test + public void testUpdateSuccessful() throws UpdateValidationFailedException { + validator.validateUpdate(ID, ethernet(IF_MTU), ethernet(IF_MTU + 1), writeContext); + } + + static Ethernet ethernet(final Integer mtu) { + final EthernetBuilder ethernet = new EthernetBuilder(); + ethernet.setMtu(mtu); + return ethernet.build(); + } +} diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/GreValidatorTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/GreValidatorTest.java new file mode 100644 index 000000000..e7f786bde --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/GreValidatorTest.java @@ -0,0 +1,111 @@ +/* + * 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.v3po.interfaces; + +import static org.mockito.MockitoAnnotations.initMocks; + +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.DataValidationFailedException.CreateValidationFailedException; +import io.fd.honeycomb.translate.write.DataValidationFailedException.DeleteValidationFailedException; +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.v3po.rev190502.VppInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.Gre; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.GreBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressNoZone; +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.Ipv6AddressNoZone; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.Interfaces; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.InterfaceKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class GreValidatorTest { + + private GreValidator validator; + + @Mock + private WriteContext writeContext; + + private static final String IPV6 = "a::100"; + private static final String IPV4_1 = "192.168.20.10"; + private static final String IPV4_2 = "192.168.20.11"; + private static final Long OUT_FIB_ID = Long.valueOf(123); + private static final String IFACE_NAME = "eth0"; + private static final InstanceIdentifier<Gre> ID = + InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IFACE_NAME)) + .augmentation(VppInterfaceAugmentation.class).child(Gre.class); + + @Before + public void setUp() { + initMocks(this); + NamingContext ifcContext = new NamingContext("testInterfaceContext", "testInterfaceContext"); + validator = new GreValidator(ifcContext); + } + + @Test + public void testWriteSuccessful() throws CreateValidationFailedException { + validator.validateWrite(ID, generateCorrectGre(), writeContext); + } + + @Test(expected = CreateValidationFailedException.class) + public void testWriteFailedMixedIpv4Ipv6() throws CreateValidationFailedException { + validator.validateWrite(ID, generateGre(ip4(IPV4_1), ip6(IPV6), OUT_FIB_ID), writeContext); + } + + @Test(expected = CreateValidationFailedException.class) + public void testWriteFailedNoSrcAddr() throws CreateValidationFailedException { + validator.validateWrite(ID, generateGre(null, ip6(IPV6), OUT_FIB_ID), writeContext); + } + + @Test(expected = CreateValidationFailedException.class) + public void testWriteFailedNoDstAddr() throws CreateValidationFailedException { + validator.validateWrite(ID, generateGre(ip4(IPV4_1), null, OUT_FIB_ID), writeContext); + } + + @Test(expected = CreateValidationFailedException.class) + public void testWriteFailedNoOutFibId() throws CreateValidationFailedException { + validator.validateWrite(ID, generateGre(ip4(IPV4_1), ip4(IPV4_2), null), writeContext); + } + + @Test + public void testDeleteSuccessful() throws DeleteValidationFailedException { + validator.validateDelete(ID, generateCorrectGre(), writeContext); + } + + private Gre generateCorrectGre() { + return generateGre(ip4(IPV4_1), ip4(IPV4_2), OUT_FIB_ID); + } + + private Gre generateGre(final IpAddressNoZone srcAddr, final IpAddressNoZone dstAddr, final Long outerFibId) { + final GreBuilder builder = new GreBuilder(); + builder.setSrc(srcAddr); + builder.setDst(dstAddr); + builder.setOuterFibId(outerFibId); + return builder.build(); + } + + private IpAddressNoZone ip4(String addr) { + return new IpAddressNoZone(new Ipv4AddressNoZone(addr)); + } + + private IpAddressNoZone ip6(String addr) { + return new IpAddressNoZone(new Ipv6AddressNoZone(addr)); + } +} diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/InterfaceRoutingCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/InterfaceRoutingCustomizerTest.java index a3028acf7..533c627f6 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/InterfaceRoutingCustomizerTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/InterfaceRoutingCustomizerTest.java @@ -20,14 +20,12 @@ import static org.mockito.Matchers.any; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import java.util.Optional; import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; import io.fd.hc2vpp.common.translate.util.NamingContext; -import io.fd.honeycomb.translate.util.RWUtils; import io.fd.honeycomb.translate.write.WriteFailedException; import io.fd.jvpp.core.dto.SwInterfaceSetTable; import io.fd.jvpp.core.dto.SwInterfaceSetTableReply; -import java.util.Collections; +import java.util.Optional; import org.junit.Test; import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.VppInterfaceAugmentation; import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.Routing; @@ -37,11 +35,6 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces. import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.Interface; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.InterfaceBuilder; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.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.Interface1Builder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4Builder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv6Builder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.AddressBuilder; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; public class InterfaceRoutingCustomizerTest extends WriterCustomizerTest { @@ -76,52 +69,16 @@ public class InterfaceRoutingCustomizerTest extends WriterCustomizerTest { customizer.writeCurrentAttributes(IID, routing(213), writeContext); } - @Test(expected = IllegalStateException.class) - public void testWriteFailedIpv4Present() throws WriteFailedException { - when(writeContext.readBefore(RWUtils.cutId(IID, Interface.class))) - .thenReturn(Optional.of(ifaceWithV4Address())); - customizer.writeCurrentAttributes(IID, routing(213), writeContext); - } - - @Test(expected = IllegalStateException.class) - public void testWriteFailedIpv6Present() throws WriteFailedException { - when(writeContext.readBefore(RWUtils.cutId(IID, Interface.class))) - .thenReturn(Optional.of(ifaceWithV6Address())); - customizer.writeCurrentAttributes(IID, routing(213), writeContext); - } - @Test public void testWriteEmptyIfaceData() throws WriteFailedException { - when(writeContext.readBefore(any(InstanceIdentifier.class))).thenReturn(Optional.of(new InterfaceBuilder().build())); + when(writeContext.readBefore(any(InstanceIdentifier.class))) + .thenReturn(Optional.of(new InterfaceBuilder().build())); final int vrfId = 123; when(api.swInterfaceSetTable(any())).thenReturn(future(new SwInterfaceSetTableReply())); customizer.writeCurrentAttributes(IID, routing(vrfId), writeContext); verify(api).swInterfaceSetTable(expectedRequest(vrfId)); } - private static Interface ifaceWithV4Address() { - return new InterfaceBuilder() - .addAugmentation(Interface1.class, new Interface1Builder() - .setIpv4(new Ipv4Builder() - .setAddress(Collections.singletonList(new AddressBuilder().build())) - .build()) - .build()) - .build(); - } - - - private static Interface ifaceWithV6Address() { - return new InterfaceBuilder() - .addAugmentation(Interface1.class, new Interface1Builder() - .setIpv6(new Ipv6Builder() - .setAddress(Collections.singletonList( - new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv6.AddressBuilder() - .build())) - .build()) - .build()) - .build(); - } - @Test(expected = WriteFailedException.class) public void testUpdateFailed() throws WriteFailedException { when(writeContext.readBefore(any(InstanceIdentifier.class))).thenReturn(Optional.empty()); diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/InterfaceRoutingValidatorTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/InterfaceRoutingValidatorTest.java new file mode 100644 index 000000000..e10aba4a2 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/InterfaceRoutingValidatorTest.java @@ -0,0 +1,146 @@ +/* + * 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.v3po.interfaces; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.util.RWUtils; +import io.fd.honeycomb.translate.write.DataValidationFailedException.CreateValidationFailedException; +import io.fd.honeycomb.translate.write.DataValidationFailedException.DeleteValidationFailedException; +import io.fd.honeycomb.translate.write.DataValidationFailedException.UpdateValidationFailedException; +import io.fd.honeycomb.translate.write.WriteContext; +import java.util.Collections; +import java.util.Optional; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.VppInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.Routing; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.RoutingBuilder; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.fib.table.management.rev180521.VniReference; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.Interfaces; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.InterfaceBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.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.Interface1Builder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4Builder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv6Builder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.AddressBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class InterfaceRoutingValidatorTest { + + private InterfaceRoutingValidator validator; + + @Mock + private WriteContext writeContext; + + private static final String IF_NAME = "eth1"; + private static final Long VRF_ID = Long.valueOf(123); + + private static final InstanceIdentifier<Routing> ID = + InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IF_NAME)) + .augmentation(VppInterfaceAugmentation.class).child(Routing.class); + + @Before + public void setUp() { + initMocks(this); + NamingContext ifcContext = new NamingContext("testInterfaceContext", "testInterfaceContext"); + validator = new InterfaceRoutingValidator(ifcContext); + } + + @Test + public void testWriteSuccessful() throws CreateValidationFailedException { + when(writeContext.readBefore(any(InstanceIdentifier.class))).thenReturn(Optional.empty()); + validator.validateWrite(ID, routing(VRF_ID, true, false), writeContext); + } + + @Test(expected = CreateValidationFailedException.class) + public void testWriteFailedNoFrfIds() throws CreateValidationFailedException { + when(writeContext.readBefore(any(InstanceIdentifier.class))).thenReturn(Optional.empty()); + validator.validateWrite(ID, routing(null, true, true), writeContext); + } + + @Test(expected = CreateValidationFailedException.class) + public void testWriteFailedWithV4Address() throws CreateValidationFailedException { + when(writeContext.readBefore(RWUtils.cutId(ID, Interface.class))) + .thenReturn(Optional.of(ifaceWithV4Address())); + validator.validateWrite(ID, routing(VRF_ID, true, false), writeContext); + } + + @Test(expected = CreateValidationFailedException.class) + public void testWriteFailedWithV6Address() throws CreateValidationFailedException { + when(writeContext.readBefore(RWUtils.cutId(ID, Interface.class))) + .thenReturn(Optional.of(ifaceWithV6Address())); + validator.validateWrite(ID, routing(VRF_ID, true, false), writeContext); + } + + @Test + public void testUpdateSuccessful() throws UpdateValidationFailedException { + when(writeContext.readBefore(any(InstanceIdentifier.class))).thenReturn(Optional.empty()); + validator.validateUpdate(ID, routing(VRF_ID, true, false), + routing(VRF_ID, true, true), writeContext); + } + + @Test + public void testDeleteSuccessful() throws DeleteValidationFailedException { + when(writeContext.readBefore(any(InstanceIdentifier.class))).thenReturn(Optional.empty()); + validator.validateDelete(ID, routing(VRF_ID, true, false), writeContext); + } + + private Routing routing(final Long vrfId, final boolean hasIpv4, final boolean hasIpv6) { + VniReference vni = null; + if (vrfId != null) { + vni = new VniReference(vrfId); + } + + RoutingBuilder builder = new RoutingBuilder(); + if (hasIpv4) { + builder.setIpv4VrfId(vni); + } + if (hasIpv6) { + builder.setIpv6VrfId(vni); + } + return builder.build(); + } + + private Interface ifaceWithV4Address() { + return new InterfaceBuilder() + .addAugmentation(Interface1.class, new Interface1Builder() + .setIpv4(new Ipv4Builder() + .setAddress(Collections.singletonList(new AddressBuilder().build())) + .build()) + .build()) + .build(); + } + + private Interface ifaceWithV6Address() { + return new InterfaceBuilder() + .addAugmentation(Interface1.class, new Interface1Builder() + .setIpv6(new Ipv6Builder() + .setAddress(Collections.singletonList( + new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv6.AddressBuilder() + .build())) + .build()) + .build()) + .build(); + } +} diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/InterfaceUnnumberedValidatorTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/InterfaceUnnumberedValidatorTest.java new file mode 100644 index 000000000..79b3f9185 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/InterfaceUnnumberedValidatorTest.java @@ -0,0 +1,82 @@ +/* + * 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.v3po.interfaces; + +import static org.mockito.MockitoAnnotations.initMocks; + +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.DataValidationFailedException.CreateValidationFailedException; +import io.fd.honeycomb.translate.write.DataValidationFailedException.DeleteValidationFailedException; +import io.fd.honeycomb.translate.write.DataValidationFailedException.UpdateValidationFailedException; +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.unnumbered.interfaces.rev180103.InterfaceUnnumberedAugmentation; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.unnumbered.interfaces.rev180103.unnumbered.config.attributes.Unnumbered; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.unnumbered.interfaces.rev180103.unnumbered.config.attributes.UnnumberedBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.Interfaces; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.InterfaceKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class InterfaceUnnumberedValidatorTest { + + private InterfaceUnnumberedValidator validator; + + @Mock + private WriteContext writeContext; + + private static final String IF_NAME = "eth2"; + private static final String TARGET_IFC0_NAME = "eth0"; + private static final InstanceIdentifier<Unnumbered> ID = InstanceIdentifier.create(Interfaces.class) + .child(Interface.class, new InterfaceKey(IF_NAME)) + .augmentation(InterfaceUnnumberedAugmentation.class) + .child(Unnumbered.class); + + @Before + public void setUp() { + initMocks(this); + NamingContext ifcContext = new NamingContext("testInterfaceContext", "testInterfaceContext"); + validator = new InterfaceUnnumberedValidator(ifcContext); + } + + @Test + public void testWriteSuccessful() throws CreateValidationFailedException { + validator.validateWrite(ID, getUnnumberedIfc(TARGET_IFC0_NAME), writeContext); + } + + @Test(expected = NullPointerException.class) + public void testWriteFailedNoUse() throws CreateValidationFailedException { + validator.validateWrite(ID, getUnnumberedIfc(null), writeContext); + } + + @Test + public void testUpdateSuccessful() throws UpdateValidationFailedException { + validator.validateUpdate(ID, getUnnumberedIfc(TARGET_IFC0_NAME), getUnnumberedIfc(TARGET_IFC0_NAME), + writeContext); + } + + @Test + public void testDeleteeSuccessful() throws DeleteValidationFailedException { + validator.validateDelete(ID, getUnnumberedIfc(TARGET_IFC0_NAME), writeContext); + } + + private Unnumbered getUnnumberedIfc(String use) { + return new UnnumberedBuilder().setUse(use).build(); + } +} diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/InterfaceValidatorTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/InterfaceValidatorTest.java new file mode 100644 index 000000000..21de26fed --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/InterfaceValidatorTest.java @@ -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.v3po.interfaces; + +import static org.mockito.MockitoAnnotations.initMocks; + +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.DataValidationFailedException.CreateValidationFailedException; +import io.fd.honeycomb.translate.write.DataValidationFailedException.DeleteValidationFailedException; +import io.fd.honeycomb.translate.write.DataValidationFailedException.UpdateValidationFailedException; +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.interfaces.rev180220.Interfaces; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.InterfaceBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.InterfaceKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class InterfaceValidatorTest { + + private InterfaceValidator validator; + + @Mock + private WriteContext writeContext; + + private static final String IF_NAME = "eth0"; + private static final InstanceIdentifier<Interface> ID = + InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IF_NAME)); + + @Before + public void setUp() { + initMocks(this); + NamingContext ifcContext = new NamingContext("testInterfaceContext", "testInterfaceContext"); + validator = new InterfaceValidator(ifcContext); + } + + @Test + public void testWriteSuccessful() throws CreateValidationFailedException { + validator.validateWrite(ID, getInterface(true), writeContext); + } + + @Test(expected = CreateValidationFailedException.class) + public void testWriteFailedNoName() throws CreateValidationFailedException { + validator.validateWrite(ID, getInterface(null, true), writeContext); + } + + @Test(expected = CreateValidationFailedException.class) + public void testWriteFailedNoEnableFlag() throws CreateValidationFailedException { + validator.validateWrite(ID, getInterface(null), writeContext); + } + + @Test + public void testUpdateSuccessful() throws UpdateValidationFailedException { + validator.validateUpdate(ID, getInterface(true), getInterface(true), writeContext); + } + + @Test + public void testDeleteSuccessful() throws DeleteValidationFailedException { + validator.validateDelete(ID, getInterface(true), writeContext); + } + + private Interface getInterface(final String name, final Boolean enabled) { + return new InterfaceBuilder().setName(name).setEnabled(enabled).build(); + } + + private Interface getInterface(final Boolean enabled) { + return new InterfaceBuilder().setName(IF_NAME).setEnabled(enabled).build(); + } +} diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceCustomizerTest.java index 6c6a2be09..37a185d6a 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceCustomizerTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceCustomizerTest.java @@ -95,13 +95,13 @@ public class SubInterfaceCustomizerTest extends WriterCustomizerTest { return tag.build(); } - private static Match generateMatch() { + static Match generateMatch() { final MatchBuilder match = new MatchBuilder(); final VlanTaggedBuilder tagged = new VlanTaggedBuilder(); tagged.setMatchExactTags(true); match.setMatchType( - new org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.match.attributes.match.type.VlanTaggedBuilder() - .setVlanTagged(tagged.build()).build()); + new org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.match.attributes.match.type.VlanTaggedBuilder() + .setVlanTagged(tagged.build()).build()); return match.build(); } @@ -136,8 +136,8 @@ public class SubInterfaceCustomizerTest extends WriterCustomizerTest { request.twoTags = 1; request.innerVlanId = innerVlanId; request.innerVlanIdAny = (byte) (isInnerAny - ? 1 - : 0); + ? 1 + : 0); request.dot1Ad = 1; request.outerVlanId = STAG_ID; request.exactMatch = 1; @@ -153,8 +153,8 @@ public class SubInterfaceCustomizerTest extends WriterCustomizerTest { private InstanceIdentifier<SubInterface> getSubInterfaceId(final String name, final long index) { return InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(name)).augmentation( - SubinterfaceAugmentation.class).child(SubInterfaces.class) - .child(SubInterface.class, new SubInterfaceKey(index)); + SubinterfaceAugmentation.class).child(SubInterfaces.class) + .child(SubInterface.class, new SubInterfaceKey(index)); } private void whenCreateSubifThenSuccess() { @@ -173,7 +173,7 @@ public class SubInterfaceCustomizerTest extends WriterCustomizerTest { } private SwInterfaceSetFlags verifySwInterfaceSetFlagsWasInvoked(final SwInterfaceSetFlags expected) - throws VppBaseCallException { + throws VppBaseCallException { ArgumentCaptor<SwInterfaceSetFlags> argumentCaptor = ArgumentCaptor.forClass(SwInterfaceSetFlags.class); verify(api).swInterfaceSetFlags(argumentCaptor.capture()); final SwInterfaceSetFlags actual = argumentCaptor.getValue(); @@ -195,8 +195,8 @@ public class SubInterfaceCustomizerTest extends WriterCustomizerTest { verify(api).createSubif(generateSubInterfaceRequest(SUPER_IF_ID, CTAG_ID, false)); verify(mappingContext) - .put(eq(mappingIid(SUB_IFACE_NAME, IFC_TEST_INSTANCE)), eq( - mapping(SUB_IFACE_NAME, 0).get())); + .put(eq(mappingIid(SUB_IFACE_NAME, IFC_TEST_INSTANCE)), eq( + mapping(SUB_IFACE_NAME, 0).get())); } @Test @@ -211,8 +211,8 @@ public class SubInterfaceCustomizerTest extends WriterCustomizerTest { verify(api).createSubif(generateSubInterfaceRequest(SUPER_IF_ID, CTAG_ANY_ID, true)); verify(mappingContext) - .put(eq(mappingIid(SUB_IFACE_NAME, IFC_TEST_INSTANCE)), eq( - mapping(SUB_IFACE_NAME, 0).get())); + .put(eq(mappingIid(SUB_IFACE_NAME, IFC_TEST_INSTANCE)), eq( + mapping(SUB_IFACE_NAME, 0).get())); } @Test @@ -228,8 +228,8 @@ public class SubInterfaceCustomizerTest extends WriterCustomizerTest { assertTrue(e.getCause() instanceof VppBaseCallException); verify(api).createSubif(generateSubInterfaceRequest(SUPER_IF_ID, CTAG_ID, false)); verify(mappingContext, times(0)).put( - eq(mappingIid(SUPER_IF_NAME, IFC_TEST_INSTANCE)), - eq(mapping(SUPER_IF_NAME, 0).get())); + eq(mappingIid(SUPER_IF_NAME, IFC_TEST_INSTANCE)), + eq(mapping(SUPER_IF_NAME, 0).get())); return; } fail("WriteFailedException.CreateFailedException was expected"); diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceRoutingCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceRoutingCustomizerTest.java index 5732d587b..90c9d66c8 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceRoutingCustomizerTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceRoutingCustomizerTest.java @@ -21,7 +21,6 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import java.util.Optional; import com.google.common.collect.ImmutableSet; import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; @@ -30,6 +29,7 @@ import io.fd.honeycomb.translate.write.WriteFailedException; import io.fd.jvpp.core.dto.SwInterfaceSetTable; import io.fd.jvpp.core.dto.SwInterfaceSetTableReply; import java.util.Collections; +import java.util.Optional; import java.util.Set; import org.junit.Test; import org.mockito.ArgumentCaptor; @@ -38,11 +38,7 @@ import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.fib.table.managem 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.SubInterfaceBuilder; 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.Ipv4Builder; -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.ip6.attributes.Ipv6Builder; import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.routing.attributes.Routing; import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.routing.attributes.RoutingBuilder; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.Interfaces; @@ -80,20 +76,6 @@ public class SubInterfaceRoutingCustomizerTest extends WriterCustomizerTest impl when(api.swInterfaceSetTable(any())).thenReturn(future(new SwInterfaceSetTableReply())); } - @Test(expected = IllegalStateException.class) - public void testWriteFailedV4AddressPresent() throws WriteFailedException { - when(writeContext.readBefore(any(InstanceIdentifier.class))).thenReturn(Optional.of(v4AddressPresent())); - final Routing v4Routing = new RoutingBuilder().setIpv4VrfId(new VniReference(4L)).build(); - customizer.writeCurrentAttributes(VALID_ID, v4Routing, writeContext); - } - - @Test(expected = IllegalStateException.class) - public void testWriteFailedV6AddressPresent() throws WriteFailedException { - when(writeContext.readBefore(any(InstanceIdentifier.class))).thenReturn(Optional.of(v6AddressPresent())); - final Routing v4Routing = new RoutingBuilder().setIpv4VrfId(new VniReference(4L)).build(); - customizer.writeCurrentAttributes(VALID_ID, v4Routing, writeContext); - } - @Test public void testWriteIpv4Vrf() throws WriteFailedException { when(writeContext.readBefore(any(InstanceIdentifier.class))).thenReturn(Optional.empty()); @@ -102,7 +84,6 @@ public class SubInterfaceRoutingCustomizerTest extends WriterCustomizerTest impl verifySetTableRequest(1, Collections.singleton(request(false, SUBIF_INDEX, 4))); } - @Test public void testWriteIpv6Vrf() throws WriteFailedException { when(writeContext.readBefore(any(InstanceIdentifier.class))).thenReturn(Optional.empty()); @@ -115,9 +96,9 @@ public class SubInterfaceRoutingCustomizerTest extends WriterCustomizerTest impl public void testUpdateIpv4Vrf() throws WriteFailedException { when(writeContext.readBefore(any(InstanceIdentifier.class))).thenReturn(Optional.empty()); final Routing routingBefore = new RoutingBuilder().setIpv6VrfId(new VniReference(3L)) - .setIpv4VrfId(new VniReference(4L)).build(); + .setIpv4VrfId(new VniReference(4L)).build(); final Routing routingAfter = new RoutingBuilder().setIpv6VrfId(new VniReference(3L)) - .setIpv4VrfId(new VniReference(5L)).build(); + .setIpv4VrfId(new VniReference(5L)).build(); customizer.updateCurrentAttributes(VALID_ID, routingBefore, routingAfter, writeContext); verifySetTableRequest(2, ImmutableSet.of(request(false, SUBIF_INDEX, 5), request(true, SUBIF_INDEX, 3))); @@ -127,9 +108,9 @@ public class SubInterfaceRoutingCustomizerTest extends WriterCustomizerTest impl public void testUpdateIpv6Vrf() throws WriteFailedException { when(writeContext.readBefore(any(InstanceIdentifier.class))).thenReturn(Optional.empty()); final Routing routingBefore = new RoutingBuilder().setIpv6VrfId(new VniReference(3L)) - .setIpv4VrfId(new VniReference(4L)).build(); + .setIpv4VrfId(new VniReference(4L)).build(); final Routing routingAfter = new RoutingBuilder().setIpv6VrfId(new VniReference(8L)) - .setIpv4VrfId(new VniReference(4L)).build(); + .setIpv4VrfId(new VniReference(4L)).build(); customizer.updateCurrentAttributes(VALID_ID, routingBefore, routingAfter, writeContext); verifySetTableRequest(2, ImmutableSet.of(request(false, SUBIF_INDEX, 4), request(true, SUBIF_INDEX, 8))); @@ -164,20 +145,4 @@ public class SubInterfaceRoutingCustomizerTest extends WriterCustomizerTest impl verify(api, times(times)).swInterfaceSetTable(requestCaptor.capture()); requestCaptor.getAllValues().containsAll(requests); } - - private static SubInterface v4AddressPresent() { - return new SubInterfaceBuilder() - .setIpv4(new Ipv4Builder() - .setAddress(Collections.singletonList(new AddressBuilder().build())) - .build()) - .build(); - } - - private static SubInterface v6AddressPresent(){ - return new SubInterfaceBuilder() - .setIpv6(new Ipv6Builder() - .setAddress(Collections.singletonList(new org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.ip6.attributes.ipv6.AddressBuilder().build())) - .build()) - .build(); - } } diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceRoutingValidatorTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceRoutingValidatorTest.java new file mode 100644 index 000000000..510887e70 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceRoutingValidatorTest.java @@ -0,0 +1,123 @@ +/* + * 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.v3po.interfaces; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.DataValidationFailedException.CreateValidationFailedException; +import io.fd.honeycomb.translate.write.DataValidationFailedException.DeleteValidationFailedException; +import io.fd.honeycomb.translate.write.DataValidationFailedException.UpdateValidationFailedException; +import io.fd.honeycomb.translate.write.WriteContext; +import java.util.Collections; +import java.util.Optional; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.fib.table.management.rev180521.VniReference; +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.SubInterfaceBuilder; +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.Ipv4Builder; +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.ip6.attributes.Ipv6Builder; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.routing.attributes.Routing; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.routing.attributes.RoutingBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.Interfaces; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.InterfaceKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class SubInterfaceRoutingValidatorTest { + + private SubInterfaceRoutingValidator validator; + + @Mock + private WriteContext writeContext; + + private static final String IF_NAME = "eth1"; + private static final int SUBIF_INDEX = 0; + private static final InstanceIdentifier<Routing> ID = + InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IF_NAME)) + .augmentation(SubinterfaceAugmentation.class) + .child(SubInterfaces.class) + .child(SubInterface.class, new SubInterfaceKey((long) SUBIF_INDEX)) + .child(Routing.class); + + @Before + public void setUp() { + initMocks(this); + NamingContext ifcContext = new NamingContext("testInterfaceContext", "testInterfaceContext"); + validator = new SubInterfaceRoutingValidator(ifcContext); + } + + @Test + public void testWriteSuccessful() throws CreateValidationFailedException { + when(writeContext.readBefore(any(InstanceIdentifier.class))).thenReturn(Optional.empty()); + validator.validateWrite(ID, getRouting(), writeContext); + } + + @Test(expected = CreateValidationFailedException.class) + public void testWriteFailedV4AddressPresent() throws CreateValidationFailedException { + when(writeContext.readBefore(any(InstanceIdentifier.class))).thenReturn(Optional.of(v4AddressPresent())); + validator.validateWrite(ID, getRouting(), writeContext); + } + + @Test(expected = CreateValidationFailedException.class) + public void testWriteFailedV6AddressPresent() throws CreateValidationFailedException { + when(writeContext.readBefore(any(InstanceIdentifier.class))).thenReturn(Optional.of(v6AddressPresent())); + validator.validateWrite(ID, getRouting(), writeContext); + } + + @Test + public void testUpdateSuccessful() throws UpdateValidationFailedException { + when(writeContext.readBefore(any(InstanceIdentifier.class))).thenReturn(Optional.empty()); + validator.validateUpdate(ID, getRouting(), getRouting(), writeContext); + } + + @Test + public void testDeleteSuccessful() throws DeleteValidationFailedException { + when(writeContext.readBefore(any(InstanceIdentifier.class))).thenReturn(Optional.empty()); + validator.validateDelete(ID, getRouting(), writeContext); + } + + private Routing getRouting() { + return new RoutingBuilder().setIpv4VrfId(new VniReference(4L)).build(); + } + + private SubInterface v4AddressPresent() { + return new SubInterfaceBuilder() + .setIpv4(new Ipv4Builder() + .setAddress(Collections.singletonList(new AddressBuilder().build())) + .build()) + .build(); + } + + private SubInterface v6AddressPresent() { + return new SubInterfaceBuilder() + .setIpv6(new Ipv6Builder() + .setAddress(Collections.singletonList( + new org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.ip6.attributes.ipv6.AddressBuilder() + .build())) + .build()) + .build(); + } +} diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceUnnumberedCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceUnnumberedCustomizerTest.java index 5c640d204..fdaf6f925 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceUnnumberedCustomizerTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceUnnumberedCustomizerTest.java @@ -34,10 +34,10 @@ public class SubInterfaceUnnumberedCustomizerTest extends AbstractUnnumberedCust private static final int UNNUMBERED_IFC_ID = 2; private static final long UNNUMBERED_IFC_NUMBER = 123; private static final InstanceIdentifier<Unnumbered> UNNUMBERED_IFC_IID = InstanceIdentifier.create(Interfaces.class) - .child(Interface.class, new InterfaceKey(PARENT_IFC_NAME)) - .augmentation(SubinterfaceAugmentation.class).child(SubInterfaces.class) - .child(SubInterface.class, new SubInterfaceKey(UNNUMBERED_IFC_NUMBER)).augmentation( - SubinterfaceUnnumberedAugmentation.class).child(Unnumbered.class); + .child(Interface.class, new InterfaceKey(PARENT_IFC_NAME)) + .augmentation(SubinterfaceAugmentation.class).child(SubInterfaces.class) + .child(SubInterface.class, new SubInterfaceKey(UNNUMBERED_IFC_NUMBER)) + .augmentation(SubinterfaceUnnumberedAugmentation.class).child(Unnumbered.class); @Override protected int getUnnumberedIfcId() { @@ -58,5 +58,4 @@ public class SubInterfaceUnnumberedCustomizerTest extends AbstractUnnumberedCust protected AbstractUnnumberedCustomizer getCustomizer() { return new SubInterfaceUnnumberedCustomizer(api, new NamingContext("ifc-prefix", IFC_CTX_NAME)); } - } diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceUnnumberedValidatorTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceUnnumberedValidatorTest.java new file mode 100644 index 000000000..73043be8b --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceUnnumberedValidatorTest.java @@ -0,0 +1,80 @@ +/* + * 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.v3po.interfaces; + +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.http.fd.io.hc2vpp.yang.unnumbered.interfaces.rev180103.InterfaceUnnumberedAugmentation; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.unnumbered.interfaces.rev180103.unnumbered.config.attributes.Unnumbered; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.unnumbered.interfaces.rev180103.unnumbered.config.attributes.UnnumberedBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.Interfaces; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.InterfaceKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class SubInterfaceUnnumberedValidatorTest { + + private SubInterfaceUnnumberedValidator validator; + + @Mock + private WriteContext writeContext; + + private static final String IF_NAME = "eth2"; + private static final String TARGET_IFC0_NAME = "eth0"; + private static final InstanceIdentifier<Unnumbered> ID = InstanceIdentifier.create(Interfaces.class) + .child(Interface.class, new InterfaceKey(IF_NAME)) + .augmentation(InterfaceUnnumberedAugmentation.class) + .child(Unnumbered.class); + + @Before + public void setUp() { + initMocks(this); + NamingContext ifcContext = new NamingContext("testInterfaceContext", "testInterfaceContext"); + validator = new SubInterfaceUnnumberedValidator(ifcContext); + } + + @Test + public void testWriteSuccessful() throws DataValidationFailedException.CreateValidationFailedException { + validator.validateWrite(ID, getUnnumberedIfc(TARGET_IFC0_NAME), writeContext); + } + + @Test(expected = NullPointerException.class) + public void testWriteFailedNoUse() throws DataValidationFailedException.CreateValidationFailedException { + validator.validateWrite(ID, getUnnumberedIfc(null), writeContext); + } + + @Test + public void testUpdateSuccessful() throws DataValidationFailedException.UpdateValidationFailedException { + validator.validateUpdate(ID, getUnnumberedIfc(TARGET_IFC0_NAME), getUnnumberedIfc(TARGET_IFC0_NAME), + writeContext); + } + + @Test + public void testDeleteeSuccessful() throws DataValidationFailedException.DeleteValidationFailedException { + validator.validateDelete(ID, getUnnumberedIfc(TARGET_IFC0_NAME), writeContext); + } + + private Unnumbered getUnnumberedIfc(String use) { + return new UnnumberedBuilder().setUse(use).build(); + } +} diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceValidatorTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceValidatorTest.java new file mode 100644 index 000000000..e7b9e668b --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/SubInterfaceValidatorTest.java @@ -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.v3po.interfaces; + +import static org.mockito.MockitoAnnotations.initMocks; + +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.DataValidationFailedException.CreateValidationFailedException; +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.SubInterfaceBuilder; +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.base.attributes.Match; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.Interfaces; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.InterfaceKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class SubInterfaceValidatorTest { + + private SubInterfaceValidator validator; + + @Mock + private WriteContext writeContext; + + private static final String SUPER_IF_NAME = "local0"; + private static final String SUB_IFACE_NAME = "local0.11"; + private static final long SUBIF_INDEX = 11; + private static final InstanceIdentifier<SubInterface> ID = + InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(SUPER_IF_NAME)) + .augmentation( + SubinterfaceAugmentation.class).child(SubInterfaces.class) + .child(SubInterface.class, new SubInterfaceKey(SUBIF_INDEX)); + + @Before + public void setUp() { + initMocks(this); + NamingContext ifcContext = new NamingContext("testInterfaceContext", "testInterfaceContext"); + validator = new SubInterfaceValidator(ifcContext); + } + + @Test + public void testWriteSuccessful() throws CreateValidationFailedException { + validator + .validateWrite(ID, generateSubInterface(11L, SubInterfaceCustomizerTest.generateMatch()), writeContext); + } + + @Test(expected = CreateValidationFailedException.class) + public void testWriteFailedNoIdentifier() throws CreateValidationFailedException { + validator.validateWrite(ID, generateSubInterface(null, SubInterfaceCustomizerTest.generateMatch()), + writeContext); + } + + @Test(expected = CreateValidationFailedException.class) + public void testWriteFailedNoMatch() throws CreateValidationFailedException { + validator.validateWrite(ID, generateSubInterface(11L, null), writeContext); + } + + private SubInterface generateSubInterface(final Long identifier, final Match match) { + return new SubInterfaceBuilder() + .setIdentifier(identifier) + .setMatch(match) + .setEnabled(true) + .build(); + } +} diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/VhostUserCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/VhostUserCustomizerTest.java index ea3b699a7..db190ee06 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/VhostUserCustomizerTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/VhostUserCustomizerTest.java @@ -61,7 +61,7 @@ public class VhostUserCustomizerTest extends WriterCustomizerTest implements Ipv .augmentation(VppInterfaceAugmentation.class).child(VhostUser.class); private VhostUserCustomizer customizer; - private static VhostUser generateVhostUser(final VhostUserRole role, final String socketName) { + static VhostUser generateVhostUser(final VhostUserRole role, final String socketName) { VhostUserBuilder builder = new VhostUserBuilder(); builder.setRole(role); builder.setSocket(socketName); @@ -121,7 +121,7 @@ public class VhostUserCustomizerTest extends WriterCustomizerTest implements Ipv customizer.writeCurrentAttributes(ID, vhostUser, writeContext); verifyCreateVhostUserIfWasInvoked(vhostUser); verify(mappingContext).put(eq(mappingIid(IFACE_NAME, "test-instance")), eq( - mapping(IFACE_NAME, 0).get())); + mapping(IFACE_NAME, 0).get())); } @Test diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/VhostUserValidatorTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/VhostUserValidatorTest.java new file mode 100644 index 000000000..eb8541270 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/VhostUserValidatorTest.java @@ -0,0 +1,79 @@ +/* + * 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.v3po.interfaces; + +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.http.fd.io.hc2vpp.yang.v3po.rev190502.VhostUserRole; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.VppInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.VhostUser; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.Interfaces; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.InterfaceKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class VhostUserValidatorTest { + + private VhostUserValidator validator; + + @Mock + private WriteContext writeContext; + + private static final String SOCKET = "testSocket"; + private static final String IFACE_NAME = "eth0"; + private static final InstanceIdentifier<VhostUser> ID = + InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IFACE_NAME)) + .augmentation(VppInterfaceAugmentation.class).child(VhostUser.class); + + @Before + public void setUp() { + initMocks(this); + NamingContext ifcContext = new NamingContext("testInterfaceContext", "testInterfaceContext"); + validator = new VhostUserValidator(ifcContext); + } + + @Test + public void testWriteSuccessful() throws DataValidationFailedException.CreateValidationFailedException { + validator.validateWrite(ID, getVhostUser(SOCKET), writeContext); + } + + @Test(expected = NullPointerException.class) + public void testWriteFailedNoSocket() throws DataValidationFailedException.CreateValidationFailedException { + validator.validateWrite(ID, getVhostUser(null), writeContext); + } + + @Test + public void testUpdateSuccessful() throws DataValidationFailedException.UpdateValidationFailedException { + validator.validateUpdate(ID, getVhostUser(SOCKET), + getVhostUser(SOCKET), writeContext); + } + + @Test + public void testDeleteeSuccessful() throws DataValidationFailedException.DeleteValidationFailedException { + validator.validateDelete(ID, getVhostUser(SOCKET), writeContext); + } + + private VhostUser getVhostUser(final String socketName) { + return VhostUserCustomizerTest.generateVhostUser(VhostUserRole.Client, socketName); + } +} diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/VxlanGpeValidatorTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/VxlanGpeValidatorTest.java new file mode 100644 index 000000000..c4955d881 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/VxlanGpeValidatorTest.java @@ -0,0 +1,151 @@ +/* + * 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.v3po.interfaces; + +import static org.mockito.MockitoAnnotations.initMocks; + +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.DisabledInterfacesManager; +import io.fd.honeycomb.translate.write.DataValidationFailedException.CreateValidationFailedException; +import io.fd.honeycomb.translate.write.DataValidationFailedException.DeleteValidationFailedException; +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.v3po.rev190502.VppInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.VxlanGpeNextProtocol; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.VxlanGpeVni; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.VxlanGpe; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.VxlanGpeBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressNoZone; +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.Ipv6AddressNoZone; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.Interfaces; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.InterfaceKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class VxlanGpeValidatorTest { + + private VxlanGpeValidator validator; + + @Mock + private WriteContext writeContext; + @Mock + private DisabledInterfacesManager interfaceDisableContext; + + private static final String IPV6 = "a::100"; + private static final String IPV4_1 = "192.168.20.10"; + private static final String IPV4_2 = "192.168.20.11"; + private static final Long VNI = Long.valueOf(11); + private static final Long ENCAP = Long.valueOf(123); + private static final Long DECAP = Long.valueOf(321); + private static final String IFACE_NAME = "eth0"; + private static final InstanceIdentifier<VxlanGpe> ID = + InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IFACE_NAME)) + .augmentation(VppInterfaceAugmentation.class).child(VxlanGpe.class); + + @Before + public void setUp() { + initMocks(this); + NamingContext ifcContext = new NamingContext("testInterfaceContext", "testInterfaceContext"); + validator = new VxlanGpeValidator(ifcContext, interfaceDisableContext); + } + + @Test + public void testWriteSuccessful() throws CreateValidationFailedException { + validator.validateWrite(ID, generateVxlanCorrect(), writeContext); + } + + @Test(expected = CreateValidationFailedException.class) + public void testWriteFailedMixedIpFamilies() throws CreateValidationFailedException { + validator.validateWrite(ID, generateVxlanMixedIpFamilies(), writeContext); + } + + @Test(expected = CreateValidationFailedException.class) + public void testWriteFailedNoLocal() throws CreateValidationFailedException { + validator.validateWrite(ID, generateVxlanSetFields(false, true, true, true, true, true), writeContext); + } + + @Test(expected = CreateValidationFailedException.class) + public void testWriteFailedNoRemote() throws CreateValidationFailedException { + validator.validateWrite(ID, generateVxlanSetFields(true, false, true, true, true, true), writeContext); + } + + @Test(expected = CreateValidationFailedException.class) + public void testWriteFailedNoEncapVrfId() throws CreateValidationFailedException { + validator.validateWrite(ID, generateVxlanSetFields(true, true, false, true, true, true), writeContext); + } + + @Test(expected = CreateValidationFailedException.class) + public void testWriteFailedNoDecapVrfId() throws CreateValidationFailedException { + validator.validateWrite(ID, generateVxlanSetFields(true, true, true, false, true, true), writeContext); + } + + @Test(expected = CreateValidationFailedException.class) + public void testWriteFailedNoVNI() throws CreateValidationFailedException { + validator.validateWrite(ID, generateVxlanSetFields(true, true, true, true, false, true), writeContext); + } + + @Test(expected = CreateValidationFailedException.class) + public void testWriteFailedNoNextProtocol() throws CreateValidationFailedException { + validator.validateWrite(ID, generateVxlanSetFields(true, true, true, true, true, false), writeContext); + } + + @Test + public void testDeleteSuccessful() throws DeleteValidationFailedException { + validator.validateDelete(ID, generateVxlanCorrect(), writeContext); + } + + private VxlanGpe generateVxlanSetFields(final boolean src, final boolean dst, final boolean encapVrfId, + final boolean decapVrfId, final boolean vni, final boolean protocol) { + final VxlanGpeBuilder builder = new VxlanGpeBuilder(); + builder.setLocal(src + ? new IpAddressNoZone(new Ipv4AddressNoZone(IPV4_1)) + : null); + builder.setRemote(dst + ? new IpAddressNoZone(new Ipv4AddressNoZone(IPV4_2)) + : null); + builder.setEncapVrfId(encapVrfId + ? ENCAP + : null); + builder.setDecapVrfId(decapVrfId + ? DECAP + : null); + builder.setVni(vni + ? new VxlanGpeVni(VNI) + : null); + builder.setNextProtocol(protocol + ? VxlanGpeNextProtocol.forValue(1) + : null); + return builder.build(); + } + + private VxlanGpe generateVxlanCorrect() { + return generateVxlanSetFields(true, true, true, true, true, true); + } + + private VxlanGpe generateVxlanMixedIpFamilies() { + return new VxlanGpeBuilder() + .setLocal(new IpAddressNoZone(new Ipv6AddressNoZone(IPV6))) + .setRemote(new IpAddressNoZone(new Ipv4AddressNoZone(IPV4_1))) + .setEncapVrfId(ENCAP).setDecapVrfId(DECAP) + .setVni(new VxlanGpeVni(VNI)) + .setNextProtocol(VxlanGpeNextProtocol.forValue(1)) + .build(); + } +} diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/VxlanValidatorTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/VxlanValidatorTest.java new file mode 100644 index 000000000..587b9f313 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/VxlanValidatorTest.java @@ -0,0 +1,142 @@ +/* + * 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.v3po.interfaces; + +import static org.mockito.MockitoAnnotations.initMocks; + +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.DisabledInterfacesManager; +import io.fd.honeycomb.translate.write.DataValidationFailedException.CreateValidationFailedException; +import io.fd.honeycomb.translate.write.DataValidationFailedException.DeleteValidationFailedException; +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.v3po.rev190502.L2Input; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.VppInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.VxlanVni; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.Vxlan; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.VxlanBuilder; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.fib.table.management.rev180521.VniReference; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressNoZone; +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.Ipv6AddressNoZone; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.Interfaces; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.InterfaceKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class VxlanValidatorTest { + + private VxlanValidator validator; + + @Mock + private WriteContext writeContext; + @Mock + private DisabledInterfacesManager interfaceDisableContext; + + private static final String IPV6 = "a::100"; + private static final String IPV4_1 = "192.168.20.10"; + private static final String IPV4_2 = "192.168.20.11"; + private static final Long VNI = Long.valueOf(11); + private static final Long ENCAP = Long.valueOf(123); + private static final String IFACE_NAME = "eth0"; + private static final InstanceIdentifier<Vxlan> ID = + InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IFACE_NAME)) + .augmentation(VppInterfaceAugmentation.class).child(Vxlan.class); + + @Before + public void setUp() { + initMocks(this); + NamingContext ifcContext = new NamingContext("testInterfaceContext", "testInterfaceContext"); + validator = new VxlanValidator(ifcContext, interfaceDisableContext); + } + + @Test + public void testWriteSuccessful() throws CreateValidationFailedException { + validator.validateWrite(ID, generateVxlanCorrect(), writeContext); + } + + @Test(expected = CreateValidationFailedException.class) + public void testWriteFailedMixedIpFamilies() throws CreateValidationFailedException { + validator.validateWrite(ID, generateVxlanMixedIpFamilies(), writeContext); + } + + @Test(expected = CreateValidationFailedException.class) + public void testWriteFailedNoSrc() throws CreateValidationFailedException { + validator.validateWrite(ID, generateVxlanSetFields(false, true, true, true), writeContext); + } + + @Test(expected = CreateValidationFailedException.class) + public void testWriteFailedNoDst() throws CreateValidationFailedException { + validator.validateWrite(ID, generateVxlanSetFields(true, false, true, true), writeContext); + } + + @Test(expected = CreateValidationFailedException.class) + public void testWriteFailedNoEncap() throws CreateValidationFailedException { + validator.validateWrite(ID, generateVxlanSetFields(true, true, false, true), writeContext); + } + + @Test(expected = CreateValidationFailedException.class) + public void testWriteFailedNoVNI() throws CreateValidationFailedException { + validator.validateWrite(ID, generateVxlanSetFields(true, true, true, false), writeContext); + } + + @Test + public void testDeleteSuccessful() throws DeleteValidationFailedException { + validator.validateDelete(ID, generateVxlanCorrect(), writeContext); + } + + private Vxlan generateVxlan(final IpAddressNoZone src, final IpAddressNoZone dst, final VniReference encapVrfId, + final long vni) { + final VxlanBuilder builder = new VxlanBuilder(); + builder.setSrc(src); + builder.setDst(dst); + builder.setEncapVrfId(encapVrfId); + builder.setVni(new VxlanVni(vni)); + builder.setDecapNext(L2Input.class); + return builder.build(); + } + + private Vxlan generateVxlanSetFields(final boolean src, final boolean dst, final boolean encapVrfId, + final boolean vni) { + final VxlanBuilder builder = new VxlanBuilder(); + builder.setSrc(src + ? new IpAddressNoZone(new Ipv4AddressNoZone(IPV4_1)) + : null); + builder.setDst(dst + ? new IpAddressNoZone(new Ipv4AddressNoZone(IPV4_2)) + : null); + builder.setEncapVrfId(encapVrfId + ? new VniReference(ENCAP) + : null); + builder.setVni(vni + ? new VxlanVni(VNI) + : null); + builder.setDecapNext(L2Input.class); + return builder.build(); + } + + private Vxlan generateVxlanCorrect() { + return generateVxlanSetFields(true, true, true, true); + } + + private Vxlan generateVxlanMixedIpFamilies() { + return generateVxlan(new IpAddressNoZone(new Ipv6AddressNoZone(IPV6)), + new IpAddressNoZone(new Ipv4AddressNoZone(IPV4_2)), new VniReference(ENCAP), VNI); + } +} diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/pbb/PbbRewriteCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/pbb/PbbRewriteCustomizerTest.java index d2c9ed3a8..206a5a086 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/pbb/PbbRewriteCustomizerTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/pbb/PbbRewriteCustomizerTest.java @@ -38,11 +38,9 @@ import org.mockito.Captor; import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.pbb.types.rev161214.Operation; import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.pbb.rev161214.PbbRewriteInterfaceAugmentation; import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.pbb.rev161214.interfaces._interface.PbbRewrite; -import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.pbb.rev161214.interfaces._interface.PbbRewriteBuilder; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.Interfaces; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.Interface; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; public class PbbRewriteCustomizerTest extends WriterCustomizerTest { @@ -72,14 +70,14 @@ public class PbbRewriteCustomizerTest extends WriterCustomizerTest { @Test public void testWrite() throws WriteFailedException { whenRewriteThenSuccess(); - customizer.writeCurrentAttributes(validId, validData(), writeContext); + customizer.writeCurrentAttributes(validId, PbbRewriteValidatorTest.validData(), writeContext); verifyRewriteRequest(desiredSetResult()); } @Test public void testWriteFailedCallFailed() { whenRewriteThenFail(); - final PbbRewrite validData = validData(); + final PbbRewrite validData = PbbRewriteValidatorTest.validData(); try { customizer.writeCurrentAttributes(validId, validData, writeContext); } catch (Exception e) { @@ -96,18 +94,9 @@ public class PbbRewriteCustomizerTest extends WriterCustomizerTest { } @Test - public void testWriteFailedInvalidData() { - verifyInvalidWriteDataCombination(invalidDataNoDestination()); - verifyInvalidWriteDataCombination(invalidDataNoSource()); - verifyInvalidWriteDataCombination(invalidDataNoItag()); - verifyInvalidWriteDataCombination(invalidDataNoOperation()); - verifyInvalidWriteDataCombination(invalidDataNoVlan()); - } - - @Test public void testUpdate() throws WriteFailedException { whenRewriteThenSuccess(); - final PbbRewrite rewrite = validData(); + final PbbRewrite rewrite = PbbRewriteValidatorTest.validData(); customizer.updateCurrentAttributes(validId, rewrite, rewrite, writeContext); verifyRewriteRequest(desiredSetResult()); } @@ -115,8 +104,8 @@ public class PbbRewriteCustomizerTest extends WriterCustomizerTest { @Test public void testUpdateFailedCallFailed() { whenRewriteThenFail(); - final PbbRewrite invalidData = invalidDataNoVlan(); - final PbbRewrite validData = validData(); + final PbbRewrite invalidData = PbbRewriteValidatorTest.invalidDataNoVlan(); + final PbbRewrite validData = PbbRewriteValidatorTest.validData(); try { customizer.updateCurrentAttributes(validId, invalidData, validData, writeContext); } catch (Exception e) { @@ -134,25 +123,16 @@ public class PbbRewriteCustomizerTest extends WriterCustomizerTest { } @Test - public void testUpdateFailedInvalidData() { - verifyInvalidUpdateDataCombination(invalidDataNoDestination()); - verifyInvalidUpdateDataCombination(invalidDataNoSource()); - verifyInvalidUpdateDataCombination(invalidDataNoItag()); - verifyInvalidUpdateDataCombination(invalidDataNoOperation()); - verifyInvalidUpdateDataCombination(invalidDataNoVlan()); - } - - @Test public void testDelete() throws WriteFailedException { whenRewriteThenSuccess(); - customizer.deleteCurrentAttributes(validId, validData(), writeContext); + customizer.deleteCurrentAttributes(validId, PbbRewriteValidatorTest.validData(), writeContext); verifyRewriteRequest(desiredDisableResult()); } @Test public void testDeleteFailedCallFailed() { whenRewriteThenFail(); - final PbbRewrite validData = validData(); + final PbbRewrite validData = PbbRewriteValidatorTest.validData(); try { customizer.deleteCurrentAttributes(validId, validData, writeContext); } catch (Exception e) { @@ -165,15 +145,6 @@ public class PbbRewriteCustomizerTest extends WriterCustomizerTest { fail("Test should have failed"); } - @Test - public void testDeleteFailedInvalidData() { - verifyInvalidDeleteDataCombination(invalidDataNoDestination()); - verifyInvalidDeleteDataCombination(invalidDataNoSource()); - verifyInvalidDeleteDataCombination(invalidDataNoItag()); - verifyInvalidDeleteDataCombination(invalidDataNoOperation()); - verifyInvalidDeleteDataCombination(invalidDataNoVlan()); - } - private void whenRewriteThenSuccess() { when(api.l2InterfacePbbTagRewrite(any())).thenReturn(future(new L2InterfacePbbTagRewriteReply())); } @@ -182,41 +153,6 @@ public class PbbRewriteCustomizerTest extends WriterCustomizerTest { when(api.l2InterfacePbbTagRewrite(any())).thenReturn(failedFuture()); } - private void verifyInvalidWriteDataCombination(final PbbRewrite invalidData) { - try { - customizer.writeCurrentAttributes(validId, invalidData, writeContext); - } catch (Exception e) { - assertTrue(e instanceof NullPointerException); - return; - } - - fail("Verifying of invalid combination failed"); - } - - private void verifyInvalidUpdateDataCombination(final PbbRewrite invalidData) { - try { - customizer.updateCurrentAttributes(validId, validData(), invalidData, writeContext); - } catch (Exception e) { - assertTrue(e instanceof NullPointerException); - return; - } - - fail("Verifying of invalid combination failed"); - } - - - private void verifyInvalidDeleteDataCombination(final PbbRewrite invalidData) { - try { - customizer.deleteCurrentAttributes(validId, invalidData, writeContext); - } catch (Exception e) { - assertTrue(e instanceof NullPointerException); - return; - } - - fail("Verifying of invalid combination failed"); - } - - private L2InterfacePbbTagRewrite desiredSetResult() { final L2InterfacePbbTagRewrite desiredResult = new L2InterfacePbbTagRewrite(); desiredResult.swIfIndex = 1; @@ -254,59 +190,4 @@ public class PbbRewriteCustomizerTest extends WriterCustomizerTest { assertArrayEquals(actualRequest.bDmac, desiredResult.bDmac); assertArrayEquals(actualRequest.bSmac, desiredResult.bSmac); } - - private PbbRewrite invalidDataNoDestination() { - return new PbbRewriteBuilder() - .setBVlanTagVlanId(1234) - .setITagIsid(2L) - .setSourceAddress(new MacAddress("aa:aa:aa:aa:aa:aa")) - .setInterfaceOperation(Operation.Pop2) - .build(); - } - - private PbbRewrite invalidDataNoSource() { - return new PbbRewriteBuilder() - .setBVlanTagVlanId(1234) - .setITagIsid(2L) - .setDestinationAddress(new MacAddress("bb:bb:bb:bb:bb:bb")) - .setInterfaceOperation(Operation.Pop2) - .build(); - } - - private PbbRewrite invalidDataNoItag() { - return new PbbRewriteBuilder() - .setBVlanTagVlanId(1234) - .setSourceAddress(new MacAddress("aa:aa:aa:aa:aa:aa")) - .setDestinationAddress(new MacAddress("bb:bb:bb:bb:bb:bb")) - .setInterfaceOperation(Operation.Pop2) - .build(); - } - - private PbbRewrite invalidDataNoVlan() { - return new PbbRewriteBuilder() - .setITagIsid(2L) - .setSourceAddress(new MacAddress("aa:aa:aa:aa:aa:aa")) - .setDestinationAddress(new MacAddress("bb:bb:bb:bb:bb:bb")) - .setInterfaceOperation(Operation.Pop2) - .build(); - } - - private PbbRewrite invalidDataNoOperation() { - return new PbbRewriteBuilder() - .setITagIsid(2L) - .setSourceAddress(new MacAddress("aa:aa:aa:aa:aa:aa")) - .setDestinationAddress(new MacAddress("bb:bb:bb:bb:bb:bb")) - .setInterfaceOperation(Operation.Pop2) - .build(); - } - - private PbbRewrite validData() { - return new PbbRewriteBuilder() - .setBVlanTagVlanId(1234) - .setITagIsid(2L) - .setSourceAddress(new MacAddress("aa:aa:aa:aa:aa:aa")) - .setDestinationAddress(new MacAddress("bb:bb:bb:bb:bb:bb")) - .setInterfaceOperation(Operation.Pop2) - .build(); - } } diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/pbb/PbbRewriteValidatorTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/pbb/PbbRewriteValidatorTest.java new file mode 100644 index 000000000..114a1bc19 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/pbb/PbbRewriteValidatorTest.java @@ -0,0 +1,189 @@ +/* + * 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.v3po.interfaces.pbb; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.MockitoAnnotations.initMocks; + +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.DataValidationFailedException.CreateValidationFailedException; +import io.fd.honeycomb.translate.write.DataValidationFailedException.DeleteValidationFailedException; +import io.fd.honeycomb.translate.write.DataValidationFailedException.UpdateValidationFailedException; +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.pbb.types.rev161214.Operation; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.pbb.rev161214.PbbRewriteInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.pbb.rev161214.interfaces._interface.PbbRewrite; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.pbb.rev161214.interfaces._interface.PbbRewriteBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.Interfaces; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class PbbRewriteValidatorTest { + + private PbbRewriteValidator validator; + private InstanceIdentifier<PbbRewrite> validId; + private InstanceIdentifier<PbbRewrite> invalidId; + + @Mock + private WriteContext writeContext; + + @Before + public void setUp() { + initMocks(this); + NamingContext ifcContext = new NamingContext("testInterfaceContext", "testInterfaceContext"); + validator = new PbbRewriteValidator(ifcContext); + validId = InstanceIdentifier.create(Interfaces.class) + .child(Interface.class, new InterfaceKey("pbb-interface")) + .augmentation(PbbRewriteInterfaceAugmentation.class) + .child(PbbRewrite.class); + + invalidId = InstanceIdentifier.create(PbbRewrite.class); + } + + @Test + public void testWriteSuccessful() + throws CreateValidationFailedException { + validator.validateWrite(validId, validData(), writeContext); + } + + @Test(expected = CreateValidationFailedException.class) + public void testWriteFailedInvalidIID() + throws CreateValidationFailedException { + validator.validateWrite(invalidId, validData(), writeContext); + } + + @Test + public void testWriteFailedInvalidData() { + verifyInvalidWriteDataCombination(invalidDataNoDestination()); + verifyInvalidWriteDataCombination(invalidDataNoSource()); + verifyInvalidWriteDataCombination(invalidDataNoItag()); + verifyInvalidWriteDataCombination(invalidDataNoOperation()); + verifyInvalidWriteDataCombination(invalidDataNoVlan()); + } + + @Test + public void testUpdateFailedInvalidData() { + verifyInvalidUpdateDataCombination(invalidDataNoDestination()); + verifyInvalidUpdateDataCombination(invalidDataNoSource()); + verifyInvalidUpdateDataCombination(invalidDataNoItag()); + verifyInvalidUpdateDataCombination(invalidDataNoOperation()); + verifyInvalidUpdateDataCombination(invalidDataNoVlan()); + } + + @Test + public void testDeleteFailedInvalidData() { + verifyInvalidDeleteDataCombination(invalidDataNoDestination()); + verifyInvalidDeleteDataCombination(invalidDataNoSource()); + verifyInvalidDeleteDataCombination(invalidDataNoItag()); + verifyInvalidDeleteDataCombination(invalidDataNoOperation()); + verifyInvalidDeleteDataCombination(invalidDataNoVlan()); + } + + private void verifyInvalidWriteDataCombination(final PbbRewrite invalidData) { + try { + validator.validateWrite(validId, invalidData, writeContext); + } catch (Exception e) { + assertTrue(e instanceof CreateValidationFailedException); + return; + } + + fail("Verifying of invalid combination failed"); + } + + private void verifyInvalidUpdateDataCombination(final PbbRewrite invalidData) { + try { + validator.validateUpdate(validId, validData(), invalidData, writeContext); + } catch (Exception e) { + assertTrue(e instanceof UpdateValidationFailedException); + return; + } + + fail("Verifying of invalid combination failed"); + } + + private void verifyInvalidDeleteDataCombination(final PbbRewrite invalidData) { + try { + validator.validateDelete(validId, invalidData, writeContext); + } catch (Exception e) { + assertTrue(e instanceof DeleteValidationFailedException); + return; + } + + fail("Verifying of invalid combination failed"); + } + + static PbbRewrite invalidDataNoDestination() { + return new PbbRewriteBuilder() + .setBVlanTagVlanId(1234) + .setITagIsid(2L) + .setSourceAddress(new MacAddress("aa:aa:aa:aa:aa:aa")) + .setInterfaceOperation(Operation.Pop2) + .build(); + } + + static PbbRewrite invalidDataNoSource() { + return new PbbRewriteBuilder() + .setBVlanTagVlanId(1234) + .setITagIsid(2L) + .setDestinationAddress(new MacAddress("bb:bb:bb:bb:bb:bb")) + .setInterfaceOperation(Operation.Pop2) + .build(); + } + + static PbbRewrite invalidDataNoItag() { + return new PbbRewriteBuilder() + .setBVlanTagVlanId(1234) + .setSourceAddress(new MacAddress("aa:aa:aa:aa:aa:aa")) + .setDestinationAddress(new MacAddress("bb:bb:bb:bb:bb:bb")) + .setInterfaceOperation(Operation.Pop2) + .build(); + } + + static PbbRewrite invalidDataNoVlan() { + return new PbbRewriteBuilder() + .setITagIsid(2L) + .setSourceAddress(new MacAddress("aa:aa:aa:aa:aa:aa")) + .setDestinationAddress(new MacAddress("bb:bb:bb:bb:bb:bb")) + .setInterfaceOperation(Operation.Pop2) + .build(); + } + + static PbbRewrite invalidDataNoOperation() { + return new PbbRewriteBuilder() + .setITagIsid(2L) + .setSourceAddress(new MacAddress("aa:aa:aa:aa:aa:aa")) + .setDestinationAddress(new MacAddress("bb:bb:bb:bb:bb:bb")) + .setInterfaceOperation(Operation.Pop2) + .build(); + } + + static PbbRewrite validData() { + return new PbbRewriteBuilder() + .setBVlanTagVlanId(1234) + .setITagIsid(2L) + .setSourceAddress(new MacAddress("aa:aa:aa:aa:aa:aa")) + .setDestinationAddress(new MacAddress("bb:bb:bb:bb:bb:bb")) + .setInterfaceOperation(Operation.Pop2) + .build(); + } +} diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/span/MirroredInterfacesCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/span/MirroredInterfacesCustomizerTest.java index 9a8ef72ef..e73106a57 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/span/MirroredInterfacesCustomizerTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/span/MirroredInterfacesCustomizerTest.java @@ -110,5 +110,4 @@ public class MirroredInterfacesCustomizerTest extends WriterCustomizerTest { assertEquals(IFACE_INDEX, deleteRequest.swIfIndexTo); assertEquals(SRC_IFACE_INDEX, deleteRequest.swIfIndexFrom); } - } diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/span/MirroredInterfacesValidatorTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/span/MirroredInterfacesValidatorTest.java new file mode 100644 index 000000000..e596c130f --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/span/MirroredInterfacesValidatorTest.java @@ -0,0 +1,115 @@ +/* + * 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.v3po.interfaces.span; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +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.http.fd.io.hc2vpp.yang.v3po.rev190502.SpanState; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.VppInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.Span; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.span.attributes.MirroredInterfaces; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.span.attributes.mirrored.interfaces.MirroredInterface; +import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.span.attributes.mirrored.interfaces.MirroredInterfaceBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.Interfaces; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.InterfaceKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class MirroredInterfacesValidatorTest { + + private InstanceIdentifier<MirroredInterface> validId; + private MirroredInterfaceValidator validator; + private static final String IFACE_NAME = "iface"; + private static final String SRC_IFACE_NAME = "src-iface"; + + @Mock + private WriteContext writeContext; + + @Before + public void setUp() { + initMocks(this); + NamingContext ifcContext = new NamingContext("testInterfaceContext", "testInterfaceContext"); + validator = new MirroredInterfaceValidator(ifcContext, id -> id.firstKeyOf(Interface.class).getName()); + validId = InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IFACE_NAME)) + .augmentation(VppInterfaceAugmentation.class).child(Span.class) + .child(MirroredInterfaces.class) + .child(MirroredInterface.class); + } + + @Test + public void testWriteSuccessful() + throws DataValidationFailedException.CreateValidationFailedException { + validator.validateWrite(validId, validData(), writeContext); + } + + @Test + public void testWriteFailed() { + validateWritingIncorrectData(incorrectDataNoIfaceRef()); + validateWritingIncorrectData(incorrectDataNoSpanState()); + } + + @Test + public void testUpdateSuccessful() + throws DataValidationFailedException.UpdateValidationFailedException { + validator.validateUpdate(validId, validData(), validData(), writeContext); + } + + @Test + public void testDeleteSuccessful() + throws DataValidationFailedException.DeleteValidationFailedException { + validator.validateDelete(validId, validData(), writeContext); + } + + private void validateWritingIncorrectData(final MirroredInterface data) { + try { + validator.validateWrite(validId, data, writeContext); + } catch (DataValidationFailedException.CreateValidationFailedException e) { + assertTrue(e instanceof DataValidationFailedException.CreateValidationFailedException); + return; + } + fail("Verifying of invalid combination failed"); + } + + private MirroredInterface incorrectDataNoIfaceRef() { + return new MirroredInterfaceBuilder() + .setIfaceRef(null) + .setState(SpanState.Receive) + .build(); + } + + private MirroredInterface incorrectDataNoSpanState() { + return new MirroredInterfaceBuilder() + .setIfaceRef(SRC_IFACE_NAME) + .setState(null) + .build(); + } + + private MirroredInterface validData() { + return new MirroredInterfaceBuilder() + .setIfaceRef(SRC_IFACE_NAME) + .setState(SpanState.Receive) + .build(); + } +} diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/VxlanGpeCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/VxlanGpeCustomizerTest.java index 2b89df0bb..e5bd6dc34 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/VxlanGpeCustomizerTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/VxlanGpeCustomizerTest.java @@ -139,145 +139,3 @@ public class VxlanGpeCustomizerTest extends ReaderCustomizerTest<VxlanGpe, Vxlan return new VxlanGpeCustomizer(api, interfacesContext, dumpCacheManager); } } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/span/MirroredInterfacesCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/span/MirroredInterfacesCustomizerTest.java index da7c8792e..c13775c75 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/span/MirroredInterfacesCustomizerTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfacesstate/span/MirroredInterfacesCustomizerTest.java @@ -104,7 +104,6 @@ public class MirroredInterfacesCustomizerTest MirroredInterfacesBuilder builder = new MirroredInterfacesBuilder(); getCustomizer().readCurrentAttributes(validId, builder, ctx); - final MirroredInterfaces data = builder.build(); // 1,2 should be returned,0 should be filtered out because of disabled state |