From e03effe522c038ba03d3cb31ca716a3eee7a5d72 Mon Sep 17 00:00:00 2001 From: Marek Gradzki Date: Thu, 23 Feb 2017 12:46:28 +0100 Subject: HC2VPP-84: multiple ARP proxy ranges support Change-Id: If3e2b8b889a62ce8b9e62f854c592c24f319c0d4 Signed-off-by: Marek Gradzki --- v3po/api/src/main/yang/proxy-arp.yang | 47 +++++++ v3po/api/src/main/yang/v3po.yang | 24 ---- .../main/java/io/fd/hc2vpp/v3po/V3poModule.java | 2 + .../v3po/factory/InterfacesStateReaderFactory.java | 6 - .../v3po/factory/InterfacesWriterFactory.java | 6 - .../hc2vpp/v3po/factory/ProxyArpWriterFactory.java | 70 +++++++++++ .../hc2vpp/v3po/interfaces/ProxyArpCustomizer.java | 136 --------------------- .../v3po/interfaces/ip/v4/ProxyArpCustomizer.java | 78 ++++++++++++ .../interfaces/ip/v4/ProxyRangeCustomizer.java | 105 ++++++++++++++++ .../v3po/interfacesstate/ProxyArpCustomizer.java | 79 ------------ .../v3po/interfaces/ProxyArpCustomizerTest.java | 60 ++++----- .../v3po/interfaces/ProxyRangeCustomizerTest.java | 96 +++++++++++++++ 12 files changed, 419 insertions(+), 290 deletions(-) create mode 100644 v3po/api/src/main/yang/proxy-arp.yang create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/ProxyArpWriterFactory.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ProxyArpCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/v4/ProxyArpCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/v4/ProxyRangeCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ProxyArpCustomizer.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/ProxyRangeCustomizerTest.java diff --git a/v3po/api/src/main/yang/proxy-arp.yang b/v3po/api/src/main/yang/proxy-arp.yang new file mode 100644 index 000000000..9629678e1 --- /dev/null +++ b/v3po/api/src/main/yang/proxy-arp.yang @@ -0,0 +1,47 @@ +module proxy-arp { + yang-version 1; + namespace "urn:opendaylight:params:xml:ns:yang:vpp:proxy:arp"; + prefix "proxy-arp"; + + revision "2017-03-15" { + description "Initial revision of proxy ARP model for VPP"; + } + + import ietf-inet-types { + prefix "inet"; + } + import ietf-interfaces { + prefix "if"; + } + import yang-ext { + prefix "ext"; + } + + container proxy-ranges { + list proxy-range { + key "vrf-id low-addr high-addr"; + leaf vrf-id { + type uint32; + } + leaf low-addr { + type inet:ipv4-address; + } + leaf high-addr { + type inet:ipv4-address; + } + description + "Parameters for configuring Proxy ARP on interfaces."; + } + } + + augment /if:interfaces/if:interface { + ext:augment-identifier "proxy-arp-interface-augmentation"; + + container proxy-arp { + presence "Enables proxy ARP on given interface"; + } + } + + // TODO(HC2VPP-86): add interfaces-state augmentation once VPP supports ARP proxy read (VPP-225) + // TODO(HC2VPP-7): move to interfaces/ip plugin +} \ No newline at end of file diff --git a/v3po/api/src/main/yang/v3po.yang b/v3po/api/src/main/yang/v3po.yang index 6333ec58d..14ca14d92 100644 --- a/v3po/api/src/main/yang/v3po.yang +++ b/v3po/api/src/main/yang/v3po.yang @@ -506,22 +506,6 @@ module v3po { } } - grouping proxy-arp-attributes { - description - "Parameters for configuring Proxy ARP on interfaces."; - - leaf vrf-id { - type uint32; - default 0; - } - leaf low-addr { - type inet:ipv4-address; - } - leaf high-addr { - type inet:ipv4-address; - } - } - grouping span-attributes { description "Parameters of the SPAN feature"; @@ -599,10 +583,6 @@ module v3po { uses vxlan-gpe-base-attributes; } - container proxy-arp { - uses proxy-arp-attributes; - } - container acl { container ingress { uses vpp-classfier-acl:acl-base-attributes; @@ -698,10 +678,6 @@ module v3po { uses l2-base-attributes; } - container proxy-arp { - uses proxy-arp-attributes; - } - container acl { container ingress { uses vpp-classfier-acl:acl-base-attributes; diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/V3poModule.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/V3poModule.java index d2e3ba442..fda7498f8 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/V3poModule.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/V3poModule.java @@ -29,6 +29,7 @@ import io.fd.hc2vpp.v3po.factory.Ipv4StateReaderFactory; import io.fd.hc2vpp.v3po.factory.Ipv4WriterFactory; import io.fd.hc2vpp.v3po.factory.Ipv6StateReaderFactory; import io.fd.hc2vpp.v3po.factory.Ipv6WriterFactory; +import io.fd.hc2vpp.v3po.factory.ProxyArpWriterFactory; import io.fd.hc2vpp.v3po.factory.SubInterfaceIpv4WriterFactory; import io.fd.hc2vpp.v3po.factory.SubInterfaceIpv6WriterFactory; import io.fd.hc2vpp.v3po.factory.SubInterfaceStateIpv4ReaderFactory; @@ -105,6 +106,7 @@ public class V3poModule extends AbstractModule { // Writers final Multibinder writerFactoryBinder = Multibinder.newSetBinder(binder(), WriterFactory.class); writerFactoryBinder.addBinding().to(InterfacesWriterFactory.class); + writerFactoryBinder.addBinding().to(ProxyArpWriterFactory.class); writerFactoryBinder.addBinding().to(SubinterfaceAugmentationWriterFactory.class); writerFactoryBinder.addBinding().to(VppHoneycombWriterFactory.class); writerFactoryBinder.addBinding().to(VppClassifierHoneycombWriterFactory.class); diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/InterfacesStateReaderFactory.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/InterfacesStateReaderFactory.java index bdb155677..91294d05f 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/InterfacesStateReaderFactory.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/InterfacesStateReaderFactory.java @@ -26,7 +26,6 @@ import io.fd.hc2vpp.v3po.interfacesstate.EthernetCustomizer; import io.fd.hc2vpp.v3po.interfacesstate.GreCustomizer; import io.fd.hc2vpp.v3po.interfacesstate.InterfaceCustomizer; import io.fd.hc2vpp.v3po.interfacesstate.L2Customizer; -import io.fd.hc2vpp.v3po.interfacesstate.ProxyArpCustomizer; import io.fd.hc2vpp.v3po.interfacesstate.RoutingCustomizer; import io.fd.hc2vpp.v3po.interfacesstate.TapCustomizer; import io.fd.hc2vpp.v3po.interfacesstate.VhostUserCustomizer; @@ -52,7 +51,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.Ethernet; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.Gre; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.L2; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.ProxyArp; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.Routing; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.Span; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.SpanBuilder; @@ -149,10 +147,6 @@ public final class InterfacesStateReaderFactory implements ReaderFactory { new GenericInitReader<>(aclIid.child(Ingress.class), new AclCustomizer(jvpp, ifcNamingCtx, classifyContext))); - // Proxy ARP - registry.add(new GenericReader<>(vppIfcAugId.child(ProxyArp.class), new ProxyArpCustomizer(jvpp, - ifcNamingCtx))); - // Span final InstanceIdentifier spanId = vppIfcAugId.child(Span.class); registry.addStructuralReader(spanId, SpanBuilder.class); 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 b321930d6..3dd7bb323 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 @@ -29,7 +29,6 @@ import io.fd.hc2vpp.v3po.interfaces.GreCustomizer; import io.fd.hc2vpp.v3po.interfaces.InterfaceCustomizer; import io.fd.hc2vpp.v3po.interfaces.L2Customizer; import io.fd.hc2vpp.v3po.interfaces.LoopbackCustomizer; -import io.fd.hc2vpp.v3po.interfaces.ProxyArpCustomizer; import io.fd.hc2vpp.v3po.interfaces.RoutingCustomizer; import io.fd.hc2vpp.v3po.interfaces.TapCustomizer; import io.fd.hc2vpp.v3po.interfaces.VhostUserCustomizer; @@ -53,7 +52,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Gre; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.L2; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Loopback; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.ProxyArp; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Routing; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Span; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Tap; @@ -151,10 +149,6 @@ public final class InterfacesWriterFactory implements WriterFactory { // L2(Execute only after subinterface (and all other ifc types) = registry.addAfter(new GenericWriter<>(L2_ID, new L2Customizer(jvpp, ifcNamingContext, bdNamingContext)), SubinterfaceAugmentationWriterFactory.SUB_IFC_ID); - // Proxy Arp (execute after specific interface customizers) - registry.addAfter( - new GenericWriter<>(VPP_IFC_AUG_ID.child(ProxyArp.class), new ProxyArpCustomizer(jvpp, ifcNamingContext)), - specificIfcTypes); // Ingress (execute after classify table and session writers) // also handles L2Acl, Ip4Acl and Ip6Acl: final InstanceIdentifier ingressId = InstanceIdentifier.create(Ingress.class); diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/ProxyArpWriterFactory.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/ProxyArpWriterFactory.java new file mode 100644 index 000000000..489a3b5b9 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/ProxyArpWriterFactory.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * + * 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.factory; + +import com.google.common.collect.Sets; +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.ip.v4.ProxyArpCustomizer; +import io.fd.hc2vpp.v3po.interfaces.ip.v4.ProxyRangeCustomizer; +import io.fd.honeycomb.translate.impl.write.GenericListWriter; +import io.fd.honeycomb.translate.impl.write.GenericWriter; +import io.fd.honeycomb.translate.write.WriterFactory; +import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.proxy.arp.rev170315.ProxyArpInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.proxy.arp.rev170315.ProxyRanges; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.proxy.arp.rev170315.interfaces._interface.ProxyArp; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.proxy.arp.rev170315.proxy.ranges.ProxyRange; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public final class ProxyArpWriterFactory implements WriterFactory { + + public static final InstanceIdentifier PROXY_RANGE_IID = + InstanceIdentifier.create(ProxyRanges.class).child(ProxyRange.class); + private static final InstanceIdentifier + IFC_ID = InstanceIdentifier.create(Interfaces.class).child(Interface.class); + private static final InstanceIdentifier PROXY_ARP_IID = + IFC_ID.augmentation(ProxyArpInterfaceAugmentation.class).child(ProxyArp.class); + + private final FutureJVppCore jvpp; + private final NamingContext ifcNamingContext; + + @Inject + public ProxyArpWriterFactory(final FutureJVppCore vppJvppIfcDependency, + @Named("interface-context") final NamingContext interfaceContextDependency) { + this.jvpp = vppJvppIfcDependency; + this.ifcNamingContext = interfaceContextDependency; + } + + @Override + public void init(final ModifiableWriterRegistryBuilder registry) { + // proxy-arp + // proxy-range = + registry.add(new GenericListWriter<>(PROXY_RANGE_IID, new ProxyRangeCustomizer(jvpp))); + + // interfaces + // interface + // proxy-arp-interface-augmentation + // proxy-arp = + registry.addAfter(new GenericWriter<>(PROXY_ARP_IID, new ProxyArpCustomizer(jvpp, ifcNamingContext)), + Sets.newHashSet(PROXY_RANGE_IID, IFC_ID)); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ProxyArpCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ProxyArpCustomizer.java deleted file mode 100644 index 9f5c4ac66..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ProxyArpCustomizer.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * 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 com.google.common.net.InetAddresses; -import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; -import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; -import io.fd.hc2vpp.common.translate.util.NamingContext; -import io.fd.honeycomb.translate.spi.write.WriterCustomizer; -import io.fd.honeycomb.translate.write.WriteContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.vpp.jvpp.core.dto.ProxyArpAddDel; -import io.fd.vpp.jvpp.core.dto.ProxyArpAddDelReply; -import io.fd.vpp.jvpp.core.dto.ProxyArpIntfcEnableDisable; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.net.InetAddress; -import java.util.concurrent.Future; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.ProxyArp; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class ProxyArpCustomizer extends FutureJVppCustomizer implements WriterCustomizer, JvppReplyConsumer { - - private static final Logger LOG = LoggerFactory.getLogger(ProxyArpCustomizer.class); - private final NamingContext interfaceContext; - - public ProxyArpCustomizer(final FutureJVppCore vppApi, final NamingContext interfaceContext) { - super(vppApi); - this.interfaceContext = interfaceContext; - } - - @Override - public void writeCurrentAttributes(@Nonnull InstanceIdentifier id, @Nonnull ProxyArp dataAfter, - @Nonnull WriteContext writeContext) throws WriteFailedException { - final String swIfName = id.firstKeyOf(Interface.class).getName(); - final int swIfIndex = interfaceContext.getIndex(swIfName, writeContext.getMappingContext()); - createProxyArp(getProxyArpRequestFuture(id, swIfName, dataAfter, (byte) 1 /* 1 is add */), id, dataAfter); - enableProxyArp(swIfName, swIfIndex, id); - } - - @Override - public void updateCurrentAttributes(@Nonnull InstanceIdentifier id, @Nonnull ProxyArp dataBefore, - @Nonnull ProxyArp dataAfter, @Nonnull WriteContext writeContext) - throws WriteFailedException.UpdateFailedException { - throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, - new UnsupportedOperationException("ARP proxy update is not supported")); - } - - @Override - public void deleteCurrentAttributes(@Nonnull InstanceIdentifier id, @Nonnull ProxyArp dataBefore, - @Nonnull WriteContext writeContext) throws WriteFailedException { - - final String swIfName = id.firstKeyOf(Interface.class).getName(); - final int swIfIndex = interfaceContext.getIndex(swIfName, writeContext.getMappingContext()); - deleteProxyArp(getProxyArpRequestFuture(id, swIfName, dataBefore, (byte) 0 /* 0 is delete */), id); - disableProxyArp(swIfName, swIfIndex, id); - } - - private Future getProxyArpRequestFuture(InstanceIdentifier id, String swIfName, - ProxyArp proxyArp, byte operation) - throws WriteFailedException { - LOG.debug("Setting Proxy ARP settings for interface: {}", swIfName); - final InetAddress srcAddress = InetAddresses.forString(getv4AddressString(proxyArp.getLowAddr())); - final InetAddress dstAddress = InetAddresses.forString(getv4AddressString(proxyArp.getHighAddr())); - final int vrfId = proxyArp.getVrfId().intValue(); - return getFutureJVpp().proxyArpAddDel( - getProxyArpConfRequest(operation, srcAddress.getAddress(), dstAddress.getAddress(), vrfId)) - .toCompletableFuture(); - } - - private void createProxyArp(final Future future, final InstanceIdentifier identifier, - final ProxyArp data) - throws WriteFailedException { - final ProxyArpAddDelReply reply = getReplyForCreate(future, identifier, data); - LOG.debug("Proxy ARP setting create successful, with reply context:", reply.context); - } - - private void deleteProxyArp(final Future future, final InstanceIdentifier identifier) - throws WriteFailedException { - final ProxyArpAddDelReply reply = getReplyForDelete(future, identifier); - LOG.debug("Proxy ARP setting delete successful, with reply context:", reply.context); - } - - private static ProxyArpAddDel getProxyArpConfRequest(final byte isAdd, final byte[] lAddr, final byte[] hAddr, - final int vrfId) { - - final ProxyArpAddDel proxyArpAddDel = new ProxyArpAddDel(); - proxyArpAddDel.isAdd = isAdd; - proxyArpAddDel.lowAddress = lAddr; - proxyArpAddDel.hiAddress = hAddr; - proxyArpAddDel.vrfId = vrfId; - return proxyArpAddDel; - } - - private String getv4AddressString(@Nonnull final Ipv4Address addr) { - return addr.getValue(); - } - - private void enableProxyArp(final String swIfName, final int swIfIndex, - final InstanceIdentifier identifier) - throws WriteFailedException { - final ProxyArpIntfcEnableDisable request = new ProxyArpIntfcEnableDisable(); - request.swIfIndex = swIfIndex; - request.enableDisable = 1; - getReplyForWrite(getFutureJVpp().proxyArpIntfcEnableDisable(request).toCompletableFuture(), identifier); - LOG.debug("Proxy ARP was successfully enabled on interface {} (id={})", swIfName, swIfIndex); - } - - private void disableProxyArp(final String swIfName, final int swIfIndex, - final InstanceIdentifier identifier) - throws WriteFailedException { - final ProxyArpIntfcEnableDisable request = new ProxyArpIntfcEnableDisable(); - request.swIfIndex = swIfIndex; - request.enableDisable = 0; - getReplyForDelete(getFutureJVpp().proxyArpIntfcEnableDisable(request).toCompletableFuture(), identifier); - LOG.debug("Proxy ARP was successfully disabled on interface {} (id={})", swIfName, swIfIndex); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/v4/ProxyArpCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/v4/ProxyArpCustomizer.java new file mode 100644 index 000000000..a39b9852f --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/v4/ProxyArpCustomizer.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * + * 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.ip.v4; + +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.spi.write.WriterCustomizer; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.ProxyArpIntfcEnableDisable; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.proxy.arp.rev170315.interfaces._interface.ProxyArp; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ProxyArpCustomizer extends FutureJVppCustomizer implements WriterCustomizer, JvppReplyConsumer { + + private static final Logger LOG = LoggerFactory.getLogger(ProxyArpCustomizer.class); + private final NamingContext interfaceContext; + + public ProxyArpCustomizer(final FutureJVppCore vppApi, final NamingContext interfaceContext) { + super(vppApi); + this.interfaceContext = interfaceContext; + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final ProxyArp dataAfter, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + final String swIfName = id.firstKeyOf(Interface.class).getName(); + final int swIfIndex = interfaceContext.getIndex(swIfName, writeContext.getMappingContext()); + final ProxyArpIntfcEnableDisable request = new ProxyArpIntfcEnableDisable(); + request.swIfIndex = swIfIndex; + request.enableDisable = 1; + getReplyForWrite(getFutureJVpp().proxyArpIntfcEnableDisable(request).toCompletableFuture(), id); + LOG.debug("Proxy ARP was successfully enabled on interface {} (id={})", swIfName, swIfIndex); + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final ProxyArp dataBefore, + @Nonnull final ProxyArp dataAfter, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, + new UnsupportedOperationException("Proxy ARP feature update is not supported.")); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final ProxyArp dataBefore, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + final String swIfName = id.firstKeyOf(Interface.class).getName(); + final int swIfIndex = interfaceContext.getIndex(swIfName, writeContext.getMappingContext()); + final ProxyArpIntfcEnableDisable request = new ProxyArpIntfcEnableDisable(); + request.swIfIndex = swIfIndex; + request.enableDisable = 0; + getReplyForDelete(getFutureJVpp().proxyArpIntfcEnableDisable(request).toCompletableFuture(), id); + LOG.debug("Proxy ARP was successfully disabled on interface {} (id={})", swIfName, swIfIndex); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/v4/ProxyRangeCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/v4/ProxyRangeCustomizer.java new file mode 100644 index 000000000..b46289fb4 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfaces/ip/v4/ProxyRangeCustomizer.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * + * 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.ip.v4; + +import com.google.common.net.InetAddresses; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.ProxyArpAddDel; +import io.fd.vpp.jvpp.core.dto.ProxyArpAddDelReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.net.InetAddress; +import java.util.concurrent.Future; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.proxy.arp.rev170315.proxy.ranges.ProxyRange; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.proxy.arp.rev170315.proxy.ranges.ProxyRangeKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ProxyRangeCustomizer extends FutureJVppCustomizer + implements ListWriterCustomizer, JvppReplyConsumer { + + private static final Logger LOG = LoggerFactory.getLogger(ProxyRangeCustomizer.class); + + public ProxyRangeCustomizer(final FutureJVppCore vppApi) { + super(vppApi); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final ProxyRange dataAfter, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + LOG.debug("Adding range of proxy ARP addresses: {}", dataAfter); + createProxyArp(getProxyArpRequestFuture(dataAfter, (byte) 1 /* 1 is add */), id, dataAfter); + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final ProxyRange dataBefore, + @Nonnull final ProxyRange dataAfter, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, + new UnsupportedOperationException("ARP proxy range update is not supported")); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final ProxyRange dataBefore, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + LOG.debug("Removing range of proxy ARP addresses: {}", dataBefore); + deleteProxyArp(getProxyArpRequestFuture(dataBefore, (byte) 0 /* 0 is delete */), id); + } + + private Future getProxyArpRequestFuture(ProxyRange proxyArp, byte operation) + throws WriteFailedException { + final InetAddress srcAddress = InetAddresses.forString(proxyArp.getLowAddr().getValue()); + final InetAddress dstAddress = InetAddresses.forString(proxyArp.getHighAddr().getValue()); + final int vrfId = proxyArp.getVrfId().intValue(); + return getFutureJVpp().proxyArpAddDel( + getProxyArpConfRequest(operation, srcAddress.getAddress(), dstAddress.getAddress(), vrfId)) + .toCompletableFuture(); + } + + private void createProxyArp(final Future future, + final InstanceIdentifier identifier, + final ProxyRange data) + throws WriteFailedException { + final ProxyArpAddDelReply reply = getReplyForCreate(future, identifier, data); + LOG.debug("Proxy ARP setting create successful, with reply context:", reply.context); + } + + private void deleteProxyArp(final Future future, + final InstanceIdentifier identifier) + throws WriteFailedException { + final ProxyArpAddDelReply reply = getReplyForDelete(future, identifier); + LOG.debug("Proxy ARP setting delete successful, with reply context:", reply.context); + } + + private static ProxyArpAddDel getProxyArpConfRequest(final byte isAdd, final byte[] lAddr, final byte[] hAddr, + final int vrfId) { + final ProxyArpAddDel proxyArpAddDel = new ProxyArpAddDel(); + proxyArpAddDel.isAdd = isAdd; + proxyArpAddDel.lowAddress = lAddr; + proxyArpAddDel.hiAddress = hAddr; + proxyArpAddDel.vrfId = vrfId; + return proxyArpAddDel; + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ProxyArpCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ProxyArpCustomizer.java deleted file mode 100644 index 551fa2b06..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ProxyArpCustomizer.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * 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.interfacesstate; - -import io.fd.honeycomb.translate.read.ReadContext; -import io.fd.honeycomb.translate.read.ReadFailedException; -import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; -import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; -import io.fd.hc2vpp.common.translate.util.NamingContext; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.ProxyArp; -import org.opendaylight.yangtools.concepts.Builder; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class ProxyArpCustomizer extends FutureJVppCustomizer - implements ReaderCustomizer { - - private static final Logger LOG = LoggerFactory.getLogger(ProxyArpCustomizer.class); - private final NamingContext interfaceContext; - - public ProxyArpCustomizer(final FutureJVppCore vppApi, final NamingContext interfaceContext) { - super(vppApi); - this.interfaceContext = interfaceContext; - } - - @Override - public void merge(@Nonnull Builder parentBuilder, - @Nonnull org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214 - .interfaces.state._interface.ProxyArp readValue) { - - ((VppInterfaceStateAugmentationBuilder) parentBuilder).setProxyArp(readValue); - } - - @Nonnull - @Override - public org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state - ._interface.ProxyArpBuilder getBuilder( - @Nonnull InstanceIdentifier id) { - - return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces - .state._interface.ProxyArpBuilder(); - } - - @Override - public void readCurrentAttributes(@Nonnull InstanceIdentifier id, - @Nonnull org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po - .rev161214.interfaces.state._interface.ProxyArpBuilder builder, - @Nonnull ReadContext ctx) throws ReadFailedException { - - //TODO: VPP-225 Implement fully when VPP Proxy ARP read API is available + add initializing - final InterfaceKey key = id.firstKeyOf(Interface.class); - final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext()); - LOG.debug("Reading of ARP data not (yet) supported by VPP API"); - } -} diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/ProxyArpCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/ProxyArpCustomizerTest.java index f1451fd9d..2e6d17b90 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/ProxyArpCustomizerTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/ProxyArpCustomizerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Cisco and/or its affiliates. + * Copyright (c) 2017 Cisco and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,25 +17,23 @@ package io.fd.hc2vpp.v3po.interfaces; import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.interfaces.ip.v4.ProxyArpCustomizer; import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.vpp.jvpp.core.dto.ProxyArpAddDel; -import io.fd.vpp.jvpp.core.dto.ProxyArpAddDelReply; import io.fd.vpp.jvpp.core.dto.ProxyArpIntfcEnableDisable; import io.fd.vpp.jvpp.core.dto.ProxyArpIntfcEnableDisableReply; import org.junit.Test; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.ProxyArp; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.ProxyArpBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.proxy.arp.rev170315.ProxyArpInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.proxy.arp.rev170315.interfaces._interface.ProxyArp; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; public class ProxyArpCustomizerTest extends WriterCustomizerTest implements ByteDataTranslator { @@ -43,60 +41,49 @@ public class ProxyArpCustomizerTest extends WriterCustomizerTest implements Byte private static final int IF_INDEX = 42; private static final String IFACE_CTX_NAME = "ifc-test-instance"; + private static final InstanceIdentifier + IID = InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IF_NAME)) + .augmentation(ProxyArpInterfaceAugmentation.class).child(ProxyArp.class); + private ProxyArpCustomizer customizer; + private ProxyArp data; @Override public void setUpTest() throws Exception { + data = mock(ProxyArp.class); customizer = new ProxyArpCustomizer(api, new NamingContext("ifacePrefix", IFACE_CTX_NAME)); defineMapping(mappingContext, IF_NAME, IF_INDEX, IFACE_CTX_NAME); - when(api.proxyArpIntfcEnableDisable(any())).thenReturn(future(new ProxyArpIntfcEnableDisableReply())); } @Test public void testWrite() throws WriteFailedException { - when(api.proxyArpAddDel(any())).thenReturn(future(new ProxyArpAddDelReply())); - customizer.writeCurrentAttributes(getProxyArpId(IF_NAME), proxyArp(), writeContext); - verify(api).proxyArpAddDel(expectedAddDelRequest(true)); + when(api.proxyArpIntfcEnableDisable(any())).thenReturn(future(new ProxyArpIntfcEnableDisableReply())); + customizer.writeCurrentAttributes(IID, data, writeContext); verify(api).proxyArpIntfcEnableDisable(expectedEnableRequest(true)); } @Test(expected = WriteFailedException.class) public void testWriteFailed() throws WriteFailedException { - when(api.proxyArpAddDel(any())).thenReturn(failedFuture()); - customizer.writeCurrentAttributes(getProxyArpId(IF_NAME), proxyArp(), writeContext); + when(api.proxyArpIntfcEnableDisable(any())).thenReturn(failedFuture()); + customizer.writeCurrentAttributes(IID, data, writeContext); } @Test(expected = WriteFailedException.UpdateFailedException.class) - public void testUpdate() throws WriteFailedException.UpdateFailedException { - customizer.updateCurrentAttributes(getProxyArpId(IF_NAME), proxyArp(), proxyArp(), writeContext); + public void testUpdate() throws WriteFailedException { + customizer.updateCurrentAttributes(IID, data, data, writeContext); } @Test public void testDelete() throws WriteFailedException { - when(api.proxyArpAddDel(any())).thenReturn(future(new ProxyArpAddDelReply())); - customizer.deleteCurrentAttributes(getProxyArpId(IF_NAME), proxyArp(), writeContext); - verify(api).proxyArpAddDel(expectedAddDelRequest(false)); + when(api.proxyArpIntfcEnableDisable(any())).thenReturn(future(new ProxyArpIntfcEnableDisableReply())); + customizer.deleteCurrentAttributes(IID, data, writeContext); verify(api).proxyArpIntfcEnableDisable(expectedEnableRequest(false)); } @Test(expected = WriteFailedException.DeleteFailedException.class) public void testDeleteFailed() throws WriteFailedException { - when(api.proxyArpAddDel(any())).thenReturn(failedFuture()); - customizer.deleteCurrentAttributes(getProxyArpId(IF_NAME), proxyArp(), writeContext); - } - - private ProxyArp proxyArp() { - return new ProxyArpBuilder().setVrfId(123L).setHighAddr(new Ipv4AddressNoZone("10.1.1.2")) - .setLowAddr(new Ipv4AddressNoZone("10.1.1.1")).build(); - } - - private ProxyArpAddDel expectedAddDelRequest(final boolean isAdd) { - final ProxyArpAddDel request = new ProxyArpAddDel(); - request.isAdd = booleanToByte(isAdd); - request.vrfId = 123; - request.lowAddress = new byte[]{10,1,1,1}; - request.hiAddress = new byte[]{10,1,1,2}; - return request; + when(api.proxyArpIntfcEnableDisable(any())).thenReturn(failedFuture()); + customizer.deleteCurrentAttributes(IID, data, writeContext); } private ProxyArpIntfcEnableDisable expectedEnableRequest(final boolean enable) { @@ -105,9 +92,4 @@ public class ProxyArpCustomizerTest extends WriterCustomizerTest implements Byte request.enableDisable = booleanToByte(enable); return request; } - - private InstanceIdentifier getProxyArpId(final String eth0) { - return InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(eth0)).augmentation( - VppInterfaceAugmentation.class).child(ProxyArp.class); - } } diff --git a/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/ProxyRangeCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/ProxyRangeCustomizerTest.java new file mode 100644 index 000000000..9b4760916 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/hc2vpp/v3po/interfaces/ProxyRangeCustomizerTest.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * 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.Matchers.any; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.v3po.interfaces.ip.v4.ProxyRangeCustomizer; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.ProxyArpAddDel; +import io.fd.vpp.jvpp.core.dto.ProxyArpAddDelReply; +import org.junit.Test; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.proxy.arp.rev170315.ProxyRanges; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.proxy.arp.rev170315.proxy.ranges.ProxyRange; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.proxy.arp.rev170315.proxy.ranges.ProxyRangeBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.proxy.arp.rev170315.proxy.ranges.ProxyRangeKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; + +public class ProxyRangeCustomizerTest extends WriterCustomizerTest implements ByteDataTranslator { + + private KeyedInstanceIdentifier IID; + private ProxyRange RANGE; + private ProxyRangeCustomizer customizer; + + @Override + public void setUpTest() throws Exception { + final Ipv4Address highAddr = new Ipv4AddressNoZone("10.1.1.2"); + final Ipv4Address lowAddr = new Ipv4AddressNoZone("10.1.1.1"); + final long vrfId = 123; + IID = InstanceIdentifier.create(ProxyRanges.class) + .child(ProxyRange.class, new ProxyRangeKey(highAddr, lowAddr, vrfId)); + RANGE = new ProxyRangeBuilder().setVrfId(vrfId).setHighAddr(highAddr).setLowAddr(new Ipv4AddressNoZone(lowAddr)) + .build(); + customizer = new ProxyRangeCustomizer(api); + } + + @Test + public void testWrite() throws WriteFailedException { + when(api.proxyArpAddDel(any())).thenReturn(future(new ProxyArpAddDelReply())); + customizer.writeCurrentAttributes(IID, RANGE, writeContext); + verify(api).proxyArpAddDel(expectedAddDelRequest(true)); + } + + @Test(expected = WriteFailedException.class) + public void testWriteFailed() throws WriteFailedException { + when(api.proxyArpAddDel(any())).thenReturn(failedFuture()); + customizer.writeCurrentAttributes(IID, RANGE, writeContext); + } + + @Test(expected = WriteFailedException.UpdateFailedException.class) + public void testUpdate() throws WriteFailedException { + customizer.updateCurrentAttributes(IID, RANGE, RANGE, writeContext); + } + + @Test + public void testDelete() throws WriteFailedException { + when(api.proxyArpAddDel(any())).thenReturn(future(new ProxyArpAddDelReply())); + customizer.deleteCurrentAttributes(IID, RANGE, writeContext); + verify(api).proxyArpAddDel(expectedAddDelRequest(false)); + } + + @Test(expected = WriteFailedException.DeleteFailedException.class) + public void testDeleteFailed() throws WriteFailedException { + when(api.proxyArpAddDel(any())).thenReturn(failedFuture()); + customizer.deleteCurrentAttributes(IID, RANGE, writeContext); + } + + private ProxyArpAddDel expectedAddDelRequest(final boolean isAdd) { + final ProxyArpAddDel request = new ProxyArpAddDel(); + request.isAdd = booleanToByte(isAdd); + request.vrfId = 123; + request.lowAddress = new byte[] {10, 1, 1, 1}; + request.hiAddress = new byte[] {10, 1, 1, 2}; + return request; + } +} -- cgit 1.2.3-korg