HONEYCOMB-9: Add InterfaceCustomizer for ietf-interfaces
authorMaros Marsalek <[email protected]>
Tue, 12 Apr 2016 08:13:34 +0000 (10:13 +0200)
committerMaros Marsalek <[email protected]>
Tue, 12 Apr 2016 08:13:34 +0000 (10:13 +0200)
Add custom reader for if:/interfaces-state/if:interface with no
augmentations for now.

Change-Id: Icc0f403db204430f27ac96cf7b32e7800e11dacb
Signed-off-by: Stefan Kobza <[email protected]>
Signed-off-by: Maros Marsalek <[email protected]>
v3po/v3po2vpp/src/main/config/default-config.xml
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizer.java [new file with mode: 0644]
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceUtils.java [new file with mode: 0644]
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VppInterfaceStateCustomizer.java [new file with mode: 0644]
v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/InterfacesStateHoneycombReaderModule.java [new file with mode: 0644]
v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/InterfacesStateHoneycombReaderModuleFactory.java [new file with mode: 0644]
v3po/v3po2vpp/src/main/yang/v3po2vpp.yang
v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizerTest.java [new file with mode: 0644]

index d76b0d6..1a1e6a8 100644 (file)
                         <name>vpp-japi</name>
                     </vpp-japi>
                 </module>
+                <module>
+                    <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:v3po2vpp">prefix:interfaces-state-honeycomb-reader</type>
+                    <name>interfaces-state-honeycomb-reader</name>
+                    <vpp-japi>
+                        <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:japi:cfg">prefix:vpp-japi</type>
+                        <name>vpp-japi</name>
+                    </vpp-japi>
+                </module>
 
                 <module>
                     <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:v3po2vpp">prefix:vpp-honeycomb-writer</type>
                         <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:api">prefix:honeycomb-reader</type>
                         <name>vpp-state-honeycomb-reader</name>
                     </root-readers>
+                    <root-readers>
+                        <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:api">prefix:honeycomb-reader</type>
+                        <name>interfaces-state-honeycomb-reader</name>
+                    </root-readers>
                 </module>
                 <module>
                     <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:utils">prefix:delegating-writer-registry</type>
                         <provider>/modules/module[type='vpp-state-honeycomb-reader'][name='vpp-state-honeycomb-reader']
                         </provider>
                     </instance>
+                    <instance>
+                        <name>interfaces-state-honeycomb-reader</name>
+                        <provider>/modules/module[type='interfaces-state-honeycomb-reader'][name='interfaces-state-honeycomb-reader']</provider>
+                    </instance>
                 </service>
                 <service>
                     <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:api">prefix:honeycomb-writer</type>
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 (file)
index 0000000..718cef1
--- /dev/null
@@ -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<Interface, InterfaceKey, InterfaceBuilder> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(InterfaceCustomizer.class);
+
+    public InterfaceCustomizer(org.openvpp.vppjapi.vppApi vppApi) {
+        super(vppApi);
+    }
+
+    @Override
+    public InterfaceBuilder getBuilder(InstanceIdentifier<Interface> id) {
+        return new InterfaceBuilder();
+    }
+
+    @Override
+    public void readCurrentAttributes(InstanceIdentifier<Interface> 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<InterfaceKey> getAllIds(InstanceIdentifier<Interface> id, Context context) {
+        vppInterfaceDetails[] ifaces;
+        final ArrayList<InterfaceKey> 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<? extends DataObject> builder,
+                      List<Interface> 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 (file)
index 0000000..d589c25
--- /dev/null
@@ -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
+     * <p>
+     * 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 (file)
index 0000000..8e5cc89
--- /dev/null
@@ -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<VppInterfaceStateAugmentation, VppInterfaceStateAugmentationBuilder> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(VppInterfaceStateCustomizer.class);
+
+    public VppInterfaceStateCustomizer(org.openvpp.vppjapi.vppApi vppApi) {
+        super(vppApi);
+    }
+
+    @Override
+    public void merge(@Nonnull Builder<? extends DataObject> parentBuilder, @Nonnull VppInterfaceStateAugmentation readValue) {
+        ((InterfaceBuilder) parentBuilder).addAugmentation(VppInterfaceStateAugmentation.class, readValue);
+    }
+
+    @Nonnull
+    @Override
+    public VppInterfaceStateAugmentationBuilder getBuilder(@Nonnull InstanceIdentifier<VppInterfaceStateAugmentation> id) {
+        return new VppInterfaceStateAugmentationBuilder();
+    }
+
+    @Override
+    public void readCurrentAttributes(@Nonnull final InstanceIdentifier<VppInterfaceStateAugmentation> 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 (file)
index 0000000..5b79ff0
--- /dev/null
@@ -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<VppInterfaceStateAugmentation> vppInterfaceStateAugmentationChildReader =
+                new CompositeChildReader<>(VppInterfaceStateAugmentation.class,
+                        new VppInterfaceStateCustomizer(vppApi));
+
+        final CompositeListReader<Interface, InterfaceKey, InterfaceBuilder> interfaceReader =
+                new CompositeListReader<>(Interface.class,
+                        RWUtils.<Interface>emptyChildReaderList(),
+                        RWUtils.<Interface>singletonAugReaderList(vppInterfaceStateAugmentationChildReader),
+                        new InterfaceCustomizer(vppApi));
+
+        return new CloseableReader(new CompositeRootReader<>(
+                InterfacesState.class,
+                RWUtils.singletonChildReaderList(interfaceReader),
+                RWUtils.<InterfacesState>emptyAugReaderList(),
+                new ReflexiveRootReaderCustomizer<>(InterfacesStateBuilder.class)));
+    }
+
+
+    private static final class CloseableReader implements Reader<InterfacesState>, AutoCloseable {
+
+        private CompositeRootReader<InterfacesState, InterfacesStateBuilder> compositeRootReader;
+
+        public CloseableReader(
+                final CompositeRootReader<InterfacesState, InterfacesStateBuilder> compositeRootReader) {
+            this.compositeRootReader = compositeRootReader;
+        }
+
+        @Nonnull
+        @Override
+        public Optional<? extends DataObject> read(@Nonnull InstanceIdentifier<? extends DataObject> id,
+                                                   @Nonnull ReadContext ctx) throws ReadFailedException {
+            return compositeRootReader.read(id, ctx);
+        }
+
+        @Nonnull
+        @Override
+        public InstanceIdentifier<InterfacesState> 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 (file)
index 0000000..f1c89f6
--- /dev/null
@@ -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 {
+
+}
index a52a05f..9d31999 100644 (file)
@@ -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 (file)
index 0000000..111d813
--- /dev/null
@@ -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<InterfacesState, InterfacesStateBuilder> interfacesStateReader;
+    private DelegatingReaderRegistry readerRegistry;
+    private ReadContext ctx;
+
+    private CompositeRootReader<InterfacesState, InterfacesStateBuilder> getInterfacesStateReader(
+            final vppApi vppApi) {
+
+        final CompositeListReader<Interface, InterfaceKey, InterfaceBuilder> interfacesReader =
+                new CompositeListReader<>(Interface.class, new InterfaceCustomizer(vppApi));
+
+        final List<ChildReader<? extends ChildOf<InterfacesState>>> childReaders = new ArrayList<>();
+        childReaders.add(interfacesReader);
+
+        return new CompositeRootReader<>(InterfacesState.class, childReaders,
+                RWUtils.<InterfacesState>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<vppInterfaceDetails> 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.<Reader<? extends DataObject>>singletonList(interfacesStateReader));
+    }
+
+    @Test
+    public void testReadAll() throws ReadFailedException {
+        final Multimap<InstanceIdentifier<? extends DataObject>, ? 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<? extends DataObject> read =
+                readerRegistry.read(InstanceIdentifier.create(InterfacesState.class).child(Interface.class, new InterfaceKey("Loofdsafdsap0")), ctx);
+        System.err.println(read);
+    }
+}