From 1c8b3b7dfb3cdf124e6a88df72612ec181de6f14 Mon Sep 17 00:00:00 2001 From: Maros Marsalek Date: Tue, 12 Apr 2016 10:13:34 +0200 Subject: HONEYCOMB-9: Add InterfaceCustomizer for ietf-interfaces Add custom reader for if:/interfaces-state/if:interface with no augmentations for now. Change-Id: Icc0f403db204430f27ac96cf7b32e7800e11dacb Signed-off-by: Stefan Kobza Signed-off-by: Maros Marsalek --- v3po/v3po2vpp/src/main/config/default-config.xml | 16 +++ .../v3po/interfacesstate/InterfaceCustomizer.java | 110 +++++++++++++++ .../v3po/interfacesstate/InterfaceUtils.java | 149 +++++++++++++++++++++ .../VppInterfaceStateCustomizer.java | 88 ++++++++++++ .../InterfacesStateHoneycombReaderModule.java | 96 +++++++++++++ ...nterfacesStateHoneycombReaderModuleFactory.java | 13 ++ v3po/v3po2vpp/src/main/yang/v3po2vpp.yang | 22 +++ .../interfacesstate/InterfaceCustomizerTest.java | 127 ++++++++++++++++++ 8 files changed, 621 insertions(+) create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceUtils.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VppInterfaceStateCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/InterfacesStateHoneycombReaderModule.java create mode 100644 v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/InterfacesStateHoneycombReaderModuleFactory.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizerTest.java diff --git a/v3po/v3po2vpp/src/main/config/default-config.xml b/v3po/v3po2vpp/src/main/config/default-config.xml index d76b0d6d3..1a1e6a8f5 100644 --- a/v3po/v3po2vpp/src/main/config/default-config.xml +++ b/v3po/v3po2vpp/src/main/config/default-config.xml @@ -34,6 +34,14 @@ vpp-japi + + prefix:interfaces-state-honeycomb-reader + interfaces-state-honeycomb-reader + + prefix:vpp-japi + vpp-japi + + prefix:vpp-honeycomb-writer @@ -51,6 +59,10 @@ prefix:honeycomb-reader vpp-state-honeycomb-reader + + prefix:honeycomb-reader + interfaces-state-honeycomb-reader + prefix:delegating-writer-registry @@ -69,6 +81,10 @@ /modules/module[type='vpp-state-honeycomb-reader'][name='vpp-state-honeycomb-reader'] + + interfaces-state-honeycomb-reader + /modules/module[type='interfaces-state-honeycomb-reader'][name='interfaces-state-honeycomb-reader'] + prefix:honeycomb-writer diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizer.java new file mode 100644 index 000000000..718cef1b5 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizer.java @@ -0,0 +1,110 @@ +/* + * 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; + +import io.fd.honeycomb.v3po.translate.Context; +import io.fd.honeycomb.v3po.translate.read.ReadFailedException; +import io.fd.honeycomb.v3po.translate.spi.read.ListReaderCustomizer; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.EthernetCsmacd; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesStateBuilder; +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.Interface.AdminStatus; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder; +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.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.vppjapi.vppInterfaceDetails; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; + + +public class InterfaceCustomizer extends io.fd.honeycomb.v3po.translate.v3po.util.VppApiCustomizer + implements ListReaderCustomizer { + + private static final Logger LOG = LoggerFactory.getLogger(InterfaceCustomizer.class); + + public InterfaceCustomizer(org.openvpp.vppjapi.vppApi vppApi) { + super(vppApi); + } + + @Override + public InterfaceBuilder getBuilder(InstanceIdentifier id) { + return new InterfaceBuilder(); + } + + @Override + public void readCurrentAttributes(InstanceIdentifier id, InterfaceBuilder builder, Context ctx) + throws ReadFailedException { + vppInterfaceDetails[] ifaces; + + final InterfaceKey key = id.firstKeyOf(id.getTargetType()); + // Extract one interface detail from VPP + ifaces = getVppApi().swInterfaceDump((byte) 1, key.getName().getBytes()); + if (null == ifaces) { + LOG.warn("VPP returned null instead of interface by key {}", key.getName().getBytes()); + return; + } + + if (1 != ifaces.length) { + LOG.error("Failed to extract interface {} details from VPP", key.getName()); + return; + } + + final vppInterfaceDetails iface = ifaces[0]; + + builder.setName(iface.interfaceName); + // FIXME: report interface type based on name + //Tunnel.class l2vlan(802.1q) bridge (transparent bridge?) + builder.setType(EthernetCsmacd.class); + builder.setIfIndex(InterfaceUtils.vppIfIndexToYang(iface.ifIndex)); + builder.setAdminStatus(iface.adminUp == 1 ? AdminStatus.Up : AdminStatus.Down); + builder.setOperStatus(1 == iface.linkUp ? OperStatus.Up : OperStatus.Down); + if (0 != iface.linkSpeed) { + builder.setSpeed(InterfaceUtils.vppInterfaceSpeedToYang(iface.linkSpeed)); + } + if (iface.physAddr.length == 6) { + builder.setPhysAddress(new PhysAddress(InterfaceUtils.vppPhysAddrToYang(iface.physAddr))); + } + } + + @Override + public List getAllIds(InstanceIdentifier id, Context context) { + vppInterfaceDetails[] ifaces; + final ArrayList interfaceKeys = new ArrayList<>(); + + ifaces = getVppApi().swInterfaceDump((byte) 0, "".getBytes()); + if (null != ifaces) { + for (vppInterfaceDetails ifc : ifaces) { + interfaceKeys.add(new InterfaceKey(ifc.interfaceName)); + } + } + + return interfaceKeys; + } + + @Override + public void merge(org.opendaylight.yangtools.concepts.Builder builder, + List readData) { + ((InterfacesStateBuilder) builder).setInterface(readData); + } + +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceUtils.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceUtils.java new file mode 100644 index 000000000..d589c257f --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceUtils.java @@ -0,0 +1,149 @@ +/* + * 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; + +import java.math.BigInteger; + +import javax.annotation.Nonnull; + +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Gauge64; + +import com.google.common.base.Preconditions; +import org.openvpp.vppjapi.vppApi; +import org.openvpp.vppjapi.vppInterfaceDetails; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class InterfaceUtils { + private static final Logger LOG = LoggerFactory.getLogger(InterfaceUtils.class); + + private static final Gauge64 vppLinkSpeed0 = new Gauge64(BigInteger.ZERO); + private static final Gauge64 vppLinkSpeed1 = new Gauge64(BigInteger.valueOf(10 * 1000000)); + private static final Gauge64 vppLinkSpeed2 = new Gauge64(BigInteger.valueOf(100 * 1000000)); + private static final Gauge64 vppLinkSpeed4 = new Gauge64(BigInteger.valueOf(1000 * 1000000)); + private static final Gauge64 vppLinkSpeed8 = new Gauge64(BigInteger.valueOf(10000L * 1000000)); + private static final Gauge64 vppLinkSpeed16 = new Gauge64(BigInteger.valueOf(40000L * 1000000)); + private static final Gauge64 vppLinkSpeed32 = new Gauge64(BigInteger.valueOf(100000L * 1000000)); + + private static final char[] HEX_CHARS = "0123456789abcdef".toCharArray(); + + /** + * Convert VPP's link speed bitmask to Yang type. 1 = 10M, 2 = 100M, 4 = 1G, + * 8 = 10G, 16 = 40G, 32 = 100G + * + * @param vppLinkSpeed Link speed in bitmask format from VPP. + * @return Converted value from VPP link speed + */ + public static Gauge64 vppInterfaceSpeedToYang(byte vppLinkSpeed) { + switch (vppLinkSpeed) { + case 1: + return vppLinkSpeed1; + case 2: + return vppLinkSpeed2; + case 4: + return vppLinkSpeed4; + case 8: + return vppLinkSpeed8; + case 16: + return vppLinkSpeed16; + case 32: + return vppLinkSpeed32; + default: + return vppLinkSpeed0; + } + } + + private static final void appendHexByte(final StringBuilder sb, final byte b) { + final int v = b & 0xFF; + sb.append(HEX_CHARS[v >>> 4]); + sb.append(HEX_CHARS[v & 15]); + } + + /** + * Convert VPP's physical address stored byte array format to string as Yang + * dictates + *

+ * Replace later with + * https://git.opendaylight.org/gerrit/#/c/34869/10/model/ietf/ietf-type- + * util/src/main/ + * java/org/opendaylight/mdsal/model/ietf/util/AbstractIetfYangUtil.java + * + * @param vppPhysAddress byte array of bytes constructing the network IF physical + * address. + * @return String like "aa:bb:cc:dd:ee:ff" + */ + public static String vppPhysAddrToYang(@Nonnull final byte[] vppPhysAddress) { + Preconditions.checkNotNull(vppPhysAddress, "Empty physicall address bytes"); + Preconditions.checkArgument(vppPhysAddress.length == 6, "Invalid physical address size %s, expected 6", + vppPhysAddress.length); + StringBuilder physAddr = new StringBuilder(); + + appendHexByte(physAddr, vppPhysAddress[0]); + for (int i = 1; i < vppPhysAddress.length; i++) { + physAddr.append(":"); + appendHexByte(physAddr, vppPhysAddress[i]); + } + + return physAddr.toString(); + } + + /** + * VPP's interface index is counted from 0, whereas ietf-interface's + * if-index is from 1. This function converts from VPP's interface index to YANG's interface index. + * + * @param vppIfIndex the sw interface index VPP reported. + * @return VPP's interface index incremented by one + */ + public static int vppIfIndexToYang(int vppIfIndex) { + return vppIfIndex + 1; + } + + /** + * This function does the opposite of what {@link #vppIfIndexToYang(int)} does. + * + * @param yangIf if-index from ietf-interfaces. + * @return VPP's representation of the if-index + */ + public static int YangIfIndexToVpp(int yangIfIndex) { + Preconditions.checkArgument(yangIfIndex >= 1, "YANG if-index has invalid value %s", yangIfIndex); + return yangIfIndex - 1; + } + + + public static vppInterfaceDetails[] getVppInterfaceDetails(final vppApi api, + final boolean specificInterface, + String interfaceName) { + if (interfaceName == null) { + interfaceName = new String(); + } + vppInterfaceDetails[] ifaces = api.swInterfaceDump( + (byte) (specificInterface ? 1 : 0), + interfaceName.getBytes()); + if (null == ifaces) { + LOG.warn("VPP returned null instead of interface by key {}", interfaceName); + return null; + } + + if (1 != ifaces.length) { + LOG.error("Failed to extract interface {} details from VPP", interfaceName); + } + + return ifaces; + } + + +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VppInterfaceStateCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VppInterfaceStateCustomizer.java new file mode 100644 index 000000000..8e5cc8932 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VppInterfaceStateCustomizer.java @@ -0,0 +1,88 @@ +/* + * 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; + +import static io.fd.honeycomb.v3po.translate.v3po.interfacesstate.InterfaceUtils.getVppInterfaceDetails; + +import io.fd.honeycomb.v3po.translate.Context; +import io.fd.honeycomb.v3po.translate.read.ReadFailedException; +import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer; +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.InterfaceBuilder; +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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.EthernetBuilder; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.vppjapi.vppInterfaceDetails; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class VppInterfaceStateCustomizer extends io.fd.honeycomb.v3po.translate.v3po.util.VppApiCustomizer + implements ChildReaderCustomizer { + + private static final Logger LOG = LoggerFactory.getLogger(VppInterfaceStateCustomizer.class); + + public VppInterfaceStateCustomizer(org.openvpp.vppjapi.vppApi vppApi) { + super(vppApi); + } + + @Override + public void merge(@Nonnull Builder parentBuilder, @Nonnull VppInterfaceStateAugmentation readValue) { + ((InterfaceBuilder) parentBuilder).addAugmentation(VppInterfaceStateAugmentation.class, readValue); + } + + @Nonnull + @Override + public VppInterfaceStateAugmentationBuilder getBuilder(@Nonnull InstanceIdentifier id) { + return new VppInterfaceStateAugmentationBuilder(); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final VppInterfaceStateAugmentationBuilder builder, + @Nonnull final Context ctx) throws ReadFailedException { + + final InterfaceKey key = id.firstKeyOf(Interface.class); + vppInterfaceDetails[] ifaces = getVppInterfaceDetails(getVppApi(), true, key.getName()); + if (null == ifaces || ifaces.length != 1) { + return; + } + + final vppInterfaceDetails iface = ifaces[0]; + final EthernetBuilder ethernet = new EthernetBuilder(); + + ethernet.setMtu(iface.linkMtu); + switch (iface.linkDuplex) { + case 1: + ethernet.setDuplex(Ethernet.Duplex.Half); + break; + case 2: + ethernet.setDuplex(Ethernet.Duplex.Full); + break; + default: + break; + } + + builder.setEthernet(ethernet.build()); + } +} 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 new file mode 100644 index 000000000..5b79ff0d3 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/InterfacesStateHoneycombReaderModule.java @@ -0,0 +1,96 @@ +package org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.v3po2vpp.rev160406; + +import com.google.common.base.Optional; +import io.fd.honeycomb.v3po.translate.impl.read.CompositeChildReader; +import io.fd.honeycomb.v3po.translate.impl.read.CompositeListReader; +import io.fd.honeycomb.v3po.translate.impl.read.CompositeRootReader; +import io.fd.honeycomb.v3po.translate.read.ChildReader; +import io.fd.honeycomb.v3po.translate.read.ReadContext; +import io.fd.honeycomb.v3po.translate.read.ReadFailedException; +import io.fd.honeycomb.v3po.translate.read.Reader; +import io.fd.honeycomb.v3po.translate.util.RWUtils; +import io.fd.honeycomb.v3po.translate.util.read.ReflexiveRootReaderCustomizer; +import io.fd.honeycomb.v3po.translate.v3po.interfacesstate.InterfaceCustomizer; +import io.fd.honeycomb.v3po.translate.v3po.interfacesstate.VppInterfaceStateCustomizer; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesStateBuilder; +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.InterfaceBuilder; +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.rev150105.VppInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceStateAugmentation; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.vppjapi.vppApi; + +import javax.annotation.Nonnull; + +public class InterfacesStateHoneycombReaderModule extends org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.v3po2vpp.rev160406.AbstractInterfacesStateHoneycombReaderModule { + public InterfacesStateHoneycombReaderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { + super(identifier, dependencyResolver); + } + + public InterfacesStateHoneycombReaderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.v3po2vpp.rev160406.InterfacesStateHoneycombReaderModule oldModule, java.lang.AutoCloseable oldInstance) { + super(identifier, dependencyResolver, oldModule, oldInstance); + } + + @Override + public void customValidation() { + // add custom validation form module attributes here. + } + + @Override + public java.lang.AutoCloseable createInstance() { + final vppApi vppApi = getVppJapiDependency(); + + final ChildReader vppInterfaceStateAugmentationChildReader = + new CompositeChildReader<>(VppInterfaceStateAugmentation.class, + new VppInterfaceStateCustomizer(vppApi)); + + final CompositeListReader interfaceReader = + new CompositeListReader<>(Interface.class, + RWUtils.emptyChildReaderList(), + RWUtils.singletonAugReaderList(vppInterfaceStateAugmentationChildReader), + new InterfaceCustomizer(vppApi)); + + return new CloseableReader(new CompositeRootReader<>( + InterfacesState.class, + RWUtils.singletonChildReaderList(interfaceReader), + RWUtils.emptyAugReaderList(), + new ReflexiveRootReaderCustomizer<>(InterfacesStateBuilder.class))); + } + + + private static final class CloseableReader implements Reader, AutoCloseable { + + private CompositeRootReader compositeRootReader; + + public CloseableReader( + final CompositeRootReader compositeRootReader) { + this.compositeRootReader = compositeRootReader; + } + + @Nonnull + @Override + public Optional read(@Nonnull InstanceIdentifier id, + @Nonnull ReadContext ctx) throws ReadFailedException { + return compositeRootReader.read(id, ctx); + } + + @Nonnull + @Override + public InstanceIdentifier getManagedDataObjectType() { + return compositeRootReader.getManagedDataObjectType(); + } + + @Override + public String toString() { + return compositeRootReader.toString(); + } + + @Override + public void close() throws Exception { + //NOOP + } + } +} diff --git a/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/InterfacesStateHoneycombReaderModuleFactory.java b/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/InterfacesStateHoneycombReaderModuleFactory.java new file mode 100644 index 000000000..f1c89f6ef --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/InterfacesStateHoneycombReaderModuleFactory.java @@ -0,0 +1,13 @@ +/* +* Generated file +* +* Generated from: yang module name: v3po2vpp yang module local name: interfaces-state-honeycomb-reader +* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator +* Generated at: Fri Apr 08 10:39:04 CEST 2016 +* +* Do not modify this file unless it is present under src/main directory +*/ +package org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.v3po2vpp.rev160406; +public class InterfacesStateHoneycombReaderModuleFactory extends org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.v3po2vpp.rev160406.AbstractInterfacesStateHoneycombReaderModuleFactory { + +} diff --git a/v3po/v3po2vpp/src/main/yang/v3po2vpp.yang b/v3po/v3po2vpp/src/main/yang/v3po2vpp.yang index a52a05fec..9d3199970 100644 --- a/v3po/v3po2vpp/src/main/yang/v3po2vpp.yang +++ b/v3po/v3po2vpp/src/main/yang/v3po2vpp.yang @@ -36,6 +36,28 @@ module v3po2vpp { } } + identity interfaces-state-honeycomb-reader { + base config:module-type; + config:provided-service tapi:honeycomb-reader; + } + + augment "/config:modules/config:module/config:configuration" { + case interfaces-state-honeycomb-reader { + when "/config:modules/config:module/config:type = 'interfaces-state-honeycomb-reader'"; + + container vpp-japi { + uses config:service-ref { + refine type { + mandatory true; + config:required-identity vjc:vpp-japi; + } + } + } + + } + } + + identity vpp-honeycomb-writer { base config:module-type; config:provided-service tapi:honeycomb-writer; diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizerTest.java new file mode 100644 index 000000000..111d813aa --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizerTest.java @@ -0,0 +1,127 @@ +/* + * 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; + +import com.google.common.base.Optional; +import com.google.common.collect.Iterables; +import com.google.common.collect.Multimap; +import io.fd.honeycomb.v3po.translate.impl.read.CompositeListReader; +import io.fd.honeycomb.v3po.translate.impl.read.CompositeRootReader; +import io.fd.honeycomb.v3po.translate.read.ChildReader; +import io.fd.honeycomb.v3po.translate.read.ReadContext; +import io.fd.honeycomb.v3po.translate.read.ReadFailedException; +import io.fd.honeycomb.v3po.translate.read.Reader; +import io.fd.honeycomb.v3po.translate.util.RWUtils; +import io.fd.honeycomb.v3po.translate.util.read.DelegatingReaderRegistry; +import io.fd.honeycomb.v3po.translate.util.read.ReflexiveRootReaderCustomizer; +import io.fd.honeycomb.v3po.translate.v3po.interfacesstate.InterfaceCustomizer; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesStateBuilder; +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.InterfaceBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; +import org.opendaylight.yangtools.yang.binding.ChildOf; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.vppjapi.vppApi; +import org.openvpp.vppjapi.vppInterfaceDetails; +import org.openvpp.vppjapi.vppVersion; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import static org.junit.Assert.assertTrue; +import static org.powermock.api.mockito.PowerMockito.mock; + +@RunWith(PowerMockRunner.class) +@SuppressStaticInitializationFor("org.openvpp.vppjapi.vppConn") +@PrepareForTest(vppApi.class) +public class InterfaceCustomizerTest { + + public static final vppVersion VERSION = new vppVersion("test", "1", "2", "33"); + + private vppApi api; + private CompositeRootReader interfacesStateReader; + private DelegatingReaderRegistry readerRegistry; + private ReadContext ctx; + + private CompositeRootReader getInterfacesStateReader( + final vppApi vppApi) { + + final CompositeListReader interfacesReader = + new CompositeListReader<>(Interface.class, new InterfaceCustomizer(vppApi)); + + final List>> childReaders = new ArrayList<>(); + childReaders.add(interfacesReader); + + return new CompositeRootReader<>(InterfacesState.class, childReaders, + RWUtils.emptyAugReaderList(), + new ReflexiveRootReaderCustomizer<>(InterfacesStateBuilder.class)); + } + + public static vppInterfaceDetails createVppInterfaceDetails(int ifIndex, String name) { + return new vppInterfaceDetails( + ifIndex, name, 0, + new byte[]{ (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00}, + (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, 0, 0, + (byte) 0, (byte) 0, (byte) 0, (byte) 0, 0, 0, 0, 0, 0); + } + + @Before + public void setUp() throws Exception { + api = mock(vppApi.class); + // PowerMockito.doReturn(VERSION).when(api).getVppVersion(); + ctx = mock(ReadContext.class); + List ifaces = new ArrayList<>(); + ifaces.add(createVppInterfaceDetails(0, "loop0")); + vppInterfaceDetails[] ifArr = ifaces.toArray(new vppInterfaceDetails[ifaces.size()]); + + PowerMockito.when(api.swInterfaceDump((byte) 0, new byte[]{})). + thenReturn(ifArr); + PowerMockito.when(api.swInterfaceDump((byte) 1, ifArr[0].interfaceName.getBytes())).thenReturn(ifArr); + + interfacesStateReader = getInterfacesStateReader(api); + readerRegistry = new DelegatingReaderRegistry( + Collections.>singletonList(interfacesStateReader)); + } + + @Test + public void testReadAll() throws ReadFailedException { + final Multimap, ? extends DataObject> dataObjects = + readerRegistry.readAll(ctx); + + System.out.println(dataObjects.keys()); + final DataObject obj = Iterables.getOnlyElement( + dataObjects.get(Iterables.getOnlyElement(dataObjects.keySet()))); + assertTrue(obj instanceof InterfacesState); + } + + @Test + public void testReadId() throws ReadFailedException { + Optional read = + readerRegistry.read(InstanceIdentifier.create(InterfacesState.class).child(Interface.class, new InterfaceKey("Loofdsafdsap0")), ctx); + System.err.println(read); + } +} -- cgit 1.2.3-korg