summaryrefslogtreecommitdiffstats
path: root/v3po/v3po2vpp/src
diff options
context:
space:
mode:
authorMarek Gradzki <mgradzki@cisco.com>2016-05-04 10:17:39 +0200
committerMarek Gradzki <mgradzki@cisco.com>2016-05-05 08:41:23 +0200
commitf187ae2f6a363616442a8968db1450977ce69078 (patch)
tree7e3c8799f931a47edbbf3a6ec40494a75a2a7d7f /v3po/v3po2vpp/src
parentfd5c022142f871c78d29708c89afc941518acbd0 (diff)
HONEYCOMB-10: Porting v3po2vpp to the new Java API
Change-Id: Ic7166b0f578442165595aa44a587ebbc5db0e75c Signed-off-by: Marek Gradzki <mgradzki@cisco.com> Signed-off-by: Maros Marsalek <mmarsale@cisco.com>
Diffstat (limited to 'v3po/v3po2vpp/src')
-rw-r--r--v3po/v3po2vpp/src/main/config/default-config.xml89
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/EthernetCustomizer.java7
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/InterfaceCustomizer.java59
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/L2Customizer.java76
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/RoutingCustomizer.java37
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanCustomizer.java59
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Interface1Customizer.java7
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4Customizer.java46
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv6Customizer.java7
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizer.java95
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceUtils.java73
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VppInterfaceStateCustomizer.java30
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/utils/V3poUtils.java55
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainCustomizer.java140
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/BridgeDomainCustomizer.java195
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VersionCustomizer.java33
-rw-r--r--v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/InterfacesHoneycombWriterModule.java24
-rw-r--r--v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/InterfacesStateHoneycombReaderModule.java41
-rw-r--r--v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/VppHoneycombWriterModule.java10
-rw-r--r--v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/VppStateHoneycombReaderModule.java10
-rw-r--r--v3po/v3po2vpp/src/main/yang/v3po2vpp.yang89
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizerTest.java200
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/ChildReaderCustomizerTest.java49
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/ListReaderCustomizerTest.java52
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/RootReaderCustomizerTest.java84
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/utils/V3poUtilsTest.java32
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainCustomizerTest.java205
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/VppTest.java185
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/VppUtils.java9
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/BridgeDomainCustomizerTest.java59
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VersionCustomizerTest.java73
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VppStateTest.java238
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VppStateTestUtils.java (renamed from v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VppStateUtils.java)41
33 files changed, 1574 insertions, 835 deletions
diff --git a/v3po/v3po2vpp/src/main/config/default-config.xml b/v3po/v3po2vpp/src/main/config/default-config.xml
index 89c3c47a2..cd736eddc 100644
--- a/v3po/v3po2vpp/src/main/config/default-config.xml
+++ b/v3po/v3po2vpp/src/main/config/default-config.xml
@@ -19,46 +19,90 @@
<snapshot>
<required-capabilities>
- <capability>urn:honeycomb:params:xml:ns:yang:vpp:japi:cfg?module=vpp-japi-cfg&amp;revision=2016-04-06</capability>
+ <capability>urn:honeycomb:params:xml:ns:yang:vpp:jvpp:cfg?module=vpp-jvpp-cfg&amp;revision=2016-04-06</capability>
<capability>urn:honeycomb:params:xml:ns:yang:v3po2vpp?module=v3po2vpp&amp;revision=2016-04-06</capability>
+ <capability>urn:honeycomb:params:xml:ns:yang:vpp:util?module=vpp-util&amp;revision=2016-04-06</capability>
</required-capabilities>
<configuration>
<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
<module>
+ <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:util">prefix:naming-context-impl</type>
+ <name>interface-context</name>
+ <artificial-name-prefix>interface-</artificial-name-prefix>
+ </module>
+ <module>
+ <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:util">prefix:naming-context-impl</type>
+ <name>bridge-domain-context</name>
+ <artificial-name-prefix>bridge-domain-</artificial-name-prefix>
+ </module>
+
+ <module>
<type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:v3po2vpp">prefix:vpp-state-honeycomb-reader</type>
<name>vpp-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>
+ <vpp-jvpp>
+ <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:jvpp:cfg">prefix:vpp-jvpp</type>
+ <name>vpp-jvpp</name>
+ </vpp-jvpp>
+ <interface-context-vpp-state>
+ <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:util">prefix:naming-context</type>
+ <name>interface-context</name>
+ </interface-context-vpp-state>
+ <bridge-domain-context-vpp-state>
+ <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:util">prefix:naming-context</type>
+ <name>bridge-domain-context</name>
+ </bridge-domain-context-vpp-state>
</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>
+ <vpp-jvpp>
+ <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:jvpp:cfg">prefix:vpp-jvpp</type>
+ <name>vpp-jvpp</name>
+ </vpp-jvpp>
+ <interface-context-ifc-state>
+ <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:util">prefix:naming-context</type>
+ <name>interface-context</name>
+ </interface-context-ifc-state>
+ <bridge-domain-context-ifc-state>
+ <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:util">prefix:naming-context</type>
+ <name>bridge-domain-context</name>
+ </bridge-domain-context-ifc-state>
</module>
<module>
<type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:v3po2vpp">prefix:vpp-honeycomb-writer</type>
<name>vpp-honeycomb-writer</name>
- <vpp-japi-writer>
- <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:japi:cfg">prefix:vpp-japi</type>
- <name>vpp-japi</name>
- </vpp-japi-writer>
+ <vpp-jvpp-writer>
+ <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:jvpp:cfg">prefix:vpp-jvpp</type>
+ <name>vpp-jvpp</name>
+ </vpp-jvpp-writer>
+ <interface-context-vpp>
+ <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:util">prefix:naming-context</type>
+ <name>interface-context</name>
+ </interface-context-vpp>
+ <bridge-domain-context-vpp>
+ <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:util">prefix:naming-context</type>
+ <name>bridge-domain-context</name>
+ </bridge-domain-context-vpp>
</module>
<module>
<type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:v3po2vpp">prefix:interfaces-honeycomb-writer</type>
<name>interfaces-honeycomb-writer</name>
- <vpp-japi-ifc>
- <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:japi:cfg">prefix:vpp-japi</type>
- <name>vpp-japi</name>
- </vpp-japi-ifc>
+ <vpp-jvpp-ifc>
+ <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:jvpp:cfg">prefix:vpp-jvpp</type>
+ <name>vpp-jvpp</name>
+ </vpp-jvpp-ifc>
+ <interface-context>
+ <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:util">prefix:naming-context</type>
+ <name>interface-context</name>
+ </interface-context>
+ <bridge-domain-context>
+ <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:util">prefix:naming-context</type>
+ <name>bridge-domain-context</name>
+ </bridge-domain-context>
</module>
<module>
@@ -102,6 +146,17 @@
</instance>
</service>
<service>
+ <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:util">prefix:naming-context</type>
+ <instance>
+ <name>interface-context</name>
+ <provider>/modules/module[type='naming-context-impl'][name='interface-context']</provider>
+ </instance>
+ <instance>
+ <name>bridge-domain-context</name>
+ <provider>/modules/module[type='naming-context-impl'][name='bridge-domain-context']</provider>
+ </instance>
+ </service>
+ <service>
<type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:api">prefix:honeycomb-writer</type>
<instance>
<name>vpp-honeycomb-writer</name>
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/EthernetCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/EthernetCustomizer.java
index 69ff63137..cdcea45f3 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/EthernetCustomizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/EthernetCustomizer.java
@@ -19,20 +19,21 @@ package io.fd.honeycomb.v3po.translate.v3po.interfaces;
import com.google.common.base.Optional;
import io.fd.honeycomb.v3po.translate.Context;
import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer;
-import io.fd.honeycomb.v3po.translate.v3po.util.VppApiCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
import javax.annotation.Nonnull;
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.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;
-public class EthernetCustomizer extends VppApiCustomizer implements ChildWriterCustomizer<Ethernet> {
+public class EthernetCustomizer extends FutureJVppCustomizer implements ChildWriterCustomizer<Ethernet> {
private static final Logger LOG = LoggerFactory.getLogger(EthernetCustomizer.class);
- public EthernetCustomizer(final org.openvpp.vppjapi.vppApi vppApi) {
+ public EthernetCustomizer(final FutureJVpp vppApi) {
super(vppApi);
}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/InterfaceCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/InterfaceCustomizer.java
index 30600d81e..5d5a6c08b 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/InterfaceCustomizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/InterfaceCustomizer.java
@@ -18,30 +18,36 @@ package io.fd.honeycomb.v3po.translate.v3po.interfaces;
import io.fd.honeycomb.v3po.translate.Context;
import io.fd.honeycomb.v3po.translate.spi.write.ListWriterCustomizer;
-import io.fd.honeycomb.v3po.translate.v3po.util.VppApiCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
+import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException;
import io.fd.honeycomb.v3po.translate.v3po.utils.V3poUtils;
import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
import java.util.List;
+import java.util.concurrent.CompletionStage;
import javax.annotation.Nonnull;
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.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.openvpp.vppjapi.vppApi;
+import org.openvpp.jvpp.dto.SwInterfaceSetFlags;
+import org.openvpp.jvpp.dto.SwInterfaceSetFlagsReply;
+import org.openvpp.jvpp.future.FutureJVpp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Ietf interface write customizer that only caches interface objects for child writers
*/
-public class InterfaceCustomizer extends VppApiCustomizer implements ListWriterCustomizer<Interface, InterfaceKey> {
+public class InterfaceCustomizer extends FutureJVppCustomizer implements ListWriterCustomizer<Interface, InterfaceKey> {
private static final Logger LOG = LoggerFactory.getLogger(InterfaceCustomizer.class);
+ private final NamingContext interfaceContext;
- public InterfaceCustomizer(final vppApi vppApi) {
+ public InterfaceCustomizer(final FutureJVpp vppApi, final NamingContext interfaceContext) {
super(vppApi);
+ this.interfaceContext = interfaceContext;
}
@Override
@@ -94,20 +100,15 @@ public class InterfaceCustomizer extends VppApiCustomizer implements ListWriterC
LOG.info("Setting interface {}, type: {}", swIf.getName(), swIf.getType().getSimpleName());
LOG.debug("Setting interface {}", swIf);
- String swIfName = swIf.getName();
- int swIfIndex = getVppApi().swIfIndexFromName(swIfName);
-
- setInterfaceAttributes(swIf, swIfName);
+ setInterfaceAttributes(swIf, swIf.getName());
}
private void setInterfaceAttributes(final Interface swIf, final String swIfName)
throws VppApiInvocationException {
LOG.debug("Creating {} interface {}", swIf.getType().getSimpleName(), swIf.getName());
- setInterfaceFlags(swIfName, getVppApi().swIfIndexFromName(swIfName),
+ setInterfaceFlags(swIfName, interfaceContext.getIndex(swIfName),
swIf.isEnabled() ? (byte) 1 : (byte) 0);
-
- setDescription(swIf);
}
private void updateInterface(final InstanceIdentifier<Interface> id,
@@ -116,35 +117,33 @@ public class InterfaceCustomizer extends VppApiCustomizer implements ListWriterC
LOG.info("Updating interface {}, type: {}", dataAfter.getName(), dataAfter.getType().getSimpleName());
LOG.debug("Updating interface {}", dataAfter);
- String swIfName = dataAfter.getName();
- int swIfIndex = getVppApi().swIfIndexFromName(swIfName);
-
- setInterfaceAttributes(dataAfter, swIfName);
+ setInterfaceAttributes(dataAfter, dataAfter.getName());
}
private void setInterfaceFlags(final String swIfName, final int swIfIndex, final byte enabled)
throws VppApiInvocationException {
- int ctxId = getVppApi().swInterfaceSetFlags(swIfIndex, enabled, enabled, (byte) 0 /* deleted */);
+ final CompletionStage<SwInterfaceSetFlagsReply> swInterfaceSetFlagsReplyFuture = getFutureJVpp().swInterfaceSetFlags(
+ getSwInterfaceSetFlagsInput(swIfIndex, enabled, (byte) 0 /* deleted */));
- LOG.debug("Updating interface flags for: {}, index: {}, enabled: {}, ctxId: {}", swIfName, swIfIndex,
- enabled, ctxId);
+ LOG.debug("Updating interface flags for: {}, index: {}, enabled: {}", swIfName, swIfIndex, enabled);
- final int rv = V3poUtils.waitForResponse(ctxId, getVppApi());
- if (rv < 0) {
- LOG.warn("Failed to update interface flags for: {}, index: {}, enabled: {}, ctxId: {}", swIfName, swIfIndex,
- enabled, ctxId);
- throw new VppApiInvocationException("swInterfaceSetFlags", ctxId, rv);
+ SwInterfaceSetFlagsReply reply = V3poUtils.getReply(swInterfaceSetFlagsReplyFuture.toCompletableFuture());
+ if (reply.retval < 0) {
+ LOG.warn("Failed to update interface flags for: {}, index: {}, enabled: {}", swIfName, swIfIndex,
+ enabled);
+ throw new VppApiInvocationException("swInterfaceSetFlags", reply.context, reply.retval);
} else {
LOG.debug("Interface flags updated successfully for: {}, index: {}, enabled: {}, ctxId: {}",
- swIfName, swIfIndex, enabled, ctxId);
+ swIfName, swIfIndex, enabled, reply.context);
}
}
- private void setDescription(final Interface swIf) {
- if (swIf.getDescription() != null) {
- getVppApi().setInterfaceDescription(swIf.getName(), swIf.getDescription());
- } else {
- getVppApi().setInterfaceDescription(swIf.getName(), "");
- }
+ private SwInterfaceSetFlags getSwInterfaceSetFlagsInput(final int swIfIndex, final byte enabled, final byte deleted) {
+ final SwInterfaceSetFlags swInterfaceSetFlags = new SwInterfaceSetFlags();
+ swInterfaceSetFlags.swIfIndex = swIfIndex;
+ swInterfaceSetFlags.adminUpDown = enabled;
+ swInterfaceSetFlags.linkUpDown = enabled;
+ swInterfaceSetFlags.deleted = deleted;
+ return swInterfaceSetFlags;
}
}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/L2Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/L2Customizer.java
index b9296b481..3bc04f81d 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/L2Customizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/L2Customizer.java
@@ -21,10 +21,12 @@ import static com.google.common.base.Preconditions.checkArgument;
import com.google.common.base.Optional;
import io.fd.honeycomb.v3po.translate.Context;
import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer;
-import io.fd.honeycomb.v3po.translate.v3po.util.VppApiCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
+import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException;
import io.fd.honeycomb.v3po.translate.v3po.utils.V3poUtils;
import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
+import java.util.concurrent.CompletionStage;
import javax.annotation.Nonnull;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentation;
@@ -34,15 +36,25 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.l2.interconnection.XconnectBased;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.openvpp.jvpp.dto.SwInterfaceSetL2Bridge;
+import org.openvpp.jvpp.dto.SwInterfaceSetL2BridgeReply;
+import org.openvpp.jvpp.dto.SwInterfaceSetL2Xconnect;
+import org.openvpp.jvpp.dto.SwInterfaceSetL2XconnectReply;
+import org.openvpp.jvpp.future.FutureJVpp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class L2Customizer extends VppApiCustomizer implements ChildWriterCustomizer<L2> {
+public class L2Customizer extends FutureJVppCustomizer implements ChildWriterCustomizer<L2> {
private static final Logger LOG = LoggerFactory.getLogger(L2Customizer.class);
+ private final NamingContext interfaceContext;
+ private final NamingContext bridgeDomainContext;
- public L2Customizer(final org.openvpp.vppjapi.vppApi vppApi) {
+ public L2Customizer(final FutureJVpp vppApi, final NamingContext interfaceContext,
+ final NamingContext bridgeDomainContext) {
super(vppApi);
+ this.interfaceContext = interfaceContext;
+ this.bridgeDomainContext = bridgeDomainContext;
}
@Nonnull
@@ -57,7 +69,7 @@ public class L2Customizer extends VppApiCustomizer implements ChildWriterCustomi
throws WriteFailedException {
final String ifcName = id.firstKeyOf(Interface.class).getName();
- final int swIfc = getSwIfc(ifcName);
+ final int swIfc = interfaceContext.getIndex(ifcName);
try {
setL2(id, swIfc, ifcName, dataAfter);
} catch (VppApiInvocationException e) {
@@ -72,7 +84,7 @@ public class L2Customizer extends VppApiCustomizer implements ChildWriterCustomi
throws WriteFailedException {
final String ifcName = id.firstKeyOf(Interface.class).getName();
- final int swIfc = getSwIfc(ifcName);
+ final int swIfc = interfaceContext.getIndex(ifcName);
// TODO handle update properly (if possible)
try {
setL2(id, swIfc, ifcName, dataAfter);
@@ -82,12 +94,6 @@ public class L2Customizer extends VppApiCustomizer implements ChildWriterCustomi
}
}
- private int getSwIfc(final String ifcName) {
- int swIfcIndex = getVppApi().swIfIndexFromName(ifcName);
- checkArgument(swIfcIndex != -1, "Interface %s does not exist", ifcName);
- return swIfcIndex;
- }
-
@Override
public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<L2> id, @Nonnull final L2 dataBefore,
@Nonnull final Context writeContext) {
@@ -126,7 +132,9 @@ public class L2Customizer extends VppApiCustomizer implements ChildWriterCustomi
bb.getBridgeDomain(), ifcName);
String bdName = bb.getBridgeDomain();
- int bdId = getVppApi().bridgeDomainIdFromName(bdName);
+
+ // FIXME need BridgeDomainContext here
+ int bdId = bridgeDomainContext.getIndex(bdName);
checkArgument(bdId > 0, "Unable to set Interconnection for Interface: %s, bridge domain: %s does not exist",
ifcName, bdName);
@@ -135,19 +143,32 @@ public class L2Customizer extends VppApiCustomizer implements ChildWriterCustomi
: (byte) 0;
byte shg = bb.getSplitHorizonGroup().byteValue();
- final int ctxId = getVppApi().swInterfaceSetL2Bridge(swIfIndex, bdId, shg, bvi, (byte) 1 /* enable */);
- final int rv = V3poUtils.waitForResponse(ctxId, getVppApi());
+ final CompletionStage<SwInterfaceSetL2BridgeReply> swInterfaceSetL2BridgeReplyCompletionStage = getFutureJVpp()
+ .swInterfaceSetL2Bridge(getL2BridgeRequest(swIfIndex, bdId, shg, bvi, (byte) 1 /* enable */));
+ final SwInterfaceSetL2BridgeReply reply =
+ V3poUtils.getReply(swInterfaceSetL2BridgeReplyCompletionStage.toCompletableFuture());
- if (rv < 0) {
+ if (reply.retval < 0) {
LOG.warn("Failed to update bridge based interconnection flags for: {}, interconnection: {}", ifcName,
bb);
- throw new VppApiInvocationException("swInterfaceSetL2Bridge", ctxId, rv);
+ throw new VppApiInvocationException("swInterfaceSetL2Bridge", reply.context, reply.retval);
} else {
LOG.debug("Bridge based interconnection updated successfully for: {}, interconnection: {}", ifcName,
bb);
}
}
+ private SwInterfaceSetL2Bridge getL2BridgeRequest(final int swIfIndex, final int bdId, final byte shg,
+ final byte bvi, final byte enabled) {
+ final SwInterfaceSetL2Bridge swInterfaceSetL2Bridge = new SwInterfaceSetL2Bridge();
+ swInterfaceSetL2Bridge.rxSwIfIndex = swIfIndex;
+ swInterfaceSetL2Bridge.bdId = bdId;
+ swInterfaceSetL2Bridge.shg = shg;
+ swInterfaceSetL2Bridge.bvi = bvi;
+ swInterfaceSetL2Bridge.enable = enabled;
+ return swInterfaceSetL2Bridge;
+ }
+
private void setXconnectBasedL2(final int swIfIndex, final String ifcName, final XconnectBased ic)
throws VppApiInvocationException {
@@ -155,21 +176,34 @@ public class L2Customizer extends VppApiCustomizer implements ChildWriterCustomi
LOG.debug("Setting xconnect based interconnection(outgoing ifc=%s) for interface: %s", outSwIfName,
ifcName);
- int outSwIfIndex = getVppApi().swIfIndexFromName(outSwIfName);
+ int outSwIfIndex = interfaceContext.getIndex(outSwIfName);
checkArgument(outSwIfIndex > 0,
"Unable to set Interconnection for Interface: %s, outgoing interface: %s does not exist",
ifcName, outSwIfIndex);
- int ctxId = getVppApi().swInterfaceSetL2Xconnect(swIfIndex, outSwIfIndex, (byte) 1 /* enable */);
- final int rv = V3poUtils.waitForResponse(ctxId, getVppApi());
+ final CompletionStage<SwInterfaceSetL2XconnectReply> swInterfaceSetL2XconnectReplyCompletionStage =
+ getFutureJVpp()
+ .swInterfaceSetL2Xconnect(getL2XConnectRequest(swIfIndex, outSwIfIndex, (byte) 1 /* enable */));
+ final SwInterfaceSetL2XconnectReply reply =
+ V3poUtils.getReply(swInterfaceSetL2XconnectReplyCompletionStage.toCompletableFuture());
- if (rv < 0) {
+ if (reply.retval < 0) {
LOG.warn("Failed to update xconnect based interconnection flags for: {}, interconnection: {}",
ifcName, ic);
- throw new VppApiInvocationException("swInterfaceSetL2Xconnect", ctxId, rv);
+ throw new VppApiInvocationException("swInterfaceSetL2Xconnect", reply.context, reply.retval);
} else {
LOG.debug("Xconnect based interconnection updated successfully for: {}, interconnection: {}", ifcName,
ic);
}
}
+
+ private SwInterfaceSetL2Xconnect getL2XConnectRequest(final int rxIfc, final int txIfc,
+ final byte enabled) {
+
+ final SwInterfaceSetL2Xconnect swInterfaceSetL2Xconnect = new SwInterfaceSetL2Xconnect();
+ swInterfaceSetL2Xconnect.enable = enabled;
+ swInterfaceSetL2Xconnect.rxSwIfIndex = rxIfc;
+ swInterfaceSetL2Xconnect.txSwIfIndex = txIfc;
+ return swInterfaceSetL2Xconnect;
+ }
}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/RoutingCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/RoutingCustomizer.java
index 718afc0e1..b15050cd0 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/RoutingCustomizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/RoutingCustomizer.java
@@ -16,30 +16,35 @@
package io.fd.honeycomb.v3po.translate.v3po.interfaces;
-import static com.google.common.base.Preconditions.checkArgument;
-
import com.google.common.base.Optional;
import io.fd.honeycomb.v3po.translate.Context;
import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer;
-import io.fd.honeycomb.v3po.translate.v3po.util.VppApiCustomizer;
+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.VppApiInvocationException;
import io.fd.honeycomb.v3po.translate.v3po.utils.V3poUtils;
import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
+import java.util.concurrent.CompletionStage;
import javax.annotation.Nonnull;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentation;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.Routing;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.openvpp.jvpp.dto.SwInterfaceSetTable;
+import org.openvpp.jvpp.dto.SwInterfaceSetTableReply;
+import org.openvpp.jvpp.future.FutureJVpp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class RoutingCustomizer extends VppApiCustomizer implements ChildWriterCustomizer<Routing> {
+public class RoutingCustomizer extends FutureJVppCustomizer implements ChildWriterCustomizer<Routing> {
private static final Logger LOG = LoggerFactory.getLogger(RoutingCustomizer.class);
+ private final NamingContext interfaceContext;
- public RoutingCustomizer(final org.openvpp.vppjapi.vppApi vppApi) {
+ public RoutingCustomizer(final FutureJVpp vppApi, final NamingContext interfaceContext) {
super(vppApi);
+ this.interfaceContext = interfaceContext;
}
@Nonnull
@@ -84,7 +89,7 @@ public class RoutingCustomizer extends VppApiCustomizer implements ChildWriterCu
}
private void setRouting(final String name, final Routing rt) throws VppApiInvocationException {
- final int swIfc = getSwIfc(name);
+ final int swIfc = interfaceContext.getIndex(name);
LOG.debug("Setting routing for interface: {}, {}. Routing: {}", name, swIfc, rt);
int vrfId = (rt != null)
@@ -92,21 +97,25 @@ public class RoutingCustomizer extends VppApiCustomizer implements ChildWriterCu
: 0;
if (vrfId != 0) {
- final int ctxId = getVppApi().swInterfaceSetTable(swIfc, (byte) 0, /* isIpv6 */ vrfId);
- final int rv = V3poUtils.waitForResponse(ctxId, getVppApi());
- if (rv < 0) {
+ final CompletionStage<SwInterfaceSetTableReply> swInterfaceSetTableReplyCompletionStage =
+ getFutureJVpp().swInterfaceSetTable(getInterfaceSetTableRequest(swIfc, (byte) 0, /* isIpv6 */ vrfId));
+ final SwInterfaceSetTableReply reply =
+ V3poUtils.getReply(swInterfaceSetTableReplyCompletionStage.toCompletableFuture());
+ if (reply.retval < 0) {
LOG.debug("Failed to set routing for interface: {}, {}, vxlan: {}", name, swIfc, rt);
- throw new VppApiInvocationException("swInterfaceSetTable", ctxId, rv);
+ throw new VppApiInvocationException("swInterfaceSetTable", reply.context, reply.retval);
} else {
LOG.debug("Routing set successfully for interface: {}, {}, routing: {}", name, swIfc, rt);
}
}
}
- private int getSwIfc(final String name) {
- int swIfcIndex = getVppApi().swIfIndexFromName(name);
- checkArgument(swIfcIndex != -1, "Interface %s does not exist", name);
- return swIfcIndex;
+ private SwInterfaceSetTable getInterfaceSetTableRequest(final int swIfc, final byte isIpv6, final int vrfId) {
+ final SwInterfaceSetTable swInterfaceSetTable = new SwInterfaceSetTable();
+ swInterfaceSetTable.isIpv6 = isIpv6;
+ swInterfaceSetTable.swIfIndex = swIfc;
+ swInterfaceSetTable.vrfId = vrfId;
+ return swInterfaceSetTable;
}
}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanCustomizer.java
index 6e84c303a..2e532660e 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanCustomizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanCustomizer.java
@@ -17,30 +17,36 @@
package io.fd.honeycomb.v3po.translate.v3po.interfaces;
import com.google.common.base.Optional;
+import com.google.common.net.InetAddresses;
import io.fd.honeycomb.v3po.translate.Context;
import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer;
-import io.fd.honeycomb.v3po.translate.v3po.util.VppApiCustomizer;
+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.VppApiInvocationException;
import io.fd.honeycomb.v3po.translate.v3po.utils.V3poUtils;
import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
+import java.net.InetAddress;
+import java.util.concurrent.CompletionStage;
import javax.annotation.Nonnull;
-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.Interface;
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.VxlanTunnel;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.Vxlan;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.openvpp.jvpp.dto.VxlanAddDelTunnel;
+import org.openvpp.jvpp.dto.VxlanAddDelTunnelReply;
+import org.openvpp.jvpp.future.FutureJVpp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class VxlanCustomizer extends VppApiCustomizer implements ChildWriterCustomizer<Vxlan> {
+public class VxlanCustomizer extends FutureJVppCustomizer implements ChildWriterCustomizer<Vxlan> {
private static final Logger LOG = LoggerFactory.getLogger(VxlanCustomizer.class);
+ private final NamingContext interfaceContext;
-
- public VxlanCustomizer(final org.openvpp.vppjapi.vppApi vppApi) {
+ public VxlanCustomizer(final FutureJVpp vppApi, final NamingContext interfaceContext) {
super(vppApi);
+ this.interfaceContext = interfaceContext;
}
@Nonnull
@@ -84,28 +90,39 @@ public class VxlanCustomizer extends VppApiCustomizer implements ChildWriterCust
}
private void createVxlanTunnel(final String swIfName, final Vxlan vxlan) throws VppApiInvocationException {
- Ipv4AddressNoZone srcAddress = V3poUtils.removeIpv4AddressNoZone(vxlan.getSrc());
- Ipv4AddressNoZone dstAddress = V3poUtils.removeIpv4AddressNoZone(vxlan.getDst());
-
- byte[] srcAddr = V3poUtils.ipv4AddressNoZoneToArray(srcAddress);
- byte[] dstAddr = V3poUtils.ipv4AddressNoZoneToArray(dstAddress);
+ final InetAddress srcAddress = InetAddresses.forString(vxlan.getSrc().getValue());
+ final InetAddress dstAddress = InetAddresses.forString(vxlan.getDst().getValue());
int encapVrfId = vxlan.getEncapVrfId().intValue();
int vni = vxlan.getVni().getValue().intValue();
LOG.debug("Setting vxlan tunnel for interface: {}. Vxlan: {}", swIfName, vxlan);
- int ctxId = 0; getVppApi().vxlanAddDelTunnel(
- (byte) 1 /* is add */,
- (byte) 0 /* is ipv6 */,
- srcAddr, dstAddr, encapVrfId, -1, vni);
- final int rv = V3poUtils.waitForResponse(ctxId, getVppApi());
- if (rv < 0) {
+ final CompletionStage<VxlanAddDelTunnelReply> vxlanAddDelTunnelReplyCompletionStage =
+ getFutureJVpp().vxlanAddDelTunnel(getVxlanTunnelRequest((byte) 1 /* is add */, srcAddress.getAddress(),
+ dstAddress.getAddress(), encapVrfId, -1, vni, (byte) 0 /* is IPV6 */));
+
+ final VxlanAddDelTunnelReply reply =
+ V3poUtils.getReply(vxlanAddDelTunnelReplyCompletionStage.toCompletableFuture());
+ if (reply.retval < 0) {
LOG.debug("Failed to set vxlan tunnel for interface: {}, vxlan: {}", swIfName, vxlan);
- throw new VppApiInvocationException("vxlanAddDelTunnel", ctxId, rv);
+ throw new VppApiInvocationException("vxlanAddDelTunnel", reply.context, reply.retval);
} else {
LOG.debug("Vxlan tunnel set successfully for: {}, vxlan: {}", swIfName, vxlan);
- // FIXME avoid this dump just to fill cache in vpp-japi
- // refresh interfaces to be able to get ifIndex
- getVppApi().swInterfaceDump((byte) 1, V3poUtils.IFC_TYPES.inverse().get(VxlanTunnel.class).getBytes());
+ // Add new interface to our interface context
+ interfaceContext.addName(reply.swIfIndex, swIfName);
}
}
+
+ private VxlanAddDelTunnel getVxlanTunnelRequest(final byte isAdd, final byte[] srcAddr, final byte[] dstAddr,
+ final int encapVrfId,
+ final int decapNextIndex, final int vni, final byte isIpv6) {
+ final VxlanAddDelTunnel vxlanAddDelTunnel = new VxlanAddDelTunnel();
+ vxlanAddDelTunnel.isAdd = isAdd;
+ vxlanAddDelTunnel.srcAddress = srcAddr;
+ vxlanAddDelTunnel.dstAddress = dstAddr;
+ vxlanAddDelTunnel.encapVrfId = encapVrfId;
+ vxlanAddDelTunnel.vni = vni;
+ vxlanAddDelTunnel.decapNextIndex = decapNextIndex;
+ vxlanAddDelTunnel.isIpv6 = isIpv6;
+ return vxlanAddDelTunnel;
+ }
}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Interface1Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Interface1Customizer.java
index 9f3584908..e309294ef 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Interface1Customizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Interface1Customizer.java
@@ -19,16 +19,17 @@ package io.fd.honeycomb.v3po.translate.v3po.interfaces.ip;
import com.google.common.base.Optional;
import io.fd.honeycomb.v3po.translate.Context;
import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer;
-import io.fd.honeycomb.v3po.translate.v3po.util.VppApiCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
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.Interface1;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.openvpp.jvpp.future.FutureJVpp;
-public class Interface1Customizer extends VppApiCustomizer implements ChildWriterCustomizer<Interface1> {
+public class Interface1Customizer extends FutureJVppCustomizer implements ChildWriterCustomizer<Interface1> {
- public Interface1Customizer(final org.openvpp.vppjapi.vppApi vppApi) {
+ public Interface1Customizer(final FutureJVpp vppApi) {
super(vppApi);
}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4Customizer.java
index 8349ebb9b..de2015c64 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4Customizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4Customizer.java
@@ -22,10 +22,12 @@ import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.base.Optional;
import io.fd.honeycomb.v3po.translate.Context;
import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer;
-import io.fd.honeycomb.v3po.translate.v3po.util.VppApiCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
+import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException;
import io.fd.honeycomb.v3po.translate.v3po.utils.V3poUtils;
import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
+import java.util.concurrent.CompletionStage;
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.Interface1;
@@ -36,17 +38,23 @@ 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._interface.ipv4.address.subnet.PrefixLength;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.openvpp.jvpp.dto.SwInterfaceAddDelAddress;
+import org.openvpp.jvpp.dto.SwInterfaceAddDelAddressReply;
+import org.openvpp.jvpp.future.FutureJVpp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class Ipv4Customizer extends VppApiCustomizer implements ChildWriterCustomizer<Ipv4> {
+public class Ipv4Customizer extends FutureJVppCustomizer implements ChildWriterCustomizer<Ipv4> {
private static final Logger LOG = LoggerFactory.getLogger(Ipv4Customizer.class);
+ private final NamingContext interfaceContext;
- public Ipv4Customizer(final org.openvpp.vppjapi.vppApi vppApi) {
+ public Ipv4Customizer(final FutureJVpp vppApi, final NamingContext interfaceContext) {
super(vppApi);
+ this.interfaceContext = interfaceContext;
}
+ // TODO replace guava's Optionals with Java8
@Nonnull
@Override
public Optional<Ipv4> extract(@Nonnull final InstanceIdentifier<Ipv4> currentId,
@@ -91,7 +99,7 @@ public class Ipv4Customizer extends VppApiCustomizer implements ChildWriterCusto
private void setIpv4(final InstanceIdentifier<Ipv4> id, final String name, final Ipv4 ipv4)
throws WriteFailedException, VppApiInvocationException {
- final int swIfc = getSwIfc(name);
+ final int swIfc = interfaceContext.getIndex(name);
for (Address ipv4Addr : ipv4.getAddress()) {
Subnet subnet = ipv4Addr.getSubnet();
@@ -127,24 +135,34 @@ public class Ipv4Customizer extends VppApiCustomizer implements ChildWriterCusto
checkArgument(plen > 0, "Invalid length");
checkNotNull(addr, "Null address");
- final int ctxId = getVppApi().swInterfaceAddDelAddress(swIfc, (byte) 1 /* isAdd */, (byte) 0 /* isIpv6 */,
- (byte) 0 /* delAll */, plen.byteValue(), addr);
+ final CompletionStage<SwInterfaceAddDelAddressReply> swInterfaceAddDelAddressReplyCompletionStage =
+ getFutureJVpp().swInterfaceAddDelAddress(getSwInterfaceAddDelAddressRequest(
+ swIfc, (byte) 1 /* isAdd */, (byte) 0 /* isIpv6 */, (byte) 0 /* delAll */, plen.byteValue(), addr));
- final int rv = V3poUtils.waitForResponse(ctxId, getVppApi());
- if (rv < 0) {
+ final SwInterfaceAddDelAddressReply reply =
+ V3poUtils.getReply(swInterfaceAddDelAddressReplyCompletionStage.toCompletableFuture());
+
+ if (reply.retval < 0) {
LOG.warn("Failed to set Subnet(prefix-length) for interface: {}, {}, Subnet: {}, Ipv4: {}", name, swIfc,
subnet, ipv4Addr);
- throw new VppApiInvocationException("swInterfaceAddDelAddress", ctxId, rv);
+ throw new VppApiInvocationException("swInterfaceAddDelAddress", reply.context, reply.retval);
} else {
LOG.debug("Subnet(prefix-length) set successfully for interface: {}, {}, Subnet: {}, Ipv4: {}", name,
swIfc, subnet, ipv4Addr);
}
}
-
- private int getSwIfc(final String name) {
- int swIfcIndex = getVppApi().swIfIndexFromName(name);
- checkArgument(swIfcIndex != -1, "Interface %s does not exist", name);
- return swIfcIndex;
+ private SwInterfaceAddDelAddress getSwInterfaceAddDelAddressRequest(final int swIfc, final byte isAdd, final byte ipv6,
+ final byte deleteAll,
+ final byte length, final byte[] addr) {
+ final SwInterfaceAddDelAddress swInterfaceAddDelAddress = new SwInterfaceAddDelAddress();
+ swInterfaceAddDelAddress.swIfIndex = swIfc;
+ swInterfaceAddDelAddress.isAdd = isAdd;
+ swInterfaceAddDelAddress.isIpv6 = ipv6;
+ swInterfaceAddDelAddress.delAll = deleteAll;
+ swInterfaceAddDelAddress.address = addr;
+ swInterfaceAddDelAddress.addressLength = length;
+ return swInterfaceAddDelAddress;
}
+
}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv6Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv6Customizer.java
index 3798f891a..e3ad3928e 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv6Customizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv6Customizer.java
@@ -19,20 +19,21 @@ package io.fd.honeycomb.v3po.translate.v3po.interfaces.ip;
import com.google.common.base.Optional;
import io.fd.honeycomb.v3po.translate.Context;
import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer;
-import io.fd.honeycomb.v3po.translate.v3po.util.VppApiCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
import javax.annotation.Nonnull;
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.Ipv6;
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;
-public class Ipv6Customizer extends VppApiCustomizer implements ChildWriterCustomizer<Ipv6> {
+public class Ipv6Customizer extends FutureJVppCustomizer implements ChildWriterCustomizer<Ipv6> {
private static final Logger LOG = LoggerFactory.getLogger(Ipv6Customizer.class);
- public Ipv6Customizer(final org.openvpp.vppjapi.vppApi vppApi) {
+ public Ipv6Customizer(final FutureJVpp vppApi) {
super(vppApi);
}
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
index 718cef1b5..f7d473f73 100644
--- 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
@@ -19,6 +19,14 @@ 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 io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
+import io.fd.honeycomb.v3po.translate.v3po.utils.V3poUtils;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Collectors;
+import javax.annotation.Nonnull;
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;
@@ -29,21 +37,23 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.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.openvpp.jvpp.dto.SwInterfaceDetails;
+import org.openvpp.jvpp.dto.SwInterfaceDetailsReplyDump;
+import org.openvpp.jvpp.dto.SwInterfaceDump;
+import org.openvpp.jvpp.future.FutureJVpp;
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
+public class InterfaceCustomizer extends FutureJVppCustomizer
implements ListReaderCustomizer<Interface, InterfaceKey, InterfaceBuilder> {
private static final Logger LOG = LoggerFactory.getLogger(InterfaceCustomizer.class);
+ private final NamingContext interfaceContext;
- public InterfaceCustomizer(org.openvpp.vppjapi.vppApi vppApi) {
- super(vppApi);
+ public InterfaceCustomizer(@Nonnull final FutureJVpp jvpp, final NamingContext interfaceContext) {
+ super(jvpp);
+ this.interfaceContext = interfaceContext;
}
@Override
@@ -54,56 +64,67 @@ public class InterfaceCustomizer extends io.fd.honeycomb.v3po.translate.v3po.uti
@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 SwInterfaceDetails iface;
+ try {
+ iface = InterfaceUtils.getVppInterfaceDetails(getFutureJVpp(), key);
+ } catch (Exception e) {
+ throw new ReadFailedException(id, e);
}
- final vppInterfaceDetails iface = ifaces[0];
- builder.setName(iface.interfaceName);
+ builder.setName(key.getName());
// 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);
+ builder.setIfIndex(InterfaceUtils.vppIfIndexToYang(iface.swIfIndex));
+ builder.setAdminStatus(iface.adminUpDown == 1
+ ? AdminStatus.Up
+ : AdminStatus.Down);
+ builder.setOperStatus(1 == iface.linkUpDown
+ ? 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)));
+ if (iface.l2AddressLength == 6) {
+ builder.setPhysAddress(new PhysAddress(InterfaceUtils.vppPhysAddrToYang(iface.l2Address)));
}
}
+ @Nonnull
@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));
- }
+ public List<InterfaceKey> getAllIds(@Nonnull final InstanceIdentifier<Interface> id,
+ @Nonnull final Context context) throws ReadFailedException {
+ final SwInterfaceDump request = new SwInterfaceDump();
+ request.nameFilter = "".getBytes();
+ request.nameFilterValid = 0;
+
+ final CompletableFuture<SwInterfaceDetailsReplyDump> swInterfaceDetailsReplyDumpCompletableFuture =
+ getFutureJVpp().swInterfaceDump(request).toCompletableFuture();
+ final SwInterfaceDetailsReplyDump ifaces = V3poUtils.getReply(swInterfaceDetailsReplyDumpCompletableFuture);
+
+ // TODO can we get null here?
+ if (null == ifaces || null == ifaces.swInterfaceDetails) {
+ return Collections.emptyList();
}
- return interfaceKeys;
+ return ifaces.swInterfaceDetails.stream()
+ .filter(elt -> elt != null)
+ .map((elt) -> {
+ // Store interface name from VPP in context if not yet present
+ if(!interfaceContext.containsName(elt.swIfIndex)){
+ interfaceContext.addName(elt.swIfIndex, V3poUtils.toString(elt.interfaceName));
+ }
+ return new InterfaceKey(interfaceContext.getName(elt.swIfIndex));
+ })
+ .collect(Collectors.toList());
}
@Override
- public void merge(org.opendaylight.yangtools.concepts.Builder<? extends DataObject> builder,
- List<Interface> readData) {
+ public void merge(@Nonnull final org.opendaylight.yangtools.concepts.Builder<? extends DataObject> builder,
+ @Nonnull final 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
index d589c257f..979c9d6bd 100644
--- 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
@@ -16,15 +16,18 @@
package io.fd.honeycomb.v3po.translate.v3po.interfacesstate;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Iterables;
import java.math.BigInteger;
-
+import java.util.concurrent.ExecutionException;
import javax.annotation.Nonnull;
-
+import javax.annotation.Nullable;
+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.Gauge64;
-
-import com.google.common.base.Preconditions;
-import org.openvpp.vppjapi.vppApi;
-import org.openvpp.vppjapi.vppInterfaceDetails;
+import org.openvpp.jvpp.dto.SwInterfaceDetails;
+import org.openvpp.jvpp.dto.SwInterfaceDetailsReplyDump;
+import org.openvpp.jvpp.dto.SwInterfaceDump;
+import org.openvpp.jvpp.future.FutureJVpp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -42,8 +45,7 @@ public class InterfaceUtils {
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
+ * 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
@@ -74,16 +76,11 @@ public class InterfaceUtils {
}
/**
- * 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/
+ * 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.
+ * @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) {
@@ -102,8 +99,8 @@ public class InterfaceUtils {
}
/**
- * 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.
+ * 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
@@ -115,7 +112,7 @@ public class InterfaceUtils {
/**
* This function does the opposite of what {@link #vppIfIndexToYang(int)} does.
*
- * @param yangIf if-index from ietf-interfaces.
+ * @param yangIfIndex if-index from ietf-interfaces.
* @return VPP's representation of the if-index
*/
public static int YangIfIndexToVpp(int yangIfIndex) {
@@ -124,25 +121,31 @@ public class InterfaceUtils {
}
- 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);
+ /**
+ * Queries VPP for interface description given interface key.
+ *
+ * @param futureJvpp VPP Java Future API
+ * @param key interface key
+ * @return SwInterfaceDetails DTO or null if interface was not found
+ * @throws ExecutionException if exception has been thrown while executing VPP query
+ * @throws InterruptedException if the current thread was interrupted
+ */
+ @Nullable
+ public static SwInterfaceDetails getVppInterfaceDetails(@Nonnull final FutureJVpp futureJvpp,
+ @Nonnull InterfaceKey key)
+ throws ExecutionException, InterruptedException {
+ final SwInterfaceDump request = new SwInterfaceDump();
+ request.nameFilter = key.getName().getBytes();
+ request.nameFilterValid = 1;
+
+ // TODO should we use timeout?
+ SwInterfaceDetailsReplyDump ifaces = futureJvpp.swInterfaceDump(request).toCompletableFuture().get();
+ if (null == ifaces) { // TODO can we get null here?
+ LOG.warn("VPP returned null instead of interface by key {}", key.getName().getBytes());
return null;
}
- if (1 != ifaces.length) {
- LOG.error("Failed to extract interface {} details from VPP", interfaceName);
- }
-
- return ifaces;
+ return Iterables.getOnlyElement(ifaces.swInterfaceDetails);
}
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
index 8e5cc8932..2bc8beaaa 100644
--- 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
@@ -16,11 +16,10 @@
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 io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
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;
@@ -32,28 +31,31 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev
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.openvpp.jvpp.dto.SwInterfaceDetails;
+import org.openvpp.jvpp.future.FutureJVpp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class VppInterfaceStateCustomizer extends io.fd.honeycomb.v3po.translate.v3po.util.VppApiCustomizer
+public class VppInterfaceStateCustomizer extends FutureJVppCustomizer
implements ChildReaderCustomizer<VppInterfaceStateAugmentation, VppInterfaceStateAugmentationBuilder> {
private static final Logger LOG = LoggerFactory.getLogger(VppInterfaceStateCustomizer.class);
- public VppInterfaceStateCustomizer(org.openvpp.vppjapi.vppApi vppApi) {
- super(vppApi);
+ public VppInterfaceStateCustomizer(@Nonnull final FutureJVpp jvpp) {
+ super(jvpp);
}
@Override
- public void merge(@Nonnull Builder<? extends DataObject> parentBuilder, @Nonnull VppInterfaceStateAugmentation readValue) {
+ 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) {
+ public VppInterfaceStateAugmentationBuilder getBuilder(
+ @Nonnull InstanceIdentifier<VppInterfaceStateAugmentation> id) {
return new VppInterfaceStateAugmentationBuilder();
}
@@ -63,15 +65,15 @@ public class VppInterfaceStateCustomizer extends io.fd.honeycomb.v3po.translate.
@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 SwInterfaceDetails iface;
+ try {
+ iface = InterfaceUtils.getVppInterfaceDetails(getFutureJVpp(), key);
+ } catch (Exception e) {
+ throw new ReadFailedException(id, e);
}
- final vppInterfaceDetails iface = ifaces[0];
final EthernetBuilder ethernet = new EthernetBuilder();
-
- ethernet.setMtu(iface.linkMtu);
+ ethernet.setMtu((int) iface.linkMtu);
switch (iface.linkDuplex) {
case 1:
ethernet.setDuplex(Ethernet.Duplex.Half);
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/utils/V3poUtils.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/utils/V3poUtils.java
index 88626453e..b4217df46 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/utils/V3poUtils.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/utils/V3poUtils.java
@@ -16,18 +16,17 @@
package io.fd.honeycomb.v3po.translate.v3po.utils;
-import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
-import javax.annotation.Nonnull;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
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.iana._if.type.rev140508.SoftwareLoopback;
-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.InterfaceType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanTunnel;
-import org.openvpp.vppjapi.vppApi;
+import org.openvpp.jvpp.dto.JVppReply;
public final class V3poUtils {
@@ -48,25 +47,17 @@ public final class V3poUtils {
private V3poUtils() {}
- public static int waitForResponse(final int ctxId, final vppApi vppApi) {
- int rv;
- while ((rv = vppApi.getRetval(ctxId, RELEASE)) == RESPONSE_NOT_READY) {
- // TODO limit attempts
+ public static <REP extends JVppReply<?>> REP getReply(Future<REP> future) {
+ try {
+ return future.get();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new IllegalStateException("Interrupted", e);
+ } catch (ExecutionException e) {
+ // Execution exception should not occur, since we are using return codes for errors
+ // TODO fix when using exceptions instead of return codes
+ throw new IllegalArgumentException("Future " + " should not fail with an exception", e);
}
- return rv;
- }
-
- public static int parseIp(final String address) {
- int result = 0;
-
- // iterate over each octet
- for (String part : DOT_SPLITTER.split(address)) {
- // shift the previously parsed bits over by 1 byte
- result = result << 8;
- // set the low order bits to the current octet
- result |= Integer.parseInt(part);
- }
- return result;
}
public static byte[] ipv4AddressNoZoneToArray(final Ipv4AddressNoZone ipv4Addr) {
@@ -80,22 +71,10 @@ public final class V3poUtils {
}
/**
- * Removes zone index from Ipv4Address.
- * @param ipv4Addr ipv4 address which can contain zone index
- * @return ipv4 address without zone index
+ * Return (interned) string from byte array while removing \u0000.
+ * Strings represented as fixed length byte[] from vpp contain \u0000.
*/
- @Nonnull
- public static Ipv4AddressNoZone removeIpv4AddressNoZone(@Nonnull final Ipv4Address ipv4Addr) {
- Preconditions.checkNotNull(ipv4Addr, "ipv4Addr should not be null");
- if (ipv4Addr instanceof Ipv4AddressNoZone) {
- return (Ipv4AddressNoZone)ipv4Addr;
- } else {
- String value = ipv4Addr.getValue();
- final int index = value.indexOf('%');
- if (index != -1) {
- value = value.substring(0, index);
- }
- return new Ipv4AddressNoZone(value);
- }
+ public static String toString(final byte[] cString) {
+ return new String(cString).replaceAll("\\u0000", "").intern();
}
}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainCustomizer.java
index c69f2ef0a..4b4d7b3c1 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainCustomizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainCustomizer.java
@@ -18,12 +18,15 @@ package io.fd.honeycomb.v3po.translate.v3po.vpp;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
-import io.fd.honeycomb.v3po.translate.spi.write.ListWriterCustomizer;
-import io.fd.honeycomb.v3po.translate.v3po.util.VppApiCustomizer;
+import com.google.common.base.Preconditions;
import io.fd.honeycomb.v3po.translate.Context;
+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.VppApiInvocationException;
import io.fd.honeycomb.v3po.translate.v3po.utils.V3poUtils;
+import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
import java.util.List;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -32,19 +35,24 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomainKey;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.openvpp.jvpp.dto.BridgeDomainAddDel;
+import org.openvpp.jvpp.dto.BridgeDomainAddDelReply;
+import org.openvpp.jvpp.future.FutureJVpp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class BridgeDomainCustomizer
- extends VppApiCustomizer
- implements ListWriterCustomizer<BridgeDomain, BridgeDomainKey> {
+ extends FutureJVppCustomizer
+ implements ListWriterCustomizer<BridgeDomain, BridgeDomainKey> {
private static final Logger LOG = LoggerFactory.getLogger(BridgeDomainCustomizer.class);
private static final byte ADD_OR_UPDATE_BD = (byte) 1;
+ private final NamingContext bdContext;
- public BridgeDomainCustomizer(final org.openvpp.vppjapi.vppApi api) {
- super(api);
+ public BridgeDomainCustomizer(@Nonnull final FutureJVpp futureJvpp, @Nonnull final NamingContext bdContext) {
+ super(futureJvpp);
+ this.bdContext = Preconditions.checkNotNull(bdContext, "bdContext should not be null");
}
@Nonnull
@@ -54,76 +62,96 @@ public class BridgeDomainCustomizer
return ((BridgeDomains) parentData).getBridgeDomain();
}
- private int addOrUpdateBridgeDomain(final int bdId, @Nonnull final BridgeDomain bd) {
- byte flood = booleanToByte(bd.isFlood());
- byte forward = booleanToByte(bd.isForward());
- byte learn = booleanToByte(bd.isLearn());
- byte uuf = booleanToByte(bd.isUnknownUnicastFlood());
- byte arpTerm = booleanToByte(bd.isArpTermination());
-
- int ctxId = getVppApi().bridgeDomainAddDel(bdId, flood, forward, learn, uuf, arpTerm, ADD_OR_UPDATE_BD);
- return V3poUtils.waitForResponse(ctxId, getVppApi());
+ private BridgeDomainAddDelReply addOrUpdateBridgeDomain(final int bdId, @Nonnull final BridgeDomain bd)
+ throws VppApiInvocationException {
+ final BridgeDomainAddDel request = new BridgeDomainAddDel();
+ request.bdId = bdId;
+ request.flood = booleanToByte(bd.isFlood());
+ request.forward = booleanToByte(bd.isForward());
+ request.learn = booleanToByte(bd.isLearn());
+ request.uuFlood = booleanToByte(bd.isUnknownUnicastFlood());
+ request.arpTerm = booleanToByte(bd.isArpTermination());
+ request.isAdd = ADD_OR_UPDATE_BD;
+
+ final BridgeDomainAddDelReply reply =
+ V3poUtils.getReply(getFutureJVpp().bridgeDomainAddDel(request).toCompletableFuture());
+ if (reply.retval < 0) {
+ LOG.warn("Bridge domain {} (id={}) add/update failed", bd.getName(), bdId);
+ throw new VppApiInvocationException("bridgeDomainAddDel", reply.context, reply.retval);
+ } else {
+ LOG.debug("Bridge domain {} (id={}) add/update successful", bd.getName(), bdId);
+ }
+
+ return reply;
}
@Override
public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<BridgeDomain> id,
- @Nonnull final BridgeDomain current,
- @Nonnull final Context ctx) {
- LOG.debug("writeCurrentAttributes: id={}, current={}, ctx={}", id, current, ctx);
- final String bdName = current.getName();
- int bdId = getVppApi().findOrAddBridgeDomainId(bdName);
- checkState(bdId > 0, "Unable to find or create bridge domain. Return code: %s", bdId);
-
- int rv = addOrUpdateBridgeDomain(bdId, current);
-
- checkState(rv >= 0, "Bridge domain %s(%s) write failed. Return code: %s", bdName, bdId, rv);
- LOG.debug("Bridge domain {} written as {} successfully", bdName, bdId);
+ @Nonnull final BridgeDomain dataBefore,
+ @Nonnull final Context ctx) throws WriteFailedException.CreateFailedException {
+ LOG.debug("writeCurrentAttributes: id={}, current={}, ctx={}", id, dataBefore, ctx);
+ final String bdName = dataBefore.getName();
+
+ try {
+ // FIXME we need the bd index to be returned by VPP or we should have a counter field (maybe in context similar to artificial name)
+ // Here we assign the next available ID from bdContext's perspective
+ int index = 1;
+ while(bdContext.containsName(index)) {
+ index++;
+ }
+ addOrUpdateBridgeDomain(index, dataBefore);
+ bdContext.addName(index, bdName);
+ } catch (VppApiInvocationException e) {
+ LOG.warn("Failed to create bridge domain", e);
+ throw new WriteFailedException.CreateFailedException(id, dataBefore, e);
+ }
}
private byte booleanToByte(@Nullable final Boolean aBoolean) {
- return aBoolean != null && aBoolean ? (byte) 1 : (byte) 0;
+ return aBoolean != null && aBoolean
+ ? (byte) 1
+ : (byte) 0;
}
@Override
public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<BridgeDomain> id,
@Nonnull final BridgeDomain dataBefore,
- @Nonnull final Context ctx) {
+ @Nonnull final Context ctx) throws WriteFailedException.DeleteFailedException {
LOG.debug("deleteCurrentAttributes: id={}, dataBefore={}, ctx={}", id, dataBefore, ctx);
- String bdName = id.firstKeyOf(BridgeDomain.class).getName();
-
- int bdId = getVppApi().bridgeDomainIdFromName(bdName);
- checkState(bdId > 0, "Unable to delete bridge domain. Does not exist. Return code: %s", bdId);
- int ctxId = getVppApi().bridgeDomainAddDel(bdId,
- (byte) 0 /* flood */,
- (byte) 0 /* forward */,
- (byte) 0 /* learn */,
- (byte) 0 /* uuf */,
- (byte) 0 /* arpTerm */,
- (byte) 0 /* isAdd */);
-
- int rv = V3poUtils.waitForResponse(ctxId, getVppApi());
-
- checkState(rv >= 0, "Bridge domain delete failed. Return code: %s", rv);
- LOG.debug("Bridge domain {} deleted as {} successfully", bdName, bdId);
+ final String bdName = id.firstKeyOf(BridgeDomain.class).getName();
+ int bdId = bdContext.getIndex(bdName);
+ final BridgeDomainAddDel request = new BridgeDomainAddDel();
+ request.bdId = bdId;
+
+ final BridgeDomainAddDelReply reply =
+ V3poUtils.getReply(getFutureJVpp().bridgeDomainAddDel(request).toCompletableFuture());
+ if (reply.retval < 0) {
+ LOG.warn("Bridge domain {} (id={}) delete failed", bdName, bdId);
+ throw new WriteFailedException.DeleteFailedException(id,
+ new VppApiInvocationException("bridgeDomainAddDel", reply.context, reply.retval));
+ } else {
+ LOG.debug("Bridge domain {} (id={}) deleted successfully", bdName, bdId);
+ }
}
@Override
public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<BridgeDomain> id,
@Nonnull final BridgeDomain dataBefore, @Nonnull final BridgeDomain dataAfter,
- @Nonnull final Context ctx) {
- LOG.debug("updateCurrentAttributes: id={}, dataBefore={}, dataAfter={}, ctx={}", id, dataBefore, dataAfter, ctx);
+ @Nonnull final Context ctx) throws WriteFailedException.UpdateFailedException {
+ LOG.debug("updateCurrentAttributes: id={}, dataBefore={}, dataAfter={}, ctx={}", id, dataBefore, dataAfter,
+ ctx);
final String bdName = checkNotNull(dataAfter.getName());
- checkArgument(bdName.equals(dataBefore.getName()), "BridgeDomain name changed. It should be deleted and then created.");
-
- int bdId = getVppApi().bridgeDomainIdFromName(bdName);
- checkState(bdId > 0, "Unable to find bridge domain. Return code: %s", bdId);
-
- final int rv = addOrUpdateBridgeDomain(bdId, dataAfter);
-
- checkState(rv >= 0, "Bridge domain %s(%s) update failed. Return code: %s", bdName, bdId, rv);
- LOG.debug("Bridge domain {}({}) updated successfully", bdName, bdId);
+ checkArgument(bdName.equals(dataBefore.getName()),
+ "BridgeDomain name changed. It should be deleted and then created.");
+
+ try {
+ addOrUpdateBridgeDomain(bdContext.getIndex(bdName), dataAfter);
+ } catch (VppApiInvocationException e) {
+ LOG.warn("Failed to create bridge domain", e);
+ throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, e);
+ }
}
}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/BridgeDomainCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/BridgeDomainCustomizer.java
index 61c345b44..addb425f6 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/BridgeDomainCustomizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/BridgeDomainCustomizer.java
@@ -16,10 +16,15 @@
package io.fd.honeycomb.v3po.translate.v3po.vppstate;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
-import io.fd.honeycomb.v3po.translate.spi.read.ListReaderCustomizer;
-import io.fd.honeycomb.v3po.translate.v3po.util.VppApiCustomizer;
+import com.google.common.primitives.Longs;
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 io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -34,104 +39,150 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.bridge.domain.InterfaceKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.bridge.domain.L2Fib;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.bridge.domain.L2FibBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.bridge.domain.L2FibKey;
import org.opendaylight.yangtools.concepts.Builder;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.openvpp.vppjapi.vppBridgeDomainDetails;
-import org.openvpp.vppjapi.vppBridgeDomainInterfaceDetails;
-import org.openvpp.vppjapi.vppL2Fib;
+import org.openvpp.jvpp.dto.BridgeDomainDetails;
+import org.openvpp.jvpp.dto.BridgeDomainDetailsReplyDump;
+import org.openvpp.jvpp.dto.BridgeDomainDump;
+import org.openvpp.jvpp.dto.BridgeDomainSwIfDetails;
+import org.openvpp.jvpp.dto.L2FibTableDump;
+import org.openvpp.jvpp.dto.L2FibTableEntry;
+import org.openvpp.jvpp.dto.L2FibTableEntryReplyDump;
+import org.openvpp.jvpp.future.FutureJVpp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public final class BridgeDomainCustomizer extends VppApiCustomizer
- implements ListReaderCustomizer<BridgeDomain, BridgeDomainKey, BridgeDomainBuilder> {
+public final class BridgeDomainCustomizer extends FutureJVppCustomizer
+ implements ListReaderCustomizer<BridgeDomain, BridgeDomainKey, BridgeDomainBuilder> {
private static final Logger LOG = LoggerFactory.getLogger(BridgeDomainCustomizer.class);
-
- public BridgeDomainCustomizer(@Nonnull final org.openvpp.vppjapi.vppApi vppApi) {
- super(vppApi);
+ private final NamingContext bdContext;
+ private final NamingContext interfaceContext;
+
+ public BridgeDomainCustomizer(@Nonnull final FutureJVpp futureJVpp, @Nonnull final NamingContext bdContext,
+ @Nonnull final NamingContext interfaceContext) {
+ super(futureJVpp);
+ this.bdContext = Preconditions.checkNotNull(bdContext, "bdContext should not be null");
+ this.interfaceContext = Preconditions.checkNotNull(interfaceContext, "interfaceContext should not be null");;
}
@Override
public void readCurrentAttributes(@Nonnull final InstanceIdentifier<BridgeDomain> id,
- @Nonnull final BridgeDomainBuilder builder, @Nonnull final Context context) {
+ @Nonnull final BridgeDomainBuilder builder, @Nonnull final Context context)
+ throws ReadFailedException {
LOG.debug("vppstate.BridgeDomainCustomizer.readCurrentAttributes: id={}, builderbuilder={}, context={}",
id, builder, context);
final BridgeDomainKey key = id.firstKeyOf(id.getTargetType());
LOG.debug("vppstate.BridgeDomainCustomizer.readCurrentAttributes: key={}", key);
- final int bdId = getVppApi().bridgeDomainIdFromName(key.getName());
+ final int bdId = bdContext.getIndex(key.getName());
LOG.debug("vppstate.BridgeDomainCustomizer.readCurrentAttributes: bdId={}", bdId);
- final vppBridgeDomainDetails bridgeDomainDetails = getVppApi().getBridgeDomainDetails(bdId);
- if(bridgeDomainDetails == null) {
- LOG.debug("Bridge domain name={} does not exist", key.getName());
+ BridgeDomainDetailsReplyDump reply;
+ BridgeDomainDetails bridgeDomainDetails;
+ final BridgeDomainDump request = new BridgeDomainDump();
+ request.bdId = bdContext.getIndex(key.getName());
+ try {
+ reply = getFutureJVpp().bridgeDomainDump(request).toCompletableFuture().get();
+ bridgeDomainDetails = Iterables.getOnlyElement(reply.bridgeDomainDetails);
+ } catch (Exception e) {
+ LOG.debug("Unable to read bridge domain: {}", key.getName(), e);
return;
}
+
logBridgeDomainDetails(bridgeDomainDetails);
builder.setName(key.getName());
- // builder.setName(bridgeDomainDetails.name);
- builder.setArpTermination(bridgeDomainDetails.arpTerm);
- builder.setFlood(bridgeDomainDetails.flood);
- builder.setForward(bridgeDomainDetails.forward);
- builder.setLearn(bridgeDomainDetails.learn);
- builder.setUnknownUnicastFlood(bridgeDomainDetails.uuFlood);
-
- builder.setInterface(getIfcs(bridgeDomainDetails));
-
- final vppL2Fib[] vppL2Fibs = getVppApi().l2FibTableDump(bdId);
-
- final List<L2Fib> l2Fibs = Lists.newArrayListWithCapacity(vppL2Fibs.length);
- for (vppL2Fib vppL2Fib : vppL2Fibs) {
- l2Fibs.add(new L2FibBuilder()
- .setAction((vppL2Fib.filter
- ? L2Fib.Action.Filter
- : L2Fib.Action.Forward))
- .setBridgedVirtualInterface(vppL2Fib.bridgedVirtualInterface)
- .setOutgoingInterface(vppL2Fib.outgoingInterface)
- .setPhysAddress(new PhysAddress(getMacAddress(vppL2Fib.physAddress)))
- .setStaticConfig(vppL2Fib.staticConfig)
- .build());
+ builder.setArpTermination(byteToBoolean(bridgeDomainDetails.arpTerm));
+ builder.setFlood(byteToBoolean(bridgeDomainDetails.flood));
+ builder.setForward(byteToBoolean(bridgeDomainDetails.forward));
+ builder.setLearn(byteToBoolean(bridgeDomainDetails.learn));
+ builder.setUnknownUnicastFlood(byteToBoolean(bridgeDomainDetails.uuFlood));
+
+ builder.setInterface(getIfcs(bridgeDomainDetails, reply.bridgeDomainSwIfDetails));
+
+ final L2FibTableDump l2FibRequest = new L2FibTableDump();
+ l2FibRequest.bdId = bdId;
+ try {
+ final L2FibTableEntryReplyDump dump =
+ getFutureJVpp().l2FibTableDump(l2FibRequest).toCompletableFuture().get();
+ final List<L2Fib> l2Fibs = Lists.newArrayListWithCapacity(dump.l2FibTableEntry.size());
+ for (L2FibTableEntry entry : dump.l2FibTableEntry) {
+ // entry.mac is a long value in the format 66:55:44:33:22:11:XX:XX
+ // where mac address is 11:22:33:44:55:66
+ final PhysAddress address = new PhysAddress(getMacAddress(Longs.toByteArray(entry.mac)));
+ l2Fibs.add(new L2FibBuilder()
+ .setAction((byteToBoolean(entry.filterMac)
+ ? L2Fib.Action.Filter
+ : L2Fib.Action.Forward))
+ .setBridgedVirtualInterface(byteToBoolean(entry.bviMac))
+ .setOutgoingInterface(interfaceContext.getName(entry.swIfIndex))
+ .setStaticConfig(byteToBoolean(entry.staticMac))
+ .setPhysAddress(address)
+ .setKey(new L2FibKey(address))
+ .build());
+ }
+ builder.setL2Fib(l2Fibs);
+
+ } catch (Exception e) {
+ LOG.warn("Failed to acquire l2FibTableDump for domain id={}", bdId, e);
+ }
+ }
+
+ // TODO move to utils
+ private static Boolean byteToBoolean(final byte aByte) {
+ if (aByte == 0) {
+ return Boolean.FALSE;
+ } else if (aByte == 1) {
+ return Boolean.TRUE;
}
- builder.setL2Fib(l2Fibs);
+ throw new IllegalArgumentException(String.format("0 or 1 was expected but was %d", aByte));
}
- private void logBridgeDomainDetails(final vppBridgeDomainDetails bridgeDomainDetails) {
+ private void logBridgeDomainDetails(final BridgeDomainDetails bridgeDomainDetails) {
LOG.debug("bridgeDomainDetails={}", bridgeDomainDetails);
if (bridgeDomainDetails != null) {
LOG.debug("bridgeDomainDetails.arpTerm={}", bridgeDomainDetails.arpTerm);
LOG.debug("bridgeDomainDetails.bdId={}", bridgeDomainDetails.bdId);
- LOG.debug("bridgeDomainDetails.bviInterfaceName={}", bridgeDomainDetails.bviInterfaceName);
+ LOG.debug("bridgeDomainDetails.bviSwIfIndex={}", bridgeDomainDetails.bviSwIfIndex);
LOG.debug("bridgeDomainDetails.flood={}", bridgeDomainDetails.flood);
LOG.debug("bridgeDomainDetails.forward={}", bridgeDomainDetails.forward);
LOG.debug("bridgeDomainDetails.learn={}", bridgeDomainDetails.learn);
- LOG.debug("bridgeDomainDetails.name={}", bridgeDomainDetails.name);
+ LOG.debug("bridgeDomainDetails.nSwIfs={}", bridgeDomainDetails.nSwIfs);
LOG.debug("bridgeDomainDetails.uuFlood={}", bridgeDomainDetails.uuFlood);
}
}
-
+ // TODO move to some utility class
private static String getMacAddress(byte[] mac) {
StringBuilder sb = new StringBuilder(18);
- for (byte b : mac) {
+ for (int i=5; i>=0; --i) {
if (sb.length() > 0) {
sb.append(':');
}
- sb.append(String.format("%02x", b));
+ sb.append(String.format("%02x", mac[i]));
}
return sb.toString();
}
- private List<Interface> getIfcs(final vppBridgeDomainDetails bridgeDomainDetails) {
- final List<Interface> ifcs = new ArrayList<>(bridgeDomainDetails.interfaces.length);
- for (vppBridgeDomainInterfaceDetails anInterface : bridgeDomainDetails.interfaces) {
- ifcs.add(new InterfaceBuilder()
- .setBridgedVirtualInterface(bridgeDomainDetails.bviInterfaceName.equals(anInterface.interfaceName))
- .setName(anInterface.interfaceName)
- .setKey(new InterfaceKey(anInterface.interfaceName))
- .build());
+ private List<Interface> getIfcs(final BridgeDomainDetails bridgeDomainDetails,
+ final List<BridgeDomainSwIfDetails> bridgeDomainSwIfDetails) {
+ final List<Interface> ifcs = new ArrayList<>(bridgeDomainSwIfDetails.size());
+ for (BridgeDomainSwIfDetails anInterface : bridgeDomainSwIfDetails) {
+ final String interfaceName = interfaceContext.getName(anInterface.swIfIndex);
+ if (anInterface.bdId == bridgeDomainDetails.bdId) {
+ ifcs.add(new InterfaceBuilder()
+ .setBridgedVirtualInterface(bridgeDomainDetails.bviSwIfIndex == anInterface.swIfIndex)
+ .setSplitHorizonGroup((short) anInterface.shg)
+ .setName(interfaceName)
+ .setKey(new InterfaceKey(interfaceName))
+ .build());
+ }
+
+
}
return ifcs;
}
@@ -144,25 +195,34 @@ public final class BridgeDomainCustomizer extends VppApiCustomizer
@Nonnull
@Override
- public List<BridgeDomainKey> getAllIds(@Nonnull final InstanceIdentifier<BridgeDomain> id, @Nonnull final Context context) {
- final int[] bIds = getVppApi().bridgeDomainDump(-1);
+ public List<BridgeDomainKey> getAllIds(@Nonnull final InstanceIdentifier<BridgeDomain> id,
+ @Nonnull final Context context) {
+ final BridgeDomainDump request = new BridgeDomainDump();
+ request.bdId = -1; // dump call
+
+ BridgeDomainDetailsReplyDump reply;
+ try {
+ reply = getFutureJVpp().bridgeDomainDump(request).toCompletableFuture().get();
+ } catch (Exception e) {
+ throw new IllegalStateException("Bridge domain dump failed", e); // TODO ReadFailedException?
+ }
- if(bIds == null) {
+ if(reply == null || reply.bridgeDomainDetails == null) {
+ return Collections.emptyList();
+ }
+
+ final int bIdsLength = reply.bridgeDomainDetails.size();
+ LOG.debug("vppstate.BridgeDomainCustomizer.getAllIds: bIds.length={}", bIdsLength);
+ if (bIdsLength == 0) {
// No bridge domains
return Collections.emptyList();
}
- LOG.debug("vppstate.BridgeDomainCustomizer.getAllIds: bIds.length={}", bIds.length);
- final List<BridgeDomainKey> allIds = new ArrayList<>(bIds.length);
- for (int bId : bIds) {
- LOG.debug("vppstate.BridgeDomainCustomizer.getAllIds: bId={}", bId);
- // FIXME this is highly inefficient having to dump all of the bridge domain details
- // Use context to store already read information
- // TODO Or just remove the getAllIds method and replace with a simple readAll
- final vppBridgeDomainDetails bridgeDomainDetails = getVppApi().getBridgeDomainDetails(bId);
- logBridgeDomainDetails(bridgeDomainDetails);
-
- final String bName = bridgeDomainDetails.name;
+ final List<BridgeDomainKey> allIds = new ArrayList<>(bIdsLength);
+ for (BridgeDomainDetails detail : reply.bridgeDomainDetails) {
+ logBridgeDomainDetails(detail);
+
+ final String bName = bdContext.getName(detail.bdId);
LOG.debug("vppstate.BridgeDomainCustomizer.getAllIds: bName={}", bName);
allIds.add(new BridgeDomainKey(bName));
}
@@ -171,7 +231,8 @@ public final class BridgeDomainCustomizer extends VppApiCustomizer
}
@Override
- public void merge(@Nonnull final Builder<? extends DataObject> builder, @Nonnull final List<BridgeDomain> readData) {
+ public void merge(@Nonnull final Builder<? extends DataObject> builder,
+ @Nonnull final List<BridgeDomain> readData) {
((BridgeDomainsBuilder) builder).setBridgeDomain(readData);
}
}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VersionCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VersionCustomizer.java
index 31e3166bb..1db8217f9 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VersionCustomizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VersionCustomizer.java
@@ -17,8 +17,10 @@
package io.fd.honeycomb.v3po.translate.v3po.vppstate;
import io.fd.honeycomb.v3po.translate.Context;
-import io.fd.honeycomb.v3po.translate.v3po.util.VppApiCustomizer;
+import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.utils.V3poUtils;
import javax.annotation.Nonnull;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppStateBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.Version;
@@ -26,14 +28,16 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev
import org.opendaylight.yangtools.concepts.Builder;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.openvpp.vppjapi.vppVersion;
+import org.openvpp.jvpp.dto.ShowVersion;
+import org.openvpp.jvpp.dto.ShowVersionReply;
+import org.openvpp.jvpp.future.FutureJVpp;
public final class VersionCustomizer
- extends VppApiCustomizer
+ extends FutureJVppCustomizer
implements ChildReaderCustomizer<Version, VersionBuilder> {
- public VersionCustomizer(@Nonnull final org.openvpp.vppjapi.vppApi vppApi) {
- super(vppApi);
+ public VersionCustomizer(@Nonnull final FutureJVpp futureJVpp) {
+ super(futureJVpp);
}
@Override
@@ -49,11 +53,18 @@ public final class VersionCustomizer
@Override
public void readCurrentAttributes(@Nonnull InstanceIdentifier<Version> id, @Nonnull final VersionBuilder builder,
- @Nonnull final Context context) {
- final vppVersion vppVersion = getVppApi().getVppVersion();
- builder.setBranch(vppVersion.gitBranch);
- builder.setName(vppVersion.programName);
- builder.setBuildDate(vppVersion.buildDate);
- builder.setBuildDirectory(vppVersion.buildDirectory);
+ @Nonnull final Context context) throws ReadFailedException {
+
+ ShowVersionReply reply;
+ try {
+ reply = getFutureJVpp().showVersion(new ShowVersion()).toCompletableFuture().get();
+ } catch (Exception e) {
+ throw new ReadFailedException(id, e);
+ }
+ builder.setBranch(V3poUtils.toString(reply.version));
+ builder.setName(V3poUtils.toString(reply.program));
+ builder.setBuildDate(V3poUtils.toString(reply.buildDate));
+ builder.setBuildDirectory(V3poUtils.toString(reply.buildDirectory));
}
+
}
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 e906167fd..769589b3d 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
@@ -54,9 +54,9 @@ public class InterfacesHoneycombWriterModule extends org.opendaylight.yang.gen.v
ifcAugmentations.add(getInterface1AugmentationWriter());
final ChildWriter<Interface> interfaceWriter = new CompositeListWriter<>(Interface.class,
- RWUtils.<Interface>emptyChildWriterList(),
+ RWUtils.emptyChildWriterList(),
ifcAugmentations,
- new InterfaceCustomizer(getVppJapiIfcDependency()),
+ new InterfaceCustomizer(getVppJvppIfcDependency(), getInterfaceContextDependency()),
// It's important that this customizer is handled in a postorder way, because you first have to handle child nodes
// e.g. Vxlan before setting other interface or vppInterfaceAugmentation leaves
TraversalType.POSTORDER);
@@ -68,36 +68,36 @@ public class InterfacesHoneycombWriterModule extends org.opendaylight.yang.gen.v
// we loose the ordering information for root writers
// Or can we rely to the order in which readers are configured ?
return new CloseableWriter<>(new CompositeRootWriter<>(Interfaces.class,
- childWriters, new NoopWriterCustomizer<Interfaces>()));
+ childWriters, new NoopWriterCustomizer<>()));
}
private ChildWriter<? extends Augmentation<Interface>> getInterface1AugmentationWriter() {
final ChildWriter<Ipv4> ipv4Writer = new CompositeChildWriter<>(Ipv4.class,
- new Ipv4Customizer(getVppJapiIfcDependency()));
+ new Ipv4Customizer(getVppJvppIfcDependency(), getInterfaceContextDependency()));
final ChildWriter<Ipv6> ipv6Writer = new CompositeChildWriter<>(Ipv6.class,
- new Ipv6Customizer(getVppJapiIfcDependency()));
+ new Ipv6Customizer(getVppJvppIfcDependency()));
final List<ChildWriter<? extends ChildOf<Interface1>>> interface1ChildWriters = Lists.newArrayList();
interface1ChildWriters.add(ipv4Writer);
interface1ChildWriters.add(ipv6Writer);
return new CompositeChildWriter<>(Interface1.class,
- interface1ChildWriters, new ReflexiveAugmentWriterCustomizer<Interface1>());
+ interface1ChildWriters, new ReflexiveAugmentWriterCustomizer<>());
}
private ChildWriter<VppInterfaceAugmentation> getVppIfcAugmentationWriter() {
final ChildWriter<Ethernet> ethernetWriter = new CompositeChildWriter<>(Ethernet.class,
- new EthernetCustomizer(getVppJapiIfcDependency()));
+ new EthernetCustomizer(getVppJvppIfcDependency()));
final ChildWriter<Routing> routingWriter = new CompositeChildWriter<>(Routing.class,
- new RoutingCustomizer(getVppJapiIfcDependency()));
+ new RoutingCustomizer(getVppJvppIfcDependency(), getInterfaceContextDependency()));
final ChildWriter<Vxlan> vxlanWriter = new CompositeChildWriter<>(Vxlan.class,
- new VxlanCustomizer(getVppJapiIfcDependency()));
+ new VxlanCustomizer(getVppJvppIfcDependency(), getInterfaceContextDependency()));
final ChildWriter<L2> l2Writer = new CompositeChildWriter<>(L2.class,
- new L2Customizer(getVppJapiIfcDependency()));
+ new L2Customizer(getVppJvppIfcDependency(), getInterfaceContextDependency(), getBridgeDomainContextDependency()));
final List<ChildWriter<? extends ChildOf<VppInterfaceAugmentation>>> vppIfcChildWriters = Lists.newArrayList();
// TODO what's the order here ?
@@ -108,7 +108,7 @@ public class InterfacesHoneycombWriterModule extends org.opendaylight.yang.gen.v
return new CompositeChildWriter<>(VppInterfaceAugmentation.class,
vppIfcChildWriters,
- RWUtils.<VppInterfaceAugmentation>emptyAugWriterList(),
- new ReflexiveAugmentWriterCustomizer<VppInterfaceAugmentation>());
+ RWUtils.emptyAugWriterList(),
+ new ReflexiveAugmentWriterCustomizer<>());
}
}
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 aa72a29af..e753cf56e 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
@@ -1,10 +1,15 @@
package org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.v3po2vpp.rev160406;
+
+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.singletonAugReaderList;
+import static io.fd.honeycomb.v3po.translate.util.RWUtils.singletonChildReaderList;
+
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.util.RWUtils;
import io.fd.honeycomb.v3po.translate.util.read.CloseableReader;
import io.fd.honeycomb.v3po.translate.util.read.ReflexiveRootReaderCustomizer;
import io.fd.honeycomb.v3po.translate.v3po.interfacesstate.InterfaceCustomizer;
@@ -15,14 +20,18 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.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.openvpp.vppjapi.vppApi;
-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) {
+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) {
+ 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);
}
@@ -33,22 +42,22 @@ public class InterfacesStateHoneycombReaderModule extends org.opendaylight.yang.
@Override
public java.lang.AutoCloseable createInstance() {
- final vppApi vppApi = getVppJapiDependency();
final ChildReader<VppInterfaceStateAugmentation> vppInterfaceStateAugmentationChildReader =
- new CompositeChildReader<>(VppInterfaceStateAugmentation.class,
- new VppInterfaceStateCustomizer(vppApi));
+ new CompositeChildReader<>(VppInterfaceStateAugmentation.class,
+ new VppInterfaceStateCustomizer(getVppJvppDependency()));
+
final CompositeListReader<Interface, InterfaceKey, InterfaceBuilder> interfaceReader =
- new CompositeListReader<>(Interface.class,
- RWUtils.<Interface>emptyChildReaderList(),
- RWUtils.<Interface>singletonAugReaderList(vppInterfaceStateAugmentationChildReader),
- new InterfaceCustomizer(vppApi));
+ new CompositeListReader<>(Interface.class,
+ emptyChildReaderList(),
+ singletonAugReaderList(vppInterfaceStateAugmentationChildReader),
+ new InterfaceCustomizer(getVppJvppDependency(), getInterfaceContextIfcStateDependency()));
return new CloseableReader<>(new CompositeRootReader<>(
- InterfacesState.class,
- RWUtils.singletonChildReaderList(interfaceReader),
- RWUtils.<InterfacesState>emptyAugReaderList(),
- new ReflexiveRootReaderCustomizer<>(InterfacesStateBuilder.class)));
+ InterfacesState.class,
+ singletonChildReaderList(interfaceReader),
+ emptyAugReaderList(),
+ new ReflexiveRootReaderCustomizer<>(InterfacesStateBuilder.class)));
}
}
diff --git a/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/VppHoneycombWriterModule.java b/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/VppHoneycombWriterModule.java
index a9eff593d..69c1bfc11 100644
--- a/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/VppHoneycombWriterModule.java
+++ b/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/VppHoneycombWriterModule.java
@@ -35,20 +35,20 @@ public class VppHoneycombWriterModule extends org.opendaylight.yang.gen.v1.urn.h
public java.lang.AutoCloseable createInstance() {
final CompositeListWriter<BridgeDomain, BridgeDomainKey> bridgeDomainWriter = new CompositeListWriter<>(
BridgeDomain.class,
- new BridgeDomainCustomizer(getVppJapiWriterDependency()));
+ new BridgeDomainCustomizer(getVppJvppWriterDependency(), getBridgeDomainContextVppDependency()));
- final ChildWriter<BridgeDomains> bridgeDomainsReader = new CompositeChildWriter<>(
+ final ChildWriter<BridgeDomains> bridgeDomainsWriter = new CompositeChildWriter<>(
BridgeDomains.class,
RWUtils.singletonChildWriterList(bridgeDomainWriter),
- new ReflexiveChildWriterCustomizer<BridgeDomains>());
+ new ReflexiveChildWriterCustomizer<>());
final List<ChildWriter<? extends ChildOf<Vpp>>> childWriters = new ArrayList<>();
- childWriters.add(bridgeDomainsReader);
+ childWriters.add(bridgeDomainsWriter);
return new CloseableWriter<>(new CompositeRootWriter<>(
Vpp.class,
childWriters,
- new NoopWriterCustomizer<Vpp>()));
+ new NoopWriterCustomizer<>()));
}
}
diff --git a/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/VppStateHoneycombReaderModule.java b/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/VppStateHoneycombReaderModule.java
index 0e1d48035..9a0165577 100644
--- a/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/VppStateHoneycombReaderModule.java
+++ b/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/VppStateHoneycombReaderModule.java
@@ -21,7 +21,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomainBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomainKey;
import org.opendaylight.yangtools.yang.binding.ChildOf;
-import org.openvpp.vppjapi.vppApi;
+import org.openvpp.jvpp.future.FutureJVpp;
public class VppStateHoneycombReaderModule extends org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.v3po2vpp.rev160406.AbstractVppStateHoneycombReaderModule {
public VppStateHoneycombReaderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
@@ -39,12 +39,13 @@ public class VppStateHoneycombReaderModule extends org.opendaylight.yang.gen.v1.
@Override
public java.lang.AutoCloseable createInstance() {
- final vppApi vppApi = getVppJapiDependency();
+ final FutureJVpp vppApi = getVppJvppDependency();
final ChildReader<Version> versionReader = new CompositeChildReader<>(Version.class, new VersionCustomizer(vppApi));
final CompositeListReader<BridgeDomain, BridgeDomainKey, BridgeDomainBuilder> bridgeDomainReader =
- new CompositeListReader<>(BridgeDomain.class, new BridgeDomainCustomizer(vppApi));
+ new CompositeListReader<>(BridgeDomain.class, new BridgeDomainCustomizer(vppApi,
+ getBridgeDomainContextVppStateDependency(), getInterfaceContextVppStateDependency()));
final ChildReader<BridgeDomains> bridgeDomainsReader = new CompositeChildReader<>(
BridgeDomains.class,
@@ -58,8 +59,7 @@ public class VppStateHoneycombReaderModule extends org.opendaylight.yang.gen.v1.
return new CloseableReader<>(new CompositeRootReader<>(
VppState.class,
childVppReaders,
- RWUtils.<VppState>emptyAugReaderList(),
+ RWUtils.emptyAugReaderList(),
new ReflexiveRootReaderCustomizer<>(VppStateBuilder.class)));
}
-
}
diff --git a/v3po/v3po2vpp/src/main/yang/v3po2vpp.yang b/v3po/v3po2vpp/src/main/yang/v3po2vpp.yang
index 286feb987..268739451 100644
--- a/v3po/v3po2vpp/src/main/yang/v3po2vpp.yang
+++ b/v3po/v3po2vpp/src/main/yang/v3po2vpp.yang
@@ -5,7 +5,8 @@ module v3po2vpp {
import config { prefix config; revision-date 2013-04-05; }
import translate-api { prefix tapi; revision-date 2016-04-06; }
- import vpp-japi-cfg { prefix vjc; revision-date 2016-04-06; }
+ import vpp-jvpp-cfg { prefix vjvppc; revision-date 2016-04-06; }
+ import vpp-util { prefix vpp-u; revision-date 2016-04-06; }
description
"This module contains reads and writers for v3po yang model";
@@ -24,15 +25,32 @@ module v3po2vpp {
case vpp-state-honeycomb-reader {
when "/config:modules/config:module/config:type = 'vpp-state-honeycomb-reader'";
- container vpp-japi {
+ container vpp-jvpp {
uses config:service-ref {
refine type {
mandatory true;
- config:required-identity vjc:vpp-japi;
+ config:required-identity vjvppc:vpp-jvpp;
}
}
}
+ container interface-context-vpp-state {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity vpp-u:naming-context;
+ }
+ }
+ }
+
+ container bridge-domain-context-vpp-state {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity vpp-u:naming-context;
+ }
+ }
+ }
}
}
@@ -45,11 +63,29 @@ module v3po2vpp {
case interfaces-state-honeycomb-reader {
when "/config:modules/config:module/config:type = 'interfaces-state-honeycomb-reader'";
- container vpp-japi {
+ container vpp-jvpp {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity vjvppc:vpp-jvpp;
+ }
+ }
+ }
+
+ container interface-context-ifc-state {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity vpp-u:naming-context;
+ }
+ }
+ }
+
+ container bridge-domain-context-ifc-state {
uses config:service-ref {
refine type {
mandatory true;
- config:required-identity vjc:vpp-japi;
+ config:required-identity vpp-u:naming-context;
}
}
}
@@ -67,15 +103,32 @@ module v3po2vpp {
case vpp-honeycomb-writer {
when "/config:modules/config:module/config:type = 'vpp-honeycomb-writer'";
- container vpp-japi-writer {
+ container vpp-jvpp-writer {
uses config:service-ref {
refine type {
mandatory true;
- config:required-identity vjc:vpp-japi;
+ config:required-identity vjvppc:vpp-jvpp;
}
}
}
+ container interface-context-vpp {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity vpp-u:naming-context;
+ }
+ }
+ }
+
+ container bridge-domain-context-vpp {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity vpp-u:naming-context;
+ }
+ }
+ }
}
}
@@ -88,11 +141,29 @@ module v3po2vpp {
case interfaces-honeycomb-writer {
when "/config:modules/config:module/config:type = 'interfaces-honeycomb-writer'";
- container vpp-japi-ifc {
+ container vpp-jvpp-ifc {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity vjvppc:vpp-jvpp;
+ }
+ }
+ }
+
+ container interface-context {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity vpp-u:naming-context;
+ }
+ }
+ }
+
+ container bridge-domain-context {
uses config:service-ref {
refine type {
mandatory true;
- config:required-identity vjc:vpp-japi;
+ config:required-identity vpp-u:naming-context;
}
}
}
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
index 111d813aa..7c88c3198 100644
--- 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
@@ -16,112 +16,150 @@
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 static io.fd.honeycomb.v3po.translate.v3po.interfacesstate.InterfaceUtils.YangIfIndexToVpp;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
import io.fd.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 io.fd.honeycomb.v3po.translate.spi.read.RootReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.test.ListReaderCustomizerTest;
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.ExecutionException;
import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
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 org.openvpp.jvpp.dto.SwInterfaceDetails;
+import org.openvpp.jvpp.dto.SwInterfaceDetailsReplyDump;
+import org.openvpp.jvpp.dto.SwInterfaceDump;
-import static org.junit.Assert.assertTrue;
-import static org.powermock.api.mockito.PowerMockito.mock;
+public class InterfaceCustomizerTest extends
+ ListReaderCustomizerTest<Interface, InterfaceKey, InterfaceBuilder> {
-@RunWith(PowerMockRunner.class)
-@SuppressStaticInitializationFor("org.openvpp.vppjapi.vppConn")
-@PrepareForTest(vppApi.class)
-public class InterfaceCustomizerTest {
+ private NamingContext interfacesContext;
- public static final vppVersion VERSION = new vppVersion("test", "1", "2", "33");
+ public InterfaceCustomizerTest() {
+ super(Interface.class);
+ }
- private vppApi api;
- private CompositeRootReader<InterfacesState, InterfacesStateBuilder> interfacesStateReader;
- private DelegatingReaderRegistry readerRegistry;
- private ReadContext ctx;
+ @Override
+ public void setUpBefore() {
+ interfacesContext = new NamingContext("generatedIfaceName");
+ }
- private CompositeRootReader<InterfacesState, InterfacesStateBuilder> getInterfacesStateReader(
- final vppApi vppApi) {
+ @Override
+ protected RootReaderCustomizer<Interface, InterfaceBuilder> initCustomizer() {
+ return new InterfaceCustomizer(api, interfacesContext);
+ }
- final CompositeListReader<Interface, InterfaceKey, InterfaceBuilder> interfacesReader =
- new CompositeListReader<>(Interface.class, new InterfaceCustomizer(vppApi));
+ // TODO use reflexion and move to ListReaderCustomizerTest
+ @Test
+ public void testMerge() throws Exception {
+ final InterfacesStateBuilder builder = mock(InterfacesStateBuilder.class);
+ final List<Interface> value = Collections.emptyList();
+ getCustomizer().merge(builder, value);
+ verify(builder).setInterface(value);
+ }
- final List<ChildReader<? extends ChildOf<InterfacesState>>> childReaders = new ArrayList<>();
- childReaders.add(interfacesReader);
+ private void verifyBridgeDomainDumpUpdateWasInvoked(final int nameFilterValid, final String ifaceName) {
+ // TODO adding equals methods for jvpp DTOs would make ArgumentCaptor usage obsolete
+ ArgumentCaptor<SwInterfaceDump> argumentCaptor = ArgumentCaptor.forClass(SwInterfaceDump.class);
+ verify(api).swInterfaceDump(argumentCaptor.capture());
+ final SwInterfaceDump actual = argumentCaptor.getValue();
+ assertEquals(nameFilterValid, actual.nameFilterValid);
+ assertArrayEquals(ifaceName.getBytes(), actual.nameFilter);
+ }
- return new CompositeRootReader<>(InterfacesState.class, childReaders,
- RWUtils.<InterfacesState>emptyAugReaderList(),
- new ReflexiveRootReaderCustomizer<>(InterfacesStateBuilder.class));
+ private static void assertIfacesAreEqual(final Interface iface, final SwInterfaceDetails details) {
+ assertEquals(iface.getName(), new String(details.interfaceName));
+ assertEquals(YangIfIndexToVpp(iface.getIfIndex().intValue()), details.swIfIndex);
+ assertEquals(iface.getPhysAddress().getValue(), InterfaceUtils.vppPhysAddrToYang(details.l2Address));
}
- 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);
+ private void whenSwInterfaceDumpThenReturn(final List<SwInterfaceDetails> interfaceList)
+ throws ExecutionException, InterruptedException {
+ final CompletionStage<SwInterfaceDetailsReplyDump> replyCS = mock(CompletionStage.class);
+ final CompletableFuture<SwInterfaceDetailsReplyDump> replyFuture = mock(CompletableFuture.class);
+ when(replyCS.toCompletableFuture()).thenReturn(replyFuture);
+ final SwInterfaceDetailsReplyDump reply = new SwInterfaceDetailsReplyDump();
+ reply.swInterfaceDetails = interfaceList;
+ when(replyFuture.get()).thenReturn(reply);
+ when(api.swInterfaceDump(any(SwInterfaceDump.class))).thenReturn(replyCS);
}
- @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 testReadCurrentAttributes() throws Exception {
+ final String ifaceName = "eth0";
+ final InstanceIdentifier<Interface> id = InstanceIdentifier.create(InterfacesState.class)
+ .child(Interface.class, new InterfaceKey(ifaceName));
+ final InterfaceBuilder builder = getCustomizer().getBuilder(id);
+
+ final SwInterfaceDetails iface = new SwInterfaceDetails();
+ iface.interfaceName = ifaceName.getBytes();
+ iface.swIfIndex = 0;
+ iface.linkSpeed = 1;
+ iface.l2AddressLength = 6;
+ iface.l2Address = new byte[iface.l2AddressLength];
+ final List<SwInterfaceDetails> interfaceList = Collections.singletonList(iface);
+ whenSwInterfaceDumpThenReturn(interfaceList);
+
+ getCustomizer().readCurrentAttributes(id, builder, ctx);
+
+ verifyBridgeDomainDumpUpdateWasInvoked(1, ifaceName);
+ assertIfacesAreEqual(builder.build(), iface);
}
@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);
+ public void testReadCurrentAttributesFailed() throws Exception {
+ final String ifaceName = "eth0";
+ final InstanceIdentifier<Interface> id = InstanceIdentifier.create(InterfacesState.class)
+ .child(Interface.class, new InterfaceKey(ifaceName));
+ final InterfaceBuilder builder = getCustomizer().getBuilder(id);
+
+ whenSwInterfaceDumpThenReturn(Collections.emptyList());
+
+ try {
+ getCustomizer().readCurrentAttributes(id, builder, ctx);
+ } catch (ReadFailedException e) {
+ verifyBridgeDomainDumpUpdateWasInvoked(1, ifaceName);
+ return;
+ }
+
+ fail("ReadFailedException was expected");
}
@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);
+ public void testGetAllIds() throws Exception {
+ final InstanceIdentifier<Interface> id = InstanceIdentifier.create(InterfacesState.class)
+ .child(Interface.class);
+
+ final String swIf0Name = "eth0";
+ final SwInterfaceDetails swIf0 = new SwInterfaceDetails();
+ swIf0.interfaceName = swIf0Name.getBytes();
+ final String swIf1Name = "eth0";
+ final SwInterfaceDetails swIf1 = new SwInterfaceDetails();
+ swIf1.interfaceName = swIf1Name.getBytes();
+ whenSwInterfaceDumpThenReturn(Arrays.asList(swIf0, swIf1));
+
+ final List<InterfaceKey> expectedIds = Arrays.asList(new InterfaceKey(swIf0Name), new InterfaceKey(swIf1Name));
+ final List<InterfaceKey> actualIds = getCustomizer().getAllIds(id, ctx);
+
+ verifyBridgeDomainDumpUpdateWasInvoked(0, "");
+
+ assertEquals(expectedIds, actualIds);
}
}
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/ChildReaderCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/ChildReaderCustomizerTest.java
new file mode 100644
index 000000000..57369d665
--- /dev/null
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/ChildReaderCustomizerTest.java
@@ -0,0 +1,49 @@
+/*
+ * 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.test;
+
+import static org.junit.Assert.assertNotNull;
+
+import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
+import org.junit.Test;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * Generic test for classes implementing {@link ChildReaderCustomizer} interface.
+ *
+ * @param <D> Specific DataObject derived type (Identifiable), that is handled by this customizer
+ * @param <B> Specific Builder for handled type (D)
+ */
+public abstract class ChildReaderCustomizerTest<D extends DataObject, B extends Builder<D>> extends RootReaderCustomizerTest<D, B>{
+
+
+ protected ChildReaderCustomizerTest(Class<D> dataObjectClass) {
+ super(dataObjectClass);
+ }
+
+ @Override
+ protected ChildReaderCustomizer<D, B> getCustomizer() {
+ return ChildReaderCustomizer.class.cast(super.getCustomizer());
+ }
+
+ @Test
+ public void testGetBuilder() throws Exception {
+ assertNotNull(getCustomizer().getBuilder(InstanceIdentifier.create(dataObjectClass)));
+ }
+}
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/ListReaderCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/ListReaderCustomizerTest.java
new file mode 100644
index 000000000..00cac2d5d
--- /dev/null
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/ListReaderCustomizerTest.java
@@ -0,0 +1,52 @@
+/*
+ * 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.test;
+
+import static org.junit.Assert.assertNotNull;
+
+import io.fd.honeycomb.v3po.translate.spi.read.ListReaderCustomizer;
+import org.junit.Test;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.Identifiable;
+import org.opendaylight.yangtools.yang.binding.Identifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * Generic test for classes implementing {@link ListReaderCustomizer} interface.
+ *
+ * @param <D> Specific DataObject derived type (Identifiable), that is handled by this customizer
+ * @param <K> Specific Identifier for handled type (D)
+ * @param <B> Specific Builder for handled type (D)
+ */
+public abstract class ListReaderCustomizerTest<D extends DataObject & Identifiable<K>, K extends Identifier<D>, B extends Builder<D>> extends RootReaderCustomizerTest<D, B>{
+
+
+ protected ListReaderCustomizerTest(Class<D> dataObjectClass) {
+ super(dataObjectClass);
+ }
+
+ @Override
+ protected ListReaderCustomizer<D, K, B> getCustomizer() {
+ return ListReaderCustomizer.class.cast(super.getCustomizer());
+ }
+
+ @Test
+ public void testGetBuilder() throws Exception {
+ assertNotNull(getCustomizer().getBuilder(InstanceIdentifier.create(dataObjectClass)));
+ }
+}
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/RootReaderCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/RootReaderCustomizerTest.java
new file mode 100644
index 000000000..76eb0fb3f
--- /dev/null
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/RootReaderCustomizerTest.java
@@ -0,0 +1,84 @@
+/*
+ * 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.test;
+
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.MockitoAnnotations.initMocks;
+
+import io.fd.honeycomb.v3po.translate.Context;
+import io.fd.honeycomb.v3po.translate.spi.read.RootReaderCustomizer;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+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;
+
+/**
+ * Generic test for classes implementing {@link RootReaderCustomizer} interface.
+ *
+ * @param <D> Specific DataObject derived type (Identifiable), that is handled by this customizer
+ * @param <B> Specific Builder for handled type (D)
+ */
+public abstract class RootReaderCustomizerTest<D extends DataObject, B extends Builder<D>> {
+
+ @Mock
+ protected FutureJVpp api;
+ @Mock
+ protected Context ctx;
+
+ protected final Class<D> dataObjectClass;
+ private RootReaderCustomizer<D, B> customizer;
+
+ protected RootReaderCustomizerTest(Class<D> dataObjectClass) {
+ this.dataObjectClass = dataObjectClass;
+ }
+
+ @Before
+ public void setUpParent() throws Exception {
+ initMocks(this);
+ setUpBefore();
+ customizer = initCustomizer();
+ setUpAfter();
+ }
+
+ /**
+ * Optional setup for subclasses. Invoked before customizer is initialized.
+ */
+ protected void setUpBefore() {
+
+ }
+
+ /**
+ * Optional setup for subclasses. Invoked after customizer is initialized.
+ */
+ protected void setUpAfter() {
+
+ }
+
+ protected abstract RootReaderCustomizer<D, B> initCustomizer();
+
+ protected RootReaderCustomizer<D, B> getCustomizer() {
+ return customizer;
+ }
+
+ @Test
+ public void testGetBuilder() throws Exception {
+ assertNotNull(customizer.getBuilder(InstanceIdentifier.create(dataObjectClass)));
+ }
+}
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/utils/V3poUtilsTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/utils/V3poUtilsTest.java
index 3cb054ad4..115eb2b9c 100644
--- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/utils/V3poUtilsTest.java
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/utils/V3poUtilsTest.java
@@ -1,35 +1,17 @@
package io.fd.honeycomb.v3po.translate.v3po.utils;
-import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertArrayEquals;
import org.junit.Test;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone;
public class V3poUtilsTest {
@Test
- public void testRemoveIpv4AddressNoZoneFromIpv4WithZone() throws Exception {
- String ipWithZone = "1.2.3.4%20";
- String ipNoZone = "1.2.3.4";
- final Ipv4Address expectedIp = new Ipv4Address(ipNoZone);
- final Ipv4AddressNoZone actualIp = V3poUtils.removeIpv4AddressNoZone(new Ipv4Address(ipWithZone));
- assertEquals(expectedIp.getValue(), actualIp.getValue());
- }
-
- @Test
- public void testRemoveIpv4AddressNoZoneFromIpv4WithoutZone() throws Exception {
- String ipNoZone = "1.2.3.4";
- final Ipv4Address expectedIp = new Ipv4Address(ipNoZone);
- final Ipv4AddressNoZone actualIp = V3poUtils.removeIpv4AddressNoZone(expectedIp);
- assertEquals(expectedIp.getValue(), actualIp.getValue());
- }
-
- @Test
- public void testRemoveIpv4AddressNoZoneNop() throws Exception {
- String ipNoZone = "1.2.3.4";
- final Ipv4Address expectedIp = new Ipv4AddressNoZone(ipNoZone);
- final Ipv4AddressNoZone actualIp = V3poUtils.removeIpv4AddressNoZone(expectedIp);
- assertEquals(expectedIp, actualIp);
+ public void testToString() {
+ final byte[] expected = "test".getBytes();
+ final byte[] cString = new byte[expected.length+10];
+ System.arraycopy(expected, 0, cString, 0, expected.length);
+ final String jString = V3poUtils.toString(cString);
+ assertArrayEquals(expected, jString.getBytes());
}
} \ No newline at end of file
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainCustomizerTest.java
index f504918a8..5d5781adb 100644
--- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainCustomizerTest.java
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainCustomizerTest.java
@@ -13,57 +13,53 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package io.fd.honeycomb.v3po.translate.v3po.vpp;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
import io.fd.honeycomb.v3po.translate.Context;
+import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.ExecutionException;
import org.junit.Before;
import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomain;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomainBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomainKey;
-import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
-import org.openvpp.vppjapi.vppApi;
-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;
-
-@RunWith(PowerMockRunner.class)
-@SuppressStaticInitializationFor("org.openvpp.vppjapi.vppConn")
-@PrepareForTest(vppApi.class)
+import org.openvpp.jvpp.dto.BridgeDomainAddDel;
+import org.openvpp.jvpp.dto.BridgeDomainAddDelReply;
+import org.openvpp.jvpp.future.FutureJVpp;
+
public class BridgeDomainCustomizerTest {
- private static final int RESPONSE_NOT_READY = -77;
private static final byte ADD_OR_UPDATE_BD = (byte) 1;
private static final byte ZERO = 0;
- private vppApi api;
+
+ @Mock
+ private FutureJVpp api;
@Mock
private Context ctx;
private BridgeDomainCustomizer customizer;
+ private NamingContext namingContext;
@Before
public void setUp() throws Exception {
- // TODO create base class for tests using vppApi
- api = PowerMockito.mock(vppApi.class);
initMocks(this);
- customizer = new BridgeDomainCustomizer(api);
-
- PowerMockito.doAnswer(BridgeDomainTestUtils.BD_NAME_TO_ID_ANSWER).when(api).findOrAddBridgeDomainId(anyString());
- PowerMockito.doAnswer(BridgeDomainTestUtils.BD_NAME_TO_ID_ANSWER).when(api).bridgeDomainIdFromName(anyString());
- PowerMockito.when(api.getRetval(anyInt(), anyInt())).thenReturn(RESPONSE_NOT_READY).thenReturn(0);
- PowerMockito.doReturn(0).when(api).getRetval(anyInt(), anyInt());
+ // TODO create base class for tests using vppApi
+ namingContext = new NamingContext("generatedBDName");
+ customizer = new BridgeDomainCustomizer(api, namingContext);
}
private BridgeDomain generateBridgeDomain(final String bdName) {
@@ -87,127 +83,140 @@ public class BridgeDomainCustomizerTest {
.build();
}
- private final int verifyBridgeDomainAddOrUpdateWasInvoked(final BridgeDomain bd) {
- final int bdn1Id = BridgeDomainTestUtils.bdNameToID(bd.getName());
+ private void verifyBridgeDomainAddOrUpdateWasInvoked(final BridgeDomain bd, final int bdId) {
final byte arpTerm = BridgeDomainTestUtils.booleanToByte(bd.isArpTermination());
final byte flood = BridgeDomainTestUtils.booleanToByte(bd.isFlood());
final byte forward = BridgeDomainTestUtils.booleanToByte(bd.isForward());
final byte learn = BridgeDomainTestUtils.booleanToByte(bd.isLearn());
final byte uuf = BridgeDomainTestUtils.booleanToByte(bd.isUnknownUnicastFlood());
- return verify(api).bridgeDomainAddDel(bdn1Id, flood, forward, learn, uuf, arpTerm, ADD_OR_UPDATE_BD);
+
+ // TODO adding equals methods for jvpp DTOs would make ArgumentCaptor usage obsolete
+ ArgumentCaptor<BridgeDomainAddDel> argumentCaptor = ArgumentCaptor.forClass(BridgeDomainAddDel.class);
+ verify(api).bridgeDomainAddDel(argumentCaptor.capture());
+ final BridgeDomainAddDel actual = argumentCaptor.getValue();
+ assertEquals(arpTerm, actual.arpTerm);
+ assertEquals(flood, actual.flood);
+ assertEquals(forward, actual.forward);
+ assertEquals(learn, actual.learn);
+ assertEquals(uuf, actual.uuFlood);
+ assertEquals(ADD_OR_UPDATE_BD, actual.isAdd);
+ assertEquals(bdId, actual.bdId);
}
- private int verifyBridgeDomainAddOrUpdateWasNotInvoked(final BridgeDomain bd) {
- final int bdn1Id = BridgeDomainTestUtils.bdNameToID(bd.getName());
- final byte arpTerm = BridgeDomainTestUtils.booleanToByte(bd.isArpTermination());
- final byte flood = BridgeDomainTestUtils.booleanToByte(bd.isFlood());
- final byte forward = BridgeDomainTestUtils.booleanToByte(bd.isForward());
- final byte learn = BridgeDomainTestUtils.booleanToByte(bd.isLearn());
- final byte uuf = BridgeDomainTestUtils.booleanToByte(bd.isUnknownUnicastFlood());
- return verify(api, never()).bridgeDomainAddDel(bdn1Id, flood, forward, learn, uuf, arpTerm, ADD_OR_UPDATE_BD);
+ private void verifyBridgeDomainDeleteWasInvoked(final int bdId) {
+ ArgumentCaptor<BridgeDomainAddDel> argumentCaptor = ArgumentCaptor.forClass(BridgeDomainAddDel.class);
+ verify(api).bridgeDomainAddDel(argumentCaptor.capture());
+ final BridgeDomainAddDel actual = argumentCaptor.getValue();
+ assertEquals(bdId, actual.bdId);
+ assertEquals(ZERO, actual.arpTerm);
+ assertEquals(ZERO, actual.flood);
+ assertEquals(ZERO, actual.forward);
+ assertEquals(ZERO, actual.learn);
+ assertEquals(ZERO, actual.uuFlood);
+ assertEquals(ZERO, actual.isAdd);
+ }
+
+ private void whenBridgeDomainAddDelThen(final int retval) throws ExecutionException, InterruptedException {
+ final CompletionStage<BridgeDomainAddDelReply> replyCS = mock(CompletionStage.class);
+ final CompletableFuture<BridgeDomainAddDelReply> replyFuture = mock(CompletableFuture.class);
+ when(replyCS.toCompletableFuture()).thenReturn(replyFuture);
+ final BridgeDomainAddDelReply reply = new BridgeDomainAddDelReply();
+ reply.retval = retval;
+ when(replyFuture.get()).thenReturn(reply);
+ when(api.bridgeDomainAddDel(any(BridgeDomainAddDel.class))).thenReturn(replyCS);
}
- private int verifyBridgeDomainDeletedWasInvoked(final BridgeDomain bd) {
- final int bdn1Id = BridgeDomainTestUtils.bdNameToID(bd.getName());
- return verify(api).bridgeDomainAddDel(bdn1Id, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO);
+ private void whenBridgeDomainAddDelThenSuccess() throws ExecutionException, InterruptedException {
+ whenBridgeDomainAddDelThen(0);
}
- private int verifyBridgeDomainDeletedWasNotInvoked(final BridgeDomain bd) {
- final int bdn1Id = BridgeDomainTestUtils.bdNameToID(bd.getName());
- return verify(api, never()).bridgeDomainAddDel(bdn1Id, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO);
+ private void whenBridgeDomainAddDelThenFailure() throws ExecutionException, InterruptedException {
+ whenBridgeDomainAddDelThen(-1);
}
@Test
- public void testAddBridgeDomain() {
+ public void testAddBridgeDomain() throws Exception {
+ final int bdId = 1;
final String bdName = "bd1";
- final BridgeDomain bd = generateBridgeDomain("bd1");
+ final BridgeDomain bd = generateBridgeDomain(bdName);
+
+ whenBridgeDomainAddDelThenSuccess();
customizer.writeCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), bd, ctx);
- verifyBridgeDomainAddOrUpdateWasInvoked(bd);
+ verifyBridgeDomainAddOrUpdateWasInvoked(bd, bdId);
}
@Test
- public void testBridgeDomainNameCreateFailed() {
+ public void testAddBridgeDomainFailed() throws Exception {
+ final int bdId = 1;
final String bdName = "bd1";
- final BridgeDomain bd = generateBridgeDomain("bd1");
+ final BridgeDomain bd = generateBridgeDomain(bdName);
- // make vpp api fail to create id for our bd name
- PowerMockito.doReturn(-1).when(api).findOrAddBridgeDomainId(bdName);
+ whenBridgeDomainAddDelThenFailure();
try {
customizer.writeCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), bd, ctx);
- } catch (IllegalStateException e) {
- verifyBridgeDomainAddOrUpdateWasNotInvoked(bd);
+ } catch (WriteFailedException.CreateFailedException e) {
+ verifyBridgeDomainAddOrUpdateWasInvoked(bd, bdId);
return;
}
- fail("IllegalStateException was expected");
+ fail("WriteFailedException.CreateFailedException was expected");
}
@Test
- public void testAddBridgeDomainFailed() {
- // make any call to vpp fail
- PowerMockito.doReturn(-1).when(api).getRetval(anyInt(), anyInt());
-
+ public void testDeleteBridgeDomain() throws Exception {
+ final int bdId = 1;
final String bdName = "bd1";
final BridgeDomain bd = generateBridgeDomain(bdName);
+ namingContext.addName(bdId, bdName);
- try {
- customizer.writeCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), bd, ctx);
- } catch (IllegalStateException e) {
- verifyBridgeDomainAddOrUpdateWasInvoked(bd);
- return;
- }
- fail("IllegalStateException was expected");
- }
-
- @Test
- public void testDeleteBridgeDomain() {
- final String bdName = "bd1";
- final BridgeDomain bd = generateBridgeDomain("bd1");
+ whenBridgeDomainAddDelThenSuccess();
customizer.deleteCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), bd, ctx);
- verifyBridgeDomainDeletedWasInvoked(bd);
+ verifyBridgeDomainDeleteWasInvoked(bdId);
}
@Test
- public void testDeleteUnknownBridgeDomain() {
+ public void testDeleteUnknownBridgeDomain() throws Exception {
final String bdName = "bd1";
final BridgeDomain bd = generateBridgeDomain("bd1");
- // make vpp api not find our bd
- PowerMockito.doReturn(-1).when(api).bridgeDomainIdFromName(bdName);
-
try {
customizer.deleteCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), bd, ctx);
- } catch (IllegalStateException e) {
- verifyBridgeDomainDeletedWasNotInvoked(bd);
+ } catch (IllegalArgumentException e) {
+ verify(api, never()).bridgeDomainAddDel(any(BridgeDomainAddDel.class));
return;
}
- fail("IllegalStateException was expected");
+ fail("IllegalArgumentException was expected");
}
@Test
- public void testDeleteBridgeDomainFailed() {
- // make any call to vpp fail
- PowerMockito.doReturn(-1).when(api).getRetval(anyInt(), anyInt());
-
+ public void testDeleteBridgeDomainFailed() throws Exception {
+ final int bdId = 1;
final String bdName = "bd1";
final BridgeDomain bd = generateBridgeDomain(bdName);
+ namingContext.addName(bdId, bdName);
+
+ whenBridgeDomainAddDelThenFailure();
try {
customizer.deleteCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), bd, ctx);
- } catch (IllegalStateException e) {
- verifyBridgeDomainDeletedWasInvoked(bd);
+ } catch (WriteFailedException.DeleteFailedException e) {
+ verifyBridgeDomainDeleteWasInvoked(bdId);
return;
}
- fail("IllegalStateException was expected");
+
+ fail("WriteFailedException.DeleteFailedException was expected");
}
@Test
public void testUpdateBridgeDomain() throws Exception {
+ final int bdId = 1;
final String bdName = "bd1";
+ namingContext.addName(bdId, bdName);
+
final byte arpTermBefore = 1;
final byte floodBefore = 1;
final byte forwardBefore = 0;
@@ -220,11 +229,11 @@ public class BridgeDomainCustomizerTest {
generateBridgeDomain(bdName, arpTermBefore ^ 1, floodBefore ^ 1, forwardBefore ^ 1, learnBefore ^ 1,
uufBefore ^ 1);
- final KeyedInstanceIdentifier<BridgeDomain, BridgeDomainKey> id = BridgeDomainTestUtils.bdIdentifierForName(bdName);
+ whenBridgeDomainAddDelThenSuccess();
- customizer.updateCurrentAttributes(id, dataBefore, dataAfter, ctx);
+ customizer.updateCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), dataBefore, dataAfter, ctx);
- verifyBridgeDomainAddOrUpdateWasInvoked(dataAfter);
+ verifyBridgeDomainAddOrUpdateWasInvoked(dataAfter, bdId);
}
@Test
@@ -232,30 +241,28 @@ public class BridgeDomainCustomizerTest {
final String bdName = "bd1";
final BridgeDomain bd = generateBridgeDomain("bd1");
- // make vpp api not find our bd
- PowerMockito.doReturn(-1).when(api).bridgeDomainIdFromName(bdName);
-
try {
customizer.updateCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), bd, bd, ctx);
- } catch (IllegalStateException e) {
- verifyBridgeDomainAddOrUpdateWasNotInvoked(bd);
+ } catch (IllegalArgumentException e) {
+ verify(api, never()).bridgeDomainAddDel(any(BridgeDomainAddDel.class));
return;
}
- fail("IllegalStateException was expected");
+ fail("IllegalArgumentException was expected");
}
@Test
- public void testUpdateBridgeDomainFailed() {
- // make any call to vpp fail
- PowerMockito.doReturn(-1).when(api).getRetval(anyInt(), anyInt());
-
+ public void testUpdateBridgeDomainFailed() throws Exception {
+ final int bdId = 1;
final String bdName = "bd1";
final BridgeDomain bd = generateBridgeDomain(bdName);
+ namingContext.addName(bdId, bdName);
+
+ whenBridgeDomainAddDelThenFailure();
try {
customizer.updateCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), bd, bd, ctx);
- } catch (IllegalStateException e) {
- verifyBridgeDomainAddOrUpdateWasInvoked(bd);
+ } catch (WriteFailedException.UpdateFailedException e) {
+ verifyBridgeDomainAddOrUpdateWasInvoked(bd, bdId);
return;
}
fail("IllegalStateException was expected");
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/VppTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/VppTest.java
index 0ff3ba16d..820cf0555 100644
--- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/VppTest.java
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/VppTest.java
@@ -16,23 +16,28 @@
package io.fd.honeycomb.v3po.translate.v3po.vpp;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyString;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import io.fd.honeycomb.v3po.translate.impl.write.CompositeRootWriter;
-import io.fd.honeycomb.v3po.translate.write.WriteContext;
import io.fd.honeycomb.v3po.translate.util.write.DelegatingWriterRegistry;
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
+import io.fd.honeycomb.v3po.translate.write.WriteContext;
import io.fd.honeycomb.v3po.translate.write.Writer;
import java.util.Collections;
import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.ExecutionException;
import org.junit.Before;
import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.Vpp;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.BridgeDomains;
@@ -41,98 +46,147 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomainBuilder;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.openvpp.vppjapi.vppApi;
-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;
-
-@RunWith(PowerMockRunner.class)
-@SuppressStaticInitializationFor("org.openvpp.vppjapi.vppConn")
-@PrepareForTest(vppApi.class)
+import org.openvpp.jvpp.dto.BridgeDomainAddDel;
+import org.openvpp.jvpp.dto.BridgeDomainAddDelReply;
+import org.openvpp.jvpp.future.FutureJVpp;
+
public class VppTest {
- private vppApi api;
+ private static final byte ADD_OR_UPDATE_BD = 1;
+ private static final byte ZERO = 0;
+ private FutureJVpp api;
private DelegatingWriterRegistry rootRegistry;
private CompositeRootWriter<Vpp> vppWriter;
private WriteContext ctx;
-
- final byte zero = (byte) 0;
- final byte flood = (byte) 1;
- final byte forward = (byte) 0;
- final byte learn = (byte) 1;
- final byte uuf = (byte) 0;
- final byte arpTerm = (byte) 0;
- final byte add = (byte) 1;
+ private NamingContext bdContext;
@Before
public void setUp() throws Exception {
- api = PowerMockito.mock(vppApi.class);
+ api = mock(FutureJVpp.class);
ctx = mock(WriteContext.class);
- PowerMockito.doAnswer(BridgeDomainTestUtils.BD_NAME_TO_ID_ANSWER).when(api).findOrAddBridgeDomainId(anyString());
- PowerMockito.doAnswer(BridgeDomainTestUtils.BD_NAME_TO_ID_ANSWER).when(api).bridgeDomainIdFromName(anyString());
- PowerMockito.doReturn(1).when(api).getRetval(anyInt(), anyInt());
- vppWriter = VppUtils.getVppWriter(api);
+ bdContext = new NamingContext("generatedBdName");
+ vppWriter = VppUtils.getVppWriter(api, bdContext);
rootRegistry = new DelegatingWriterRegistry(
Collections.<Writer<? extends DataObject>>singletonList(vppWriter));
}
+ private BridgeDomains getBridgeDomains(String... name) {
+ final List<BridgeDomain> bdmns = Lists.newArrayList();
+ for (String s : name) {
+ bdmns.add(new BridgeDomainBuilder()
+ .setName(s)
+ .setArpTermination(false)
+ .setFlood(true)
+ .setForward(false)
+ .setLearn(true)
+ .build());
+ }
+ return new BridgeDomainsBuilder()
+ .setBridgeDomain(bdmns)
+ .build();
+ }
+
+ private void whenBridgeDomainAddDelThen(final int retval) throws ExecutionException, InterruptedException {
+ final CompletionStage<BridgeDomainAddDelReply> replyCS = mock(CompletionStage.class);
+ final CompletableFuture<BridgeDomainAddDelReply> replyFuture = mock(CompletableFuture.class);
+ when(replyCS.toCompletableFuture()).thenReturn(replyFuture);
+ final BridgeDomainAddDelReply reply = new BridgeDomainAddDelReply();
+ reply.retval = retval;
+ when(replyFuture.get()).thenReturn(reply);
+ when(api.bridgeDomainAddDel(any(BridgeDomainAddDel.class))).thenReturn(replyCS);
+ }
+
+ private void verifyBridgeDomainAddDel(final BridgeDomain bd, final int bdId) {
+ final byte arpTerm = BridgeDomainTestUtils.booleanToByte(bd.isArpTermination());
+ final byte flood = BridgeDomainTestUtils.booleanToByte(bd.isFlood());
+ final byte forward = BridgeDomainTestUtils.booleanToByte(bd.isForward());
+ final byte learn = BridgeDomainTestUtils.booleanToByte(bd.isLearn());
+ final byte uuf = BridgeDomainTestUtils.booleanToByte(bd.isUnknownUnicastFlood());
+
+ // TODO adding equals methods for jvpp DTOs would make ArgumentCaptor usage obsolete
+ ArgumentCaptor<BridgeDomainAddDel> argumentCaptor = ArgumentCaptor.forClass(BridgeDomainAddDel.class);
+ verify(api).bridgeDomainAddDel(argumentCaptor.capture());
+ final BridgeDomainAddDel actual = argumentCaptor.getValue();
+ assertEquals(arpTerm, actual.arpTerm);
+ assertEquals(flood, actual.flood);
+ assertEquals(forward, actual.forward);
+ assertEquals(learn, actual.learn);
+ assertEquals(uuf, actual.uuFlood);
+ assertEquals(ADD_OR_UPDATE_BD, actual.isAdd);
+ assertEquals(bdId, actual.bdId);
+ }
+
+ private void verifyBridgeDomainDeleteWasInvoked(final int bdId) {
+ ArgumentCaptor<BridgeDomainAddDel> argumentCaptor = ArgumentCaptor.forClass(BridgeDomainAddDel.class);
+ verify(api).bridgeDomainAddDel(argumentCaptor.capture());
+ final BridgeDomainAddDel actual = argumentCaptor.getValue();
+ assertEquals(bdId, actual.bdId);
+ assertEquals(ZERO, actual.arpTerm);
+ assertEquals(ZERO, actual.flood);
+ assertEquals(ZERO, actual.forward);
+ assertEquals(ZERO, actual.learn);
+ assertEquals(ZERO, actual.uuFlood);
+ assertEquals(ZERO, actual.isAdd);
+ }
+
@Test
- public void writeVpp() throws Exception {
+ public void writeVppUsingRootRegistry() throws Exception {
+ final int bdId = 1;
+ final BridgeDomains bdn1 = getBridgeDomains("bdn1");
+ whenBridgeDomainAddDelThen(0);
+
rootRegistry.update(
- InstanceIdentifier.create(Vpp.class),
- null,
- new VppBuilder().setBridgeDomains(getBridgeDomains("bdn1")).build(),
- ctx);
+ InstanceIdentifier.create(Vpp.class),
+ null,
+ new VppBuilder().setBridgeDomains(bdn1).build(),
+ ctx);
+
+ verifyBridgeDomainAddDel(Iterators.getOnlyElement(bdn1.getBridgeDomain().iterator()), bdId);
+ }
- verify(api).bridgeDomainAddDel(1, flood, forward, learn, uuf, arpTerm, add);
+ @Test
+ public void writeVppUsingVppWriter() throws Exception {
+ final int bdId = 1;
+ final BridgeDomains bdn1 = getBridgeDomains("bdn1");
+ whenBridgeDomainAddDelThen(0);
vppWriter.update(InstanceIdentifier.create(Vpp.class),
- null,
- new VppBuilder().setBridgeDomains(getBridgeDomains("bdn1")).build(),
- ctx);
+ null,
+ new VppBuilder().setBridgeDomains(bdn1).build(),
+ ctx);
- verify(api, times(2)).bridgeDomainAddDel(1, flood, forward, learn, uuf, arpTerm, add);
+ verifyBridgeDomainAddDel(Iterators.getOnlyElement(bdn1.getBridgeDomain().iterator()), bdId);
}
@Test
public void writeVppFromRoot() throws Exception {
- final Vpp vpp = new VppBuilder().setBridgeDomains(getBridgeDomains("bdn1")).build();
+ final BridgeDomains bdn1 = getBridgeDomains("bdn1");
+ final int bdId = 1;
+ final Vpp vpp = new VppBuilder().setBridgeDomains(bdn1).build();
+ whenBridgeDomainAddDelThen(0);
rootRegistry.update(Collections.<InstanceIdentifier<?>, DataObject>emptyMap(),
Collections.<InstanceIdentifier<?>, DataObject>singletonMap(InstanceIdentifier.create(Vpp.class),
vpp), ctx);
- verify(api).bridgeDomainAddDel(1, flood, forward, learn, uuf, arpTerm, add);
- }
-
- private BridgeDomains getBridgeDomains(String... name) {
- final List<BridgeDomain> bdmns = Lists.newArrayList();
- for (String s : name) {
- bdmns.add(new BridgeDomainBuilder()
- .setName(s)
- .setArpTermination(false)
- .setFlood(true)
- .setForward(false)
- .setLearn(true)
- .build());
- }
- return new BridgeDomainsBuilder()
- .setBridgeDomain(bdmns)
- .build();
+ verifyBridgeDomainAddDel(Iterators.getOnlyElement(bdn1.getBridgeDomain().iterator()), bdId);
}
@Test
public void deleteVpp() throws Exception {
+ final String bdName = "bdn1";
+ final BridgeDomains bdn1 = getBridgeDomains(bdName);
+ final int bdId = 1;
+ whenBridgeDomainAddDelThen(0);
+ bdContext.addName(bdId, bdName);
+
rootRegistry.update(
InstanceIdentifier.create(Vpp.class),
- new VppBuilder().setBridgeDomains(getBridgeDomains("bdn1")).build(),
+ new VppBuilder().setBridgeDomains(bdn1).build(),
null,
ctx);
- final byte zero = (byte) 0;
-
- verify(api).bridgeDomainAddDel(1, zero, zero, zero, zero, zero, zero);
+ verifyBridgeDomainDeleteWasInvoked(bdId);
}
@Test
@@ -148,7 +202,10 @@ public class VppTest {
@Test
public void writeUpdate() throws Exception {
- final BridgeDomains domainsBefore = getBridgeDomains("bdn1");
+ final String bdName = "bdn1";
+ final int bdn1Id = 1;
+ bdContext.addName(bdn1Id, bdName);
+ final BridgeDomains domainsBefore = getBridgeDomains(bdName);
final BridgeDomain bdn1Before = domainsBefore.getBridgeDomain().get(0);
final BridgeDomain bdn1After = new BridgeDomainBuilder(bdn1Before).setFlood(!bdn1Before.isFlood()).build();
@@ -156,16 +213,16 @@ public class VppTest {
.setBridgeDomain(Collections.singletonList(bdn1After))
.build();
+ whenBridgeDomainAddDelThen(0);
+
rootRegistry.update(
InstanceIdentifier.create(Vpp.class),
new VppBuilder().setBridgeDomains(domainsBefore).build(),
new VppBuilder().setBridgeDomains(domainsAfter).build(),
ctx);
- final int bdn1Id = 1;
-
// bdn1 is created with negated flood value
- verify(api).bridgeDomainAddDel(bdn1Id, (byte) (flood ^ 1), forward, learn, uuf, arpTerm, add);
+ verifyBridgeDomainAddDel(bdn1After, bdn1Id);
}
// TODO test unkeyed list
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/VppUtils.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/VppUtils.java
index cb74314e3..4b3eb5adc 100644
--- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/VppUtils.java
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/VppUtils.java
@@ -19,10 +19,11 @@ package io.fd.honeycomb.v3po.translate.v3po.vpp;
import io.fd.honeycomb.v3po.translate.impl.write.CompositeChildWriter;
import io.fd.honeycomb.v3po.translate.impl.write.CompositeListWriter;
import io.fd.honeycomb.v3po.translate.impl.write.CompositeRootWriter;
+import io.fd.honeycomb.v3po.translate.util.RWUtils;
import io.fd.honeycomb.v3po.translate.util.write.NoopWriterCustomizer;
import io.fd.honeycomb.v3po.translate.util.write.ReflexiveChildWriterCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
import io.fd.honeycomb.v3po.translate.write.ChildWriter;
-import io.fd.honeycomb.v3po.translate.util.RWUtils;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nonnull;
@@ -31,7 +32,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomain;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomainKey;
import org.opendaylight.yangtools.yang.binding.ChildOf;
-import org.openvpp.vppjapi.vppApi;
+import org.openvpp.jvpp.future.FutureJVpp;
final class VppUtils {
@@ -40,11 +41,11 @@ final class VppUtils {
/**
* Create root Vpp writer with all its children wired
*/
- static CompositeRootWriter<Vpp> getVppWriter(@Nonnull final vppApi vppApi) {
+ static CompositeRootWriter<Vpp> getVppWriter(@Nonnull final FutureJVpp vppApi, final NamingContext bdContext) {
final CompositeListWriter<BridgeDomain, BridgeDomainKey> bridgeDomainWriter = new CompositeListWriter<>(
BridgeDomain.class,
- new BridgeDomainCustomizer(vppApi));
+ new BridgeDomainCustomizer(vppApi, bdContext));
final ChildWriter<BridgeDomains> bridgeDomainsReader = new CompositeChildWriter<>(
BridgeDomains.class,
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/BridgeDomainCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/BridgeDomainCustomizerTest.java
new file mode 100644
index 000000000..c482c4485
--- /dev/null
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/BridgeDomainCustomizerTest.java
@@ -0,0 +1,59 @@
+/*
+ * 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.vppstate;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import io.fd.honeycomb.v3po.translate.spi.read.RootReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.test.ListReaderCustomizerTest;
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
+import java.util.Collections;
+import java.util.List;
+import org.junit.Test;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.BridgeDomainsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomain;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomainBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomainKey;
+
+public class BridgeDomainCustomizerTest extends ListReaderCustomizerTest<BridgeDomain, BridgeDomainKey, BridgeDomainBuilder> {
+
+ private NamingContext bdContext;
+ private NamingContext interfacesContext;
+
+ public BridgeDomainCustomizerTest() {
+ super(BridgeDomain.class);
+ }
+
+ @Override
+ public void setUpBefore() {
+ bdContext = new NamingContext("generatedBdName");
+ interfacesContext = new NamingContext("generatedIfaceName");
+ }
+
+ @Test
+ public void testMerge() throws Exception {
+ final BridgeDomainsBuilder builder = mock(BridgeDomainsBuilder.class);
+ final List<BridgeDomain> value = Collections.emptyList();
+ getCustomizer().merge(builder, value);
+ verify(builder).setBridgeDomain(value);
+ }
+
+ @Override
+ protected RootReaderCustomizer<BridgeDomain, BridgeDomainBuilder> initCustomizer() {
+ return new BridgeDomainCustomizer(api, bdContext, interfacesContext);
+ }
+} \ No newline at end of file
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VersionCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VersionCustomizerTest.java
new file mode 100644
index 000000000..03b923102
--- /dev/null
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VersionCustomizerTest.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.vppstate;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.test.ChildReaderCustomizerTest;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
+import org.junit.Test;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppStateBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.Version;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.VersionBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.openvpp.jvpp.dto.ShowVersion;
+import org.openvpp.jvpp.dto.ShowVersionReply;
+
+public class VersionCustomizerTest extends ChildReaderCustomizerTest<Version, VersionBuilder> {
+
+ public VersionCustomizerTest() {
+ super(Version.class);
+ }
+
+ @Override
+ protected ChildReaderCustomizer<Version, VersionBuilder> initCustomizer() {
+ return new VersionCustomizer(api);
+ }
+
+ @Test
+ public void testMerge() {
+ final VppStateBuilder builder = mock(VppStateBuilder.class);
+ final Version value = mock(Version.class);
+ getCustomizer().merge(builder, value);
+ verify(builder).setVersion(value);
+ }
+
+ @Test
+ public void testReadCurrentAttributes() throws Exception {
+ final CompletionStage<ShowVersionReply> replyCS = mock(CompletionStage.class);
+ final CompletableFuture<ShowVersionReply> replyFuture = mock(CompletableFuture.class);
+ when(replyCS.toCompletableFuture()).thenReturn(replyFuture);
+ final ShowVersionReply reply = new ShowVersionReply();
+ reply.retval = 0;
+ reply.version = new byte[]{};
+ reply.program = new byte[]{};
+ reply.buildDate = new byte[]{};
+ reply.buildDirectory = new byte[]{};
+ when(replyFuture.get()).thenReturn(reply);
+ when(api.showVersion(any(ShowVersion.class))).thenReturn(replyCS);
+
+ getCustomizer().readCurrentAttributes(InstanceIdentifier.create(Version.class), new VersionBuilder(), ctx);
+
+ verify(api).showVersion(any(ShowVersion.class));
+ }
+} \ No newline at end of file
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VppStateTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VppStateTest.java
index 6f53f6519..bf1d12152 100644
--- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VppStateTest.java
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VppStateTest.java
@@ -19,27 +19,30 @@ package io.fd.honeycomb.v3po.translate.v3po.vppstate;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.mockito.MockitoAnnotations.initMocks;
import com.google.common.base.Optional;
-import com.google.common.base.Predicate;
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.util.read.DelegatingReaderRegistry;
import io.fd.honeycomb.v3po.translate.read.ReadContext;
import io.fd.honeycomb.v3po.translate.read.Reader;
+import io.fd.honeycomb.v3po.translate.util.read.DelegatingReaderRegistry;
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.ExecutionException;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Matchers;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
+import org.mockito.Mock;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppState;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppStateBuilder;
@@ -53,131 +56,123 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.bridge.domain.L2FibKey;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.openvpp.vppjapi.vppApi;
-import org.openvpp.vppjapi.vppBridgeDomainDetails;
-import org.openvpp.vppjapi.vppBridgeDomainInterfaceDetails;
-import org.openvpp.vppjapi.vppL2Fib;
-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;
-
-@RunWith(PowerMockRunner.class)
-@SuppressStaticInitializationFor("org.openvpp.vppjapi.vppConn")
-@PrepareForTest(vppApi.class)
+import org.openvpp.jvpp.dto.BridgeDomainDetails;
+import org.openvpp.jvpp.dto.BridgeDomainDetailsReplyDump;
+import org.openvpp.jvpp.dto.BridgeDomainDump;
+import org.openvpp.jvpp.dto.L2FibTableDump;
+import org.openvpp.jvpp.dto.L2FibTableEntry;
+import org.openvpp.jvpp.dto.L2FibTableEntryReplyDump;
+import org.openvpp.jvpp.dto.ShowVersion;
+import org.openvpp.jvpp.dto.ShowVersionReply;
+import org.openvpp.jvpp.future.FutureJVpp;
+
public class VppStateTest {
- public static final vppVersion VERSION = new vppVersion("test", "1", "2", "33");
+ @Mock
+ private FutureJVpp api;
+ @Mock
+ private ReadContext ctx;
+
+ private NamingContext bdContext;
+ private NamingContext interfaceContext;
- private vppApi api;
private CompositeRootReader<VppState, VppStateBuilder> vppStateReader;
private DelegatingReaderRegistry readerRegistry;
- private vppBridgeDomainDetails bdDetails;
- private vppBridgeDomainDetails bdDetails2;
- private ReadContext ctx;
@Before
public void setUp() throws Exception {
- api = PowerMockito.mock(vppApi.class);
-
- ctx = mock(ReadContext.class);
-
- bdDetails = new vppBridgeDomainDetails();
- setIfcs(bdDetails);
- setBaseAttrs(bdDetails, "bdn1", 1);
-
- bdDetails2 = new vppBridgeDomainDetails();
- setIfcs(bdDetails2);
- setBaseAttrs(bdDetails2, "bdn2", 2);
-
- final vppL2Fib[] l2Fibs = getL2Fibs();
- PowerMockito.doReturn(l2Fibs).when(api).l2FibTableDump(Matchers.anyInt());
- PowerMockito.doAnswer(new Answer<vppBridgeDomainDetails>() {
-
- @Override
- public vppBridgeDomainDetails answer(final InvocationOnMock invocationOnMock) throws Throwable {
- final Integer idx = (Integer) invocationOnMock.getArguments()[0];
- switch (idx) {
- case 1 : return bdDetails;
- case 2 : return bdDetails2;
- default: return null;
- }
- }
- }).when(api).getBridgeDomainDetails(Matchers.anyInt());
-
- PowerMockito.doAnswer(new Answer<Object>() {
- @Override
- public Object answer(final InvocationOnMock invocationOnMock) throws Throwable {
- final String name = (String) invocationOnMock.getArguments()[0];
- switch (name) {
- case "bdn1" : return 1;
- case "bdn2" : return 2;
- default: return null;
- }
- }
- }).when(api).bridgeDomainIdFromName(anyString());
- PowerMockito.doReturn(new int[] {1, 2}).when(api).bridgeDomainDump(Matchers.anyInt());
- PowerMockito.doReturn(VERSION).when(api).getVppVersion();
- vppStateReader = VppStateUtils.getVppStateReader(api);
+ initMocks(this);
+
+ bdContext = new NamingContext("generatedBdName");
+ interfaceContext = new NamingContext("generatedInterfaceName");
+ vppStateReader = VppStateTestUtils.getVppStateReader(api, bdContext, interfaceContext);
readerRegistry = new DelegatingReaderRegistry(Collections.<Reader<? extends DataObject>>singletonList(vppStateReader));
}
- private vppL2Fib[] getL2Fibs() {
- return new vppL2Fib[] {
- new vppL2Fib(new byte[]{1,2,3,4,5,6}, true, "ifc1", true, true),
- new vppL2Fib(new byte[]{2,2,3,4,5,6}, true, "ifc2", true, true),
- };
+ private static Version getVersion() {
+ return new VersionBuilder()
+ .setName("test")
+ .setBuildDirectory("1")
+ .setBranch("2")
+ .setBuildDate("3")
+ .build();
}
- private void setIfcs(final vppBridgeDomainDetails bdDetails) {
- final vppBridgeDomainInterfaceDetails ifcDetails = new vppBridgeDomainInterfaceDetails();
- ifcDetails.interfaceName = "ifc";
- ifcDetails.splitHorizonGroup = 2;
- bdDetails.interfaces = new vppBridgeDomainInterfaceDetails[] {ifcDetails};
+ private void whenShowVersionThenReturn(int retval, Version version) throws ExecutionException, InterruptedException {
+ final CompletionStage<ShowVersionReply> replyCS = mock(CompletionStage.class);
+ final CompletableFuture<ShowVersionReply> replyFuture = mock(CompletableFuture.class);
+ when(replyCS.toCompletableFuture()).thenReturn(replyFuture);
+ final ShowVersionReply reply = new ShowVersionReply();
+ reply.retval = 0; // success
+ reply.buildDate = version.getBuildDate().getBytes();
+ reply.program = version.getName().getBytes();
+ reply.version = version.getBranch().getBytes();
+ reply.buildDirectory = version.getBuildDirectory().getBytes();
+ when(replyFuture.get()).thenReturn(reply);
+ when(api.showVersion(any(ShowVersion.class))).thenReturn(replyCS);
}
- private void setBaseAttrs(final vppBridgeDomainDetails bdDetails, final String bdn, final int i) {
- bdDetails.name = bdn;
- bdDetails.arpTerm = true;
- bdDetails.bdId = i;
- bdDetails.bviInterfaceName = "ifc";
- bdDetails.flood = true;
- bdDetails.forward = true;
- bdDetails.learn = true;
- bdDetails.uuFlood = true;
+ private void whenL2FibTableDumpThenReturn(final List<L2FibTableEntry> entryList) throws ExecutionException, InterruptedException {
+ final CompletionStage<L2FibTableEntryReplyDump> replyCS = mock(CompletionStage.class);
+ final CompletableFuture<L2FibTableEntryReplyDump> replyFuture = mock(CompletableFuture.class);
+ when(replyCS.toCompletableFuture()).thenReturn(replyFuture);
+ final L2FibTableEntryReplyDump reply = new L2FibTableEntryReplyDump();
+ reply.l2FibTableEntry = entryList;
+ when(replyFuture.get()).thenReturn(reply);
+ when(api.l2FibTableDump(any(L2FibTableDump.class))).thenReturn(replyCS);
+ }
+
+ private void whenBridgeDomainDumpThenReturn(final List<BridgeDomainDetails> bdList) throws ExecutionException, InterruptedException {
+ final CompletionStage<BridgeDomainDetailsReplyDump> replyCS = mock(CompletionStage.class);
+ final CompletableFuture<BridgeDomainDetailsReplyDump> replyFuture = mock(CompletableFuture.class);
+ when(replyCS.toCompletableFuture()).thenReturn(replyFuture);
+ final BridgeDomainDetailsReplyDump reply = new BridgeDomainDetailsReplyDump();
+ reply.bridgeDomainDetails = bdList;
+ when(replyFuture.get()).thenReturn(reply);
+
+ doAnswer(invocation -> {
+ BridgeDomainDump request = (BridgeDomainDump)invocation.getArguments()[0];
+ if (request.bdId == -1) {
+ reply.bridgeDomainDetails = bdList;
+ } else {
+ reply.bridgeDomainDetails = Collections.singletonList(bdList.get(request.bdId));
+ }
+ return replyCS;
+ }).when(api).bridgeDomainDump(any(BridgeDomainDump.class));
}
@Test
public void testReadAll() throws Exception {
+ final Version version = getVersion();
+ whenShowVersionThenReturn(0, version);
+
+ final List<BridgeDomainDetails> bdList = Arrays.asList(new BridgeDomainDetails(), new BridgeDomainDetails());
+ whenBridgeDomainDumpThenReturn(bdList);
+
final Multimap<InstanceIdentifier<? extends DataObject>, ? extends DataObject> dataObjects = readerRegistry.readAll(ctx);
assertEquals(dataObjects.size(), 1);
- final DataObject dataObject = Iterables.getOnlyElement(dataObjects.get(Iterables.getOnlyElement(dataObjects.keySet())));
- assertTrue(dataObject instanceof VppState);
- assertVersion((VppState) dataObject);
- assertEquals(2, ((VppState) dataObject).getBridgeDomains().getBridgeDomain().size());
- }
-
- private void assertVersion(final VppState dataObject) {
- assertEquals(
- new VersionBuilder()
- .setName("test")
- .setBuildDirectory("1")
- .setBranch("2")
- .setBuildDate("33")
- .build(),
- dataObject.getVersion());
+ final VppState dataObject = (VppState)Iterables.getOnlyElement(dataObjects.get(Iterables.getOnlyElement(dataObjects.keySet())));
+ assertEquals(version, dataObject.getVersion());
+ assertEquals(2, dataObject.getBridgeDomains().getBridgeDomain().size());
}
@Test
public void testReadSpecific() throws Exception {
+ final Version version = getVersion();
+ whenShowVersionThenReturn(0, version);
+ whenBridgeDomainDumpThenReturn(Collections.emptyList());
+
final Optional<? extends DataObject> read = readerRegistry.read(InstanceIdentifier.create(VppState.class), ctx);
assertTrue(read.isPresent());
- assertVersion((VppState) read.get());
+ assertEquals(version, ((VppState) read.get()).getVersion());
}
@Test
public void testReadBridgeDomains() throws Exception {
+ final Version version = getVersion();
+ whenShowVersionThenReturn(0, version);
+ whenBridgeDomainDumpThenReturn(Collections.singletonList(new BridgeDomainDetails()));
+
VppState readRoot = (VppState) readerRegistry.read(InstanceIdentifier.create(VppState.class), ctx).get();
Optional<? extends DataObject> read =
@@ -191,6 +186,16 @@ public class VppStateTest {
*/
@Test
public void testReadL2Fib() throws Exception {
+ final BridgeDomainDetails bd = new BridgeDomainDetails();
+ bd.bdId = 0;
+ final String bdName = "bdn1";
+ bdContext.addName(bd.bdId, bdName);
+ whenBridgeDomainDumpThenReturn(Collections.singletonList(bd));
+ final L2FibTableEntry l2FibEntry = new L2FibTableEntry();
+ l2FibEntry.bdId = 0;
+ l2FibEntry.mac = 0x0605040302010000L;
+ whenL2FibTableDumpThenReturn(Collections.singletonList(l2FibEntry));
+
// Deep child without a dedicated reader with specific l2fib key
Optional<? extends DataObject> read =
readerRegistry.read(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child(
@@ -208,10 +213,14 @@ public class VppStateTest {
@Test
public void testReadBridgeDomainAll() throws Exception {
+ final Version version = getVersion();
+ whenShowVersionThenReturn(0, version);
+ whenBridgeDomainDumpThenReturn(Collections.singletonList(new BridgeDomainDetails()));
+
VppState readRoot = (VppState) readerRegistry.read(InstanceIdentifier.create(VppState.class), ctx).get();
final CompositeListReader<BridgeDomain, BridgeDomainKey, BridgeDomainBuilder> bridgeDomainReader =
- VppStateUtils.getBridgeDomainReader(api);
+ VppStateTestUtils.getBridgeDomainReader(api, bdContext, interfaceContext);
final List<BridgeDomain> read =
bridgeDomainReader.readList(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child(
@@ -222,24 +231,25 @@ public class VppStateTest {
@Test
public void testReadBridgeDomain() throws Exception {
+ final BridgeDomainDetails bd = new BridgeDomainDetails();
+ bd.bdId = 0;
+ final String bdName = "bdn1";
+ bdContext.addName(bd.bdId, bdName);
+ whenBridgeDomainDumpThenReturn(Collections.singletonList(bd));
+ whenShowVersionThenReturn(0, getVersion());
+
VppState readRoot = (VppState) readerRegistry.read(InstanceIdentifier.create(VppState.class), ctx).get();
final Optional<? extends DataObject> read =
readerRegistry.read(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child(
- BridgeDomain.class, new BridgeDomainKey("bdn1")), ctx);
+ BridgeDomain.class, new BridgeDomainKey(bdName)), ctx);
assertTrue(read.isPresent());
- assertEquals(Iterables.find(readRoot.getBridgeDomains().getBridgeDomain(), new Predicate<BridgeDomain>() {
- @Override
- public boolean apply(final BridgeDomain input) {
- return input.getKey().getName().equals("bdn1");
- }
- }), read.get());
+ assertEquals(Iterables.find(readRoot.getBridgeDomains().getBridgeDomain(),
+ input -> input.getKey().getName().equals(bdName)), read.get());
}
- // FIXME
- @Ignore("Bridge domain customizer does not check whether the bd exists or not and fails with NPE, add it there")
- @Test
+ @Test(expected = IllegalArgumentException.class)
public void testReadBridgeDomainNotExisting() throws Exception {
final Optional<? extends DataObject> read =
readerRegistry.read(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child(
@@ -249,6 +259,8 @@ public class VppStateTest {
@Test
public void testReadVersion() throws Exception {
+ whenShowVersionThenReturn(0, getVersion());
+ whenBridgeDomainDumpThenReturn(Collections.emptyList());
VppState readRoot = (VppState) readerRegistry.read(InstanceIdentifier.create(VppState.class), ctx).get();
Optional<? extends DataObject> read =
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VppStateUtils.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VppStateTestUtils.java
index 5c619d84d..688f75911 100644
--- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VppStateUtils.java
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VppStateTestUtils.java
@@ -19,10 +19,11 @@ package io.fd.honeycomb.v3po.translate.v3po.vppstate;
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.util.RWUtils;
import io.fd.honeycomb.v3po.translate.util.read.ReflexiveChildReaderCustomizer;
import io.fd.honeycomb.v3po.translate.util.read.ReflexiveRootReaderCustomizer;
-import io.fd.honeycomb.v3po.translate.util.RWUtils;
-import io.fd.honeycomb.v3po.translate.read.ChildReader;
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nonnull;
@@ -35,43 +36,47 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomainBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomainKey;
import org.opendaylight.yangtools.yang.binding.ChildOf;
-import org.openvpp.vppjapi.vppApi;
+import org.openvpp.jvpp.future.FutureJVpp;
-final class VppStateUtils {
+final class VppStateTestUtils {
- public VppStateUtils() {}
+ public VppStateTestUtils() {
+ }
/**
* Create root VppState reader with all its children wired
*/
- static CompositeRootReader<VppState, VppStateBuilder> getVppStateReader(@Nonnull final vppApi vppApi) {
+ static CompositeRootReader<VppState, VppStateBuilder> getVppStateReader(@Nonnull final FutureJVpp futureJVpp,
+ @Nonnull final NamingContext bdContext,
+ @Nonnull final NamingContext interfaceContext) {
final ChildReader<Version> versionReader = new CompositeChildReader<>(
- Version.class, new VersionCustomizer(vppApi));
+ Version.class, new VersionCustomizer(futureJVpp));
final CompositeListReader<BridgeDomain, BridgeDomainKey, BridgeDomainBuilder> bridgeDomainReader =
- getBridgeDomainReader(vppApi);
+ getBridgeDomainReader(futureJVpp, bdContext, interfaceContext);
final ChildReader<BridgeDomains> bridgeDomainsReader = new CompositeChildReader<>(
- BridgeDomains.class,
- RWUtils.singletonChildReaderList(bridgeDomainReader),
- new ReflexiveChildReaderCustomizer<>(BridgeDomainsBuilder.class));
+ BridgeDomains.class,
+ RWUtils.singletonChildReaderList(bridgeDomainReader),
+ new ReflexiveChildReaderCustomizer<>(BridgeDomainsBuilder.class));
final List<ChildReader<? extends ChildOf<VppState>>> childVppReaders = new ArrayList<>();
childVppReaders.add(versionReader);
childVppReaders.add(bridgeDomainsReader);
return new CompositeRootReader<>(
- VppState.class,
- childVppReaders,
- RWUtils.<VppState>emptyAugReaderList(),
- new ReflexiveRootReaderCustomizer<>(VppStateBuilder.class));
+ VppState.class,
+ childVppReaders,
+ RWUtils.<VppState>emptyAugReaderList(),
+ new ReflexiveRootReaderCustomizer<>(VppStateBuilder.class));
}
static CompositeListReader<BridgeDomain, BridgeDomainKey, BridgeDomainBuilder> getBridgeDomainReader(
- final @Nonnull vppApi vppApi) {
+ final @Nonnull FutureJVpp futureJVpp, @Nonnull final NamingContext bdContext,
+ @Nonnull final NamingContext interfaceContext) {
return new CompositeListReader<>(
- BridgeDomain.class,
- new BridgeDomainCustomizer(vppApi));
+ BridgeDomain.class,
+ new BridgeDomainCustomizer(futureJVpp, bdContext, interfaceContext));
}
}