From 582bc3d05c36fcb2d8c92727a41f581b248da74a Mon Sep 17 00:00:00 2001 From: Jan Srnicek Date: Sun, 3 Jul 2016 18:56:54 +0200 Subject: HONEYCOMB-97 - Added support for ip_neighbour_add_del Change-Id: I20d957bbfce3e1c50d7501844382a3ef301c3e95 Signed-off-by: Jan Srnicek --- v3po/postman_rest_collection.json | 65 ++++++++- .../v3po/initializers/InterfacesInitializer.java | 25 +++- .../interfaces/ip/Ipv4NeighbourCustomizer.java | 142 ++++++++++++++++++ .../ip/Ipv4NeighbourCustomizer.java | 73 ++++++++++ .../rev160406/InterfacesHoneycombWriterModule.java | 32 ++-- .../InterfacesStateHoneycombReaderModule.java | 10 +- .../interfaces/ip/Ipv4NeighbourCustomizerTest.java | 162 +++++++++++++++++++++ 7 files changed, 479 insertions(+), 30 deletions(-) create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4NeighbourCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/ip/Ipv4NeighbourCustomizer.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4NeighbourCustomizerTest.java diff --git a/v3po/postman_rest_collection.json b/v3po/postman_rest_collection.json index 313a2efec..fdaca99c7 100644 --- a/v3po/postman_rest_collection.json +++ b/v3po/postman_rest_collection.json @@ -18,6 +18,9 @@ "name": "IP", "description": "", "order": [ + "014dcd2b-1024-37a3-bc85-c18b0fdc0e8c", + "eb4852a6-ff3a-f9f4-4332-6677a93fcd2a", + "dc22d351-497a-4f01-52c1-6f01c76cf80b", "69a05849-026d-f120-5c6a-f3e2b0884d88", "b10169c2-ae0e-bb1c-3dea-ca06839c6c9c", "8d49cf41-facc-c4ac-cee7-475d50e2a0be", @@ -218,6 +221,66 @@ "responses": [], "rawModeData": "{\r\n \r\n \"interface\": [\r\n {\r\n \"name\": \"testInterface\",\r\n \"description\": \"for testing purposes\",\r\n \"type\": \"iana-if-type:ethernetCsmacd\",\r\n \"enabled\": \"true\",\r\n \"link-up-down-trap-enable\": \"enabled\",\r\n \"ietf-ip:ipv4\": {\r\n \"enabled\": \"true\",\r\n \"mtu\": \"1500\",\r\n \"address\": [\r\n {\r\n \"ip\": \"1.2.3.0\",\r\n \"netmask\": \"255.255.255.0\"\r\n }\r\n ]\r\n }\r\n }\r\n ]\r\n \r\n}" }, + { + "id": "014dcd2b-1024-37a3-bc85-c18b0fdc0e8c", + "headers": "Content-Type: application/json\nAuthorization: Basic YWRtaW46YWRtaW4=\n", + "url": "http://localhost:8181/restconf/config/ietf-interfaces:interfaces/interface/GigabitEthernet0%2F8%2F0/ipv4/neighbor/172.16.0.2", + "preRequestScript": null, + "pathVariables": {}, + "method": "GET", + "data": [], + "dataMode": "raw", + "version": 2, + "tests": null, + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1466498440466, + "name": "Ip Neighbour Get", + "description": "This call returns data stored in honeycomb,to verify actual data stored by vpp, call vppctl show ip fib|arp", + "collectionId": "7c35192d-9085-20f6-9fcd-3f8570aaefd7", + "responses": [], + "rawModeData": "{\n \n \"interface\":{\n \"name\":\"GigabitEthernet0/8/0\",\n \"type\": \"iana-if-type:ethernetCsmacd\",\n \"enabled\":\"true\",\n \"ipv4\":{\n \"neighbor\":{\n \"ip\":\"172.16.0.2\",\n \"link-layer-address\":\"00:01:11:00:02:02\"\n }\n }\n }\n}\n" + }, + { + "id": "dc22d351-497a-4f01-52c1-6f01c76cf80b", + "headers": "Content-Type: application/json\nAuthorization: Basic YWRtaW46YWRtaW4=\n", + "url": "http://localhost:8181/restconf/config/ietf-interfaces:interfaces/interface/GigabitEthernet0%2F8%2F0/ipv4/neighbor/172.16.0.2", + "preRequestScript": null, + "pathVariables": {}, + "method": "DELETE", + "data": [], + "dataMode": "raw", + "version": 2, + "tests": null, + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1466498502212, + "name": "Ip Neighbour Delete", + "description": "Verify this call by invoking vppctl show ip fib|arp", + "collectionId": "7c35192d-9085-20f6-9fcd-3f8570aaefd7", + "responses": [], + "rawModeData": "{\n \"neighbor\":{\n \"ip\":\"172.16.0.2\",\n \"link-layer-address\":\"00:01:11:00:02:02\"\n }\n}\n" + }, + { + "id": "eb4852a6-ff3a-f9f4-4332-6677a93fcd2a", + "headers": "Content-Type: application/json\nAuthorization: Basic YWRtaW46YWRtaW4=\n", + "url": "http://localhost:8181/restconf/config/ietf-interfaces:interfaces/interface/GigabitEthernet0%2F8%2F0/ipv4/neighbor/172.16.0.2", + "preRequestScript": null, + "pathVariables": {}, + "method": "PUT", + "data": [], + "dataMode": "raw", + "version": 2, + "tests": null, + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1466498409820, + "name": "Ip Neighbour Add", + "description": "This call doesnt have respective dump call,because of performance issues(dump for this can contain millions of entries). Data inserted throught this call can be verified by calling vppctl show ip fib|arp", + "collectionId": "7c35192d-9085-20f6-9fcd-3f8570aaefd7", + "responses": [], + "rawModeData": "{\n \n \"neighbor\":{\n \"ip\":\"172.16.0.2\",\n \"link-layer-address\":\"00:01:11:00:02:02\"\n }\n \n}\n" + }, { "id": "2ca639f4-f4a4-07c7-9419-79fd66061458", "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n", @@ -1047,4 +1110,4 @@ "rawModeData": "{\r\n \"sub-interface\": [\r\n {\r\n \"identifier\": \"1\",\r\n \"vlan-type\": \"802dot1q\",\r\n \"tags\": {\r\n \"tag\": [\r\n {\r\n \"index\": \"0\",\r\n \"dot1q-tag\": {\r\n \"tag-type\": \"dot1q-types:s-vlan\",\r\n \"vlan-id\": \"100\"\r\n }\r\n },\r\n {\r\n \"index\": \"1\",\r\n \"dot1q-tag\": {\r\n \"tag-type\": \"dot1q-types:c-vlan\",\r\n \"vlan-id\": \"any\"\r\n }\r\n }\r\n ]\r\n },\r\n \"match\": {\r\n \"vlan-tagged\": {\r\n \"match-exact-tags\": \"true\"\r\n }\r\n },\r\n \"enabled\": \"true\"\r\n }\r\n ]\r\n}" } ] -} \ No newline at end of file +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/initializers/InterfacesInitializer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/initializers/InterfacesInitializer.java index 23898689f..5941710fa 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/initializers/InterfacesInitializer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/initializers/InterfacesInitializer.java @@ -36,6 +36,8 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev14061 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.Interface2; 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.ipv4.Neighbor; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.NeighborBuilder; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.Subnet; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.PrefixLengthBuilder; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv4; @@ -160,15 +162,22 @@ public class InterfacesInitializer extends AbstractDataTreeConverter collect = - ipv4.getAddress().stream() - .map(address -> new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.AddressBuilder() - .setIp(address.getIp()) - .setSubnet(getSubnet(address)) - .build()) + if (ipv4 != null) { + final List + collect = + ipv4.getAddress().stream() + .map(address -> new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.AddressBuilder() + .setIp(address.getIp()) + .setSubnet(getSubnet(address)) + .build()) + .collect(Collectors.toList()); + + final List neighbors = ipv4.getNeighbor().stream() + .map(neighbor -> new NeighborBuilder().setIp(neighbor.getIp()) + .setLinkLayerAddress(neighbor.getLinkLayerAddress()).build()) .collect(Collectors.toList()); - augmentBuilder.setIpv4(new Ipv4Builder().setAddress(collect).build()); + + augmentBuilder.setIpv4(new Ipv4Builder().setAddress(collect).setNeighbor(neighbors).build()); } // TODO ipv6 diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4NeighbourCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4NeighbourCustomizer.java new file mode 100644 index 000000000..e01d4c1bf --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4NeighbourCustomizer.java @@ -0,0 +1,142 @@ +/* + * 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.honeycomb.v3po.translate.v3po.interfaces.ip; + +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 com.google.common.base.Optional; +import io.fd.honeycomb.v3po.translate.MappingContext; +import io.fd.honeycomb.v3po.translate.spi.write.ListWriterCustomizer; +import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer; +import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext; +import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils; +import io.fd.honeycomb.v3po.translate.v3po.util.WriteTimeoutException; +import io.fd.honeycomb.v3po.translate.write.WriteContext; +import io.fd.honeycomb.v3po.translate.write.WriteFailedException; +import java.util.List; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Neighbor; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.NeighborKey; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.VppBaseCallException; +import org.openvpp.jvpp.dto.IpNeighborAddDel; +import org.openvpp.jvpp.future.FutureJVpp; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * Customizer for writing {@link Neighbor} for {@link Ipv4} + */ +public class Ipv4NeighbourCustomizer extends FutureJVppCustomizer + implements ListWriterCustomizer { + + + private static final Logger LOG = LoggerFactory.getLogger(Ipv4NeighbourCustomizer.class); + final NamingContext interfaceContext; + + public Ipv4NeighbourCustomizer(final FutureJVpp futureJvpp, final NamingContext interfaceContext) { + super(futureJvpp); + this.interfaceContext = interfaceContext; + } + + @Override + public void writeCurrentAttributes(@Nonnull InstanceIdentifier id, @Nonnull Neighbor dataAfter, + @Nonnull WriteContext writeContext) + throws WriteFailedException { + + checkNotNull(dataAfter, "Cannot write null neighbour"); + checkArgument(id.firstKeyOf(Interface.class) != null, "No parent interface key found"); + + LOG.debug("Processing request for Neigbour write"); + String interfaceName = id.firstKeyOf(Interface.class).getName(); + MappingContext mappingContext = writeContext.getMappingContext(); + + checkState(interfaceContext.containsIndex(interfaceName, mappingContext), + "Mapping does not contains mapping for provider interface name ".concat(interfaceName)); + + LOG.debug("Parent interface index found"); + try { + addDelNeighbourAndReply(id, true, + interfaceContext.getIndex(interfaceName, mappingContext), dataAfter); + LOG.info("Neighbour successfully written"); + } catch (VppBaseCallException e) { + throw new WriteFailedException.CreateFailedException(id, dataAfter, e); + } + } + + @Override + public void updateCurrentAttributes(@Nonnull InstanceIdentifier id, @Nonnull Neighbor dataBefore, + @Nonnull Neighbor dataAfter, + @Nonnull WriteContext writeContext) throws WriteFailedException { + new UnsupportedOperationException("Operation not supported"); + } + + @Override + public void deleteCurrentAttributes(@Nonnull InstanceIdentifier id, @Nonnull Neighbor dataBefore, + @Nonnull WriteContext writeContext) + throws WriteFailedException { + + checkNotNull(dataBefore, "Cannot delete null neighbour"); + checkArgument(id.firstKeyOf(Interface.class) != null, "No parent interface key found"); + + LOG.debug("Processing request for Neigbour delete"); + String interfaceName = id.firstKeyOf(Interface.class).getName(); + MappingContext mappingContext = writeContext.getMappingContext(); + + checkState(interfaceContext.containsIndex(interfaceName, mappingContext), + "Mapping does not contains mapping for provider interface name %s", interfaceName); + + LOG.debug("Parent interface[{}] index found", interfaceName); + try { + addDelNeighbourAndReply(id, false, + interfaceContext.getIndex(interfaceName, mappingContext), dataBefore); + LOG.info("Neighbour {} successfully deleted", id); + } catch (VppBaseCallException e) { + throw new WriteFailedException.DeleteFailedException(id, e); + } + } + + @Override + public Optional> extract(@Nonnull InstanceIdentifier currentId, + @Nonnull DataObject parentData) { + return Optional.fromNullable((((Ipv4) parentData).getNeighbor())); + } + + private void addDelNeighbourAndReply(InstanceIdentifier id, boolean add, int parentInterfaceIndex, + Neighbor data) + throws VppBaseCallException, WriteTimeoutException { + + IpNeighborAddDel request = new IpNeighborAddDel(); + + request.isAdd = TranslateUtils.booleanToByte(add); + request.isIpv6 = 0; + request.isStatic = 1; + request.dstAddress = TranslateUtils.ipv4AddressNoZoneToArray(data.getIp()); + request.macAddress = TranslateUtils.parseMac(data.getLinkLayerAddress().getValue()); + request.swIfIndex = parentInterfaceIndex; + + //TODO if it is necessary for future use ,make adjustments to be able to set vrfid + //request.vrfId + TranslateUtils.getReplyForWrite(getFutureJVpp().ipNeighborAddDel(request).toCompletableFuture(), id); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/ip/Ipv4NeighbourCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/ip/Ipv4NeighbourCustomizer.java new file mode 100644 index 000000000..103fbb012 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/ip/Ipv4NeighbourCustomizer.java @@ -0,0 +1,73 @@ +/* + * 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.honeycomb.v3po.translate.v3po.interfacesstate.ip; + +import io.fd.honeycomb.v3po.translate.read.ReadContext; +import io.fd.honeycomb.v3po.translate.read.ReadFailedException; +import io.fd.honeycomb.v3po.translate.spi.read.ListReaderCustomizer; +import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer; +import java.util.Collections; +import java.util.List; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv4Builder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.Neighbor; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.NeighborBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.NeighborKey; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.future.FutureJVpp; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Operational data read operation customizer for {@link Neighbor}
+ * Currently not supported in jvpp, so this is only dummy implementation
+ */ +public class Ipv4NeighbourCustomizer extends FutureJVppCustomizer + implements ListReaderCustomizer { + + private static final Logger LOG = LoggerFactory.getLogger(Ipv4NeighbourCustomizer.class); + + public Ipv4NeighbourCustomizer(FutureJVpp futureJvpp) { + super(futureJvpp); + } + + @Override + public NeighborBuilder getBuilder(InstanceIdentifier id) { + return new NeighborBuilder(); + } + + @Override + public void readCurrentAttributes(InstanceIdentifier id, NeighborBuilder builder, ReadContext ctx) + throws ReadFailedException { + //TODO - not supported, implement https://jira.fd.io/browse/VPP-164 first + LOG.warn("Operation not supported"); + } + + @Override + public List getAllIds(InstanceIdentifier id, ReadContext context) + throws ReadFailedException { + //TODO - not supported, implement https://jira.fd.io/browse/VPP-164 first + LOG.warn("Operation not supported,returning empty List"); + return Collections.emptyList(); + } + + @Override + public void merge(Builder builder, List readData) { + ((Ipv4Builder) builder).setNeighbor(readData); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/InterfacesHoneycombWriterModule.java b/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/InterfacesHoneycombWriterModule.java index e1513c213..d87370a8b 100644 --- a/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/InterfacesHoneycombWriterModule.java +++ b/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/InterfacesHoneycombWriterModule.java @@ -1,5 +1,6 @@ package org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.v3po2vpp.rev160406; +import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import io.fd.honeycomb.v3po.translate.impl.TraversalType; import io.fd.honeycomb.v3po.translate.impl.write.CompositeChildWriter; @@ -9,37 +10,27 @@ import io.fd.honeycomb.v3po.translate.util.RWUtils; import io.fd.honeycomb.v3po.translate.util.write.CloseableWriter; import io.fd.honeycomb.v3po.translate.util.write.NoopWriterCustomizer; import io.fd.honeycomb.v3po.translate.util.write.ReflexiveAugmentWriterCustomizer; -import io.fd.honeycomb.v3po.translate.v3po.interfaces.EthernetCustomizer; -import io.fd.honeycomb.v3po.translate.v3po.interfaces.InterfaceCustomizer; -import io.fd.honeycomb.v3po.translate.v3po.interfaces.L2Customizer; -import io.fd.honeycomb.v3po.translate.v3po.interfaces.RoutingCustomizer; -import io.fd.honeycomb.v3po.translate.v3po.interfaces.TapCustomizer; -import io.fd.honeycomb.v3po.translate.v3po.interfaces.VhostUserCustomizer; -import io.fd.honeycomb.v3po.translate.v3po.interfaces.VxlanCustomizer; -import io.fd.honeycomb.v3po.translate.v3po.interfaces.VxlanGpeCustomizer; +import io.fd.honeycomb.v3po.translate.v3po.interfaces.*; import io.fd.honeycomb.v3po.translate.v3po.interfaces.ip.Ipv4AddressCustomizer; import io.fd.honeycomb.v3po.translate.v3po.interfaces.ip.Ipv4Customizer; +import io.fd.honeycomb.v3po.translate.v3po.interfaces.ip.Ipv4NeighbourCustomizer; import io.fd.honeycomb.v3po.translate.v3po.interfaces.ip.Ipv6Customizer; import io.fd.honeycomb.v3po.translate.write.ChildWriter; -import java.util.ArrayList; -import java.util.List; 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.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.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Neighbor; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.Ethernet; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.L2; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.Routing; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.Tap; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.VhostUser; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.Vxlan; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.VxlanGpe; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.*; import org.opendaylight.yangtools.yang.binding.Augmentation; import org.opendaylight.yangtools.yang.binding.ChildOf; +import java.util.ArrayList; +import java.util.List; + public class InterfacesHoneycombWriterModule extends org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.v3po2vpp.rev160406.AbstractInterfacesHoneycombWriterModule { public InterfacesHoneycombWriterModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, @@ -89,12 +80,15 @@ public class InterfacesHoneycombWriterModule extends private ChildWriter> getInterface1AugmentationWriter() { + final ChildWriter neighborWriter = new CompositeListWriter<>(Neighbor.class, + new Ipv4NeighbourCustomizer(getVppJvppIfcDependency(),getInterfaceContextDependency())); + final ChildWriter
addressWriter = new CompositeListWriter<>(Address.class, new Ipv4AddressCustomizer(getVppJvppIfcDependency(), getInterfaceContextDependency())); final ChildWriter ipv4Writer = new CompositeChildWriter<>(Ipv4.class, - RWUtils.singletonChildWriterList(addressWriter), - new Ipv4Customizer(getVppJvppIfcDependency(), getInterfaceContextDependency())); + ImmutableList.of(neighborWriter,addressWriter), + new Ipv4Customizer(getVppJvppIfcDependency(),getInterfaceContextDependency())); final ChildWriter ipv6Writer = new CompositeChildWriter<>(Ipv6.class, new Ipv6Customizer(getVppJvppIfcDependency())); diff --git a/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/InterfacesStateHoneycombReaderModule.java b/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/InterfacesStateHoneycombReaderModule.java index 3b8c5a863..1b8898dff 100644 --- a/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/InterfacesStateHoneycombReaderModule.java +++ b/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/InterfacesStateHoneycombReaderModule.java @@ -4,6 +4,7 @@ import static io.fd.honeycomb.v3po.translate.util.RWUtils.emptyAugReaderList; import static io.fd.honeycomb.v3po.translate.util.RWUtils.emptyChildReaderList; import static io.fd.honeycomb.v3po.translate.util.RWUtils.singletonChildReaderList; +import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import io.fd.honeycomb.v3po.translate.impl.read.CompositeChildReader; import io.fd.honeycomb.v3po.translate.impl.read.CompositeListReader; @@ -22,6 +23,7 @@ import io.fd.honeycomb.v3po.translate.v3po.interfacesstate.VxlanCustomizer; import io.fd.honeycomb.v3po.translate.v3po.interfacesstate.VxlanGpeCustomizer; import io.fd.honeycomb.v3po.translate.v3po.interfacesstate.ip.Ipv4AddressCustomizer; import io.fd.honeycomb.v3po.translate.v3po.interfacesstate.ip.Ipv4Customizer; +import io.fd.honeycomb.v3po.translate.v3po.interfacesstate.ip.Ipv4NeighbourCustomizer; import io.fd.honeycomb.v3po.translate.v3po.interfacesstate.ip.Ipv6Customizer; import java.util.ArrayList; import java.util.List; @@ -35,6 +37,7 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev14061 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv4; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv6; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.Neighbor; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceStateAugmentation; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceStateAugmentationBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.Ethernet; @@ -88,11 +91,14 @@ public class InterfacesStateHoneycombReaderModule extends private ChildReader> getInterface1AugmentationReader() { + final ChildReader neighborReader = new CompositeListReader<>(Neighbor.class, + new Ipv4NeighbourCustomizer(getVppJvppDependency())); + final ChildReader
addressReader = new CompositeListReader<>(Address.class, - new Ipv4AddressCustomizer(getVppJvppDependency(), getInterfaceContextIfcStateDependency())); + new Ipv4AddressCustomizer(getVppJvppDependency(),getInterfaceContextIfcStateDependency())); final ChildReader> ipv4Reader = new CompositeChildReader<>(Ipv4.class, - RWUtils.singletonChildReaderList(addressReader), + ImmutableList.of(neighborReader,addressReader), new Ipv4Customizer(getVppJvppDependency())); final ChildReader> ipv6Reader = new CompositeChildReader<>(Ipv6.class, new Ipv6Customizer(getVppJvppDependency(), getInterfaceContextIfcStateDependency())); diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4NeighbourCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4NeighbourCustomizerTest.java new file mode 100644 index 000000000..5811907a4 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4NeighbourCustomizerTest.java @@ -0,0 +1,162 @@ +/* + * 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.honeycomb.v3po.translate.v3po.interfaces.ip; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.google.common.base.Optional; +import com.google.common.io.BaseEncoding; +import io.fd.honeycomb.v3po.translate.MappingContext; +import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext; +import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils; +import io.fd.honeycomb.v3po.translate.write.WriteContext; +import io.fd.honeycomb.v3po.translate.write.WriteFailedException; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.mappings.Mapping; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface1; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4Builder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Neighbor; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.NeighborBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.dto.IpNeighborAddDel; +import org.openvpp.jvpp.dto.IpNeighborAddDelReply; +import org.openvpp.jvpp.future.FutureJVpp; + +public class Ipv4NeighbourCustomizerTest { + + @Mock + private FutureJVpp jvpp; + + @Mock + private WriteContext context; + + @Mock + private MappingContext mappingContext; + + @Mock + private Mapping mapping; + + private ArgumentCaptor requestCaptor; + private Ipv4NeighbourCustomizer customizer; + private NamingContext namingContext; + + + @Before + public void init() { + MockitoAnnotations.initMocks(this); + + namingContext = new NamingContext("prefix", "instance"); + namingContext.addName(5, "parent", mappingContext); + + customizer = new Ipv4NeighbourCustomizer(jvpp,namingContext); + + requestCaptor = ArgumentCaptor.forClass(IpNeighborAddDel.class); + + CompletableFuture future = new CompletableFuture<>(); + future.complete(new IpNeighborAddDelReply()); + + when(context.getMappingContext()).thenReturn(mappingContext); + when(mapping.getIndex()).thenReturn(5); + when(mapping.getName()).thenReturn("parent"); + when(mappingContext.read(Mockito.any())).thenReturn(Optional.fromNullable(mapping)); + when(jvpp.ipNeighborAddDel(Mockito.any(IpNeighborAddDel.class))).thenReturn(future); + } + + @Test + public void testWriteCurrentAttributes() throws WriteFailedException { + + InterfaceKey intfKey = new InterfaceKey("parent"); + + InstanceIdentifier id = InstanceIdentifier.builder(Interfaces.class).child(Interface.class, intfKey) + .augmentation(Interface1.class).child(Ipv4.class).child(Neighbor.class).build(); + + Ipv4AddressNoZone noZoneIp = new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")); + PhysAddress mac = new PhysAddress("aa:bb:cc:ee:11:22"); + + Neighbor data = new NeighborBuilder().setIp(noZoneIp).setLinkLayerAddress(mac).build(); + + customizer.writeCurrentAttributes(id, data, context); + + verify(jvpp, times(1)).ipNeighborAddDel(requestCaptor.capture()); + + IpNeighborAddDel request = requestCaptor.getValue(); + + assertEquals(0, request.isIpv6); + assertEquals(1, request.isAdd); + assertEquals(1, request.isStatic); + assertEquals("1.2.168.192", TranslateUtils.arrayToIpv4AddressNoZone(request.dstAddress).getValue()); + assertEquals("aabbccee1122", BaseEncoding.base16().lowerCase().encode(request.macAddress)); + assertEquals(5, request.swIfIndex); + } + + @Test + public void testDeleteCurrentAttributes() throws WriteFailedException { + InterfaceKey intfKey = new InterfaceKey("parent"); + + InstanceIdentifier id = InstanceIdentifier.builder(Interfaces.class).child(Interface.class, intfKey) + .augmentation(Interface1.class).child(Ipv4.class).child(Neighbor.class).build(); + + Ipv4AddressNoZone noZoneIp = new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")); + PhysAddress mac = new PhysAddress("aa:bb:cc:ee:11:22"); + + Neighbor data = new NeighborBuilder().setIp(noZoneIp).setLinkLayerAddress(mac).build(); + + customizer.deleteCurrentAttributes(id, data, context); + + verify(jvpp, times(1)).ipNeighborAddDel(requestCaptor.capture()); + + IpNeighborAddDel request = requestCaptor.getValue(); + + assertEquals(0, request.isIpv6); + assertEquals(0, request.isAdd); + assertEquals(1, request.isStatic); + assertEquals("1.2.168.192", TranslateUtils.arrayToIpv4AddressNoZone(request.dstAddress).getValue()); + assertEquals("aabbccee1122", BaseEncoding.base16().lowerCase().encode(request.macAddress)); + assertEquals(5, request.swIfIndex); + } + + @Test + public void testExtract() { + Neighbor data = new NeighborBuilder().build(); + Ipv4 parentData = new Ipv4Builder().setNeighbor(Collections.singletonList(data)).build(); + + Optional> optionalData = new Ipv4NeighbourCustomizer(mock(FutureJVpp.class), null).extract(null, + parentData); + assertEquals(true, optionalData.isPresent()); + assertEquals(true, optionalData.get().contains(data)); + } + +} \ No newline at end of file -- cgit 1.2.3-korg