diff options
46 files changed, 988 insertions, 1039 deletions
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/InterconnectionWriteUtils.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/InterconnectionWriteUtils.java index 1463ca9e5..917d2e7ee 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/InterconnectionWriteUtils.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/InterconnectionWriteUtils.java @@ -21,7 +21,6 @@ import static java.util.Objects.requireNonNull; import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext; import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils; -import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException; import io.fd.honeycomb.v3po.translate.write.WriteContext; import io.fd.honeycomb.v3po.translate.write.WriteFailedException; import java.util.concurrent.CompletionStage; @@ -31,6 +30,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.l2.base.attributes.interconnection.XconnectBased; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.VppBaseCallException; import org.openvpp.jvpp.dto.SwInterfaceSetL2Bridge; import org.openvpp.jvpp.dto.SwInterfaceSetL2BridgeReply; import org.openvpp.jvpp.dto.SwInterfaceSetL2Xconnect; @@ -61,27 +61,31 @@ final class InterconnectionWriteUtils { void setInterconnection(final InstanceIdentifier<? extends DataObject> id, final int swIfIndex, final String ifcName, final Interconnection ic, final WriteContext writeContext) - throws VppApiInvocationException, WriteFailedException { - if (ic == null) { // TODO in case of update we should delete interconnection - LOG.trace("Interconnection is not set. Skipping"); - } else if (ic instanceof XconnectBased) { - setXconnectBasedL2(swIfIndex, ifcName, (XconnectBased) ic, writeContext); - } else if (ic instanceof BridgeBased) { - setBridgeBasedL2(swIfIndex, ifcName, (BridgeBased) ic, writeContext); - } else { - // FIXME how does choice extensibility work - // FIXME it is not even possible to create a dedicated customizer for Interconnection, since it's not a DataObject - // FIXME we might need a choice customizer - // THis choice is already from augment, so its probably not possible to augment augmented choice - LOG.error("Unable to handle Interconnection of type {}", ic.getClass()); - throw new WriteFailedException(id, "Unable to handle Interconnection of type " + ic.getClass()); + throws WriteFailedException { + try { + if (ic == null) { // TODO in case of update we should delete interconnection + LOG.trace("Interconnection is not set. Skipping"); + } else if (ic instanceof XconnectBased) { + setXconnectBasedL2(swIfIndex, ifcName, (XconnectBased) ic, writeContext); + } else if (ic instanceof BridgeBased) { + setBridgeBasedL2(swIfIndex, ifcName, (BridgeBased) ic, writeContext); + } else { + // FIXME how does choice extensibility work + // FIXME it is not even possible to create a dedicated customizer for Interconnection, since it's not a DataObject + // FIXME we might need a choice customizer + // THis choice is already from augment, so its probably not possible to augment augmented choice + LOG.error("Unable to handle Interconnection of type {}", ic.getClass()); + throw new WriteFailedException(id, "Unable to handle Interconnection of type " + ic.getClass()); + } + } catch (VppBaseCallException e) { + LOG.warn("Failed to update bridge/xconnect based interconnection flags for: {}, interconnection: {}", ifcName, ic); + throw new WriteFailedException(id, "Unable to handle Interconnection of type " + ic.getClass(), e); } } private void setBridgeBasedL2(final int swIfIndex, final String ifcName, final BridgeBased bb, final WriteContext writeContext) - throws VppApiInvocationException { - + throws VppBaseCallException { LOG.debug("Setting bridge based interconnection(bridge-domain={}) for interface: {}", bb.getBridgeDomain(), ifcName); @@ -101,12 +105,7 @@ final class InterconnectionWriteUtils { final SwInterfaceSetL2BridgeReply reply = TranslateUtils.getReply(swInterfaceSetL2BridgeReplyCompletionStage.toCompletableFuture()); - if (reply.retval < 0) { - LOG.warn("Failed to update bridge based interconnection flags for: {}, interconnection: {}", ifcName, bb); - throw new VppApiInvocationException("swInterfaceSetL2Bridge", reply.context, reply.retval); - } else { - LOG.debug("Bridge based interconnection updated successfully for: {}, interconnection: {}", ifcName, bb); - } + LOG.debug("Bridge based interconnection updated successfully for: {}, interconnection: {}", ifcName, bb); } private SwInterfaceSetL2Bridge getL2BridgeRequest(final int swIfIndex, final int bdId, final byte shg, @@ -122,7 +121,7 @@ final class InterconnectionWriteUtils { private void setXconnectBasedL2(final int swIfIndex, final String ifcName, final XconnectBased ic, final WriteContext writeContext) - throws VppApiInvocationException { + throws VppBaseCallException { String outSwIfName = ic.getXconnectOutgoingInterface(); LOG.debug("Setting xconnect based interconnection(outgoing ifc={}) for interface: {}", outSwIfName, ifcName); @@ -136,13 +135,7 @@ final class InterconnectionWriteUtils { .swInterfaceSetL2Xconnect(getL2XConnectRequest(swIfIndex, outSwIfIndex, (byte) 1 /* enable */)); final SwInterfaceSetL2XconnectReply reply = TranslateUtils.getReply(swInterfaceSetL2XconnectReplyCompletionStage.toCompletableFuture()); - - if (reply.retval < 0) { - LOG.warn("Failed to update xconnect based interconnection flags for: {}, interconnection: {}", ifcName, ic); - throw new VppApiInvocationException("swInterfaceSetL2Xconnect", reply.context, reply.retval); - } else { - LOG.debug("Xconnect based interconnection updated successfully for: {}, interconnection: {}", ifcName, ic); - } + LOG.debug("Xconnect based interconnection updated successfully for: {}, interconnection: {}", ifcName, ic); } private SwInterfaceSetL2Xconnect getL2XConnectRequest(final int rxIfc, final int txIfc, 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 3a4638d90..81f5c7dd2 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,26 +18,27 @@ package io.fd.honeycomb.v3po.translate.v3po.interfaces; import com.google.common.base.Optional; import io.fd.honeycomb.v3po.translate.spi.write.ListWriterCustomizer; -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.util.NamingContext; import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils; import io.fd.honeycomb.v3po.translate.write.WriteContext; import io.fd.honeycomb.v3po.translate.write.WriteFailedException; -import java.util.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.jvpp.VppBaseCallException; 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; +import javax.annotation.Nonnull; +import java.util.List; +import java.util.concurrent.CompletionStage; + /** * Ietf interface write customizer that only caches interface objects for child writers */ @@ -59,7 +60,7 @@ public class InterfaceCustomizer extends FutureJVppCustomizer implements ListWri try { setInterface(id, dataAfter, writeContext); - } catch (VppApiInvocationException e) { + } catch (VppBaseCallException e) { LOG.warn("Update of VppInterfaceAugment failed", e); throw new WriteFailedException.CreateFailedException(id, dataAfter, e); } @@ -74,7 +75,7 @@ public class InterfaceCustomizer extends FutureJVppCustomizer implements ListWri try { updateInterface(id, dataBefore, dataAfter, writeContext); - } catch (VppApiInvocationException e) { + } catch (VppBaseCallException e) { LOG.warn("Update of VppInterfaceAugment failed", e); throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, e); } @@ -98,13 +99,13 @@ public class InterfaceCustomizer extends FutureJVppCustomizer implements ListWri private void setInterface(final InstanceIdentifier<Interface> id, final Interface swIf, final WriteContext writeContext) - throws VppApiInvocationException, WriteFailedException { + throws VppBaseCallException { LOG.debug("Setting interface: {} to: {}", id, swIf); setInterfaceAttributes(swIf, swIf.getName(), writeContext); } private void setInterfaceAttributes(final Interface swIf, final String swIfName, final WriteContext writeContext) - throws VppApiInvocationException { + throws VppBaseCallException { setInterfaceFlags(swIfName, interfaceContext.getIndex(swIfName, writeContext.getMappingContext()), swIf.isEnabled() ? (byte) 1 : (byte) 0); @@ -112,27 +113,21 @@ public class InterfaceCustomizer extends FutureJVppCustomizer implements ListWri private void updateInterface(final InstanceIdentifier<Interface> id, final Interface dataBefore, - final Interface dataAfter, final WriteContext writeContext) throws VppApiInvocationException { + final Interface dataAfter, final WriteContext writeContext) throws VppBaseCallException { LOG.debug("Updating interface:{} to: {}", id, dataAfter); setInterfaceAttributes(dataAfter, dataAfter.getName(), writeContext); } private void setInterfaceFlags(final String swIfName, final int swIfIndex, final byte enabled) - throws VppApiInvocationException { + throws VppBaseCallException { final CompletionStage<SwInterfaceSetFlagsReply> swInterfaceSetFlagsReplyFuture = getFutureJVpp().swInterfaceSetFlags( getSwInterfaceSetFlagsInput(swIfIndex, enabled, (byte) 0 /* deleted */)); LOG.debug("Updating interface flags for: {}, index: {}, enabled: {}", swIfName, swIfIndex, enabled); SwInterfaceSetFlagsReply reply = TranslateUtils.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: {}", + LOG.debug("Interface flags updated successfully for: {}, index: {}, enabled: {}, ctxId: {}", swIfName, swIfIndex, enabled, reply.context); - } } private SwInterfaceSetFlags getSwInterfaceSetFlagsInput(final int swIfIndex, final byte enabled, final byte deleted) { 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 c4c6ecc0a..099e721ab 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 @@ -20,19 +20,23 @@ import com.google.common.base.Optional; import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer; 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.write.WriteContext; import io.fd.honeycomb.v3po.translate.write.WriteFailedException; -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.L2; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.VppBaseCallException; import org.openvpp.jvpp.future.FutureJVpp; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.annotation.Nonnull; +import java.util.concurrent.CompletionStage; + +import static com.google.common.base.Preconditions.checkArgument; + public class L2Customizer extends FutureJVppCustomizer implements ChildWriterCustomizer<L2> { private static final Logger LOG = LoggerFactory.getLogger(L2Customizer.class); @@ -59,12 +63,7 @@ public class L2Customizer extends FutureJVppCustomizer implements ChildWriterCus final String ifcName = id.firstKeyOf(Interface.class).getName(); final int swIfc = interfaceContext.getIndex(ifcName, writeContext.getMappingContext()); - try { - setL2(id, swIfc, ifcName, dataAfter, writeContext); - } catch (VppApiInvocationException e) { - LOG.warn("Write of L2 failed", e); - throw new WriteFailedException.CreateFailedException(id, dataAfter, e); - } + setL2(id, swIfc, ifcName, dataAfter, writeContext); } @Override @@ -75,12 +74,7 @@ public class L2Customizer extends FutureJVppCustomizer implements ChildWriterCus final String ifcName = id.firstKeyOf(Interface.class).getName(); final int swIfc = interfaceContext.getIndex(ifcName, writeContext.getMappingContext()); // TODO handle update properly (if possible) - try { - setL2(id, swIfc, ifcName, dataAfter, writeContext); - } catch (VppApiInvocationException e) { - LOG.warn("Update of L2 failed", e); - throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, e); - } + setL2(id, swIfc, ifcName, dataAfter, writeContext); } @Override @@ -91,7 +85,7 @@ public class L2Customizer extends FutureJVppCustomizer implements ChildWriterCus private void setL2(final InstanceIdentifier<L2> id, final int swIfIndex, final String ifcName, final L2 l2, final WriteContext writeContext) - throws VppApiInvocationException, WriteFailedException { + throws WriteFailedException { LOG.debug("Setting L2 for interface: {}", ifcName); // Nothing besides interconnection here icWriteUtils.setInterconnection(id, swIfIndex, ifcName, l2.getInterconnection(), writeContext); diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/RewriteCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/RewriteCustomizer.java index 2309344c8..f07d163b4 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/RewriteCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/RewriteCustomizer.java @@ -16,22 +16,12 @@ package io.fd.honeycomb.v3po.translate.v3po.interfaces; -import static io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils.booleanToByte; - import com.google.common.base.Optional; import com.google.common.base.Preconditions; import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer; -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.SubInterfaceUtils; -import io.fd.honeycomb.v3po.translate.v3po.util.TagRewriteOperation; -import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils; -import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException; +import io.fd.honeycomb.v3po.translate.v3po.util.*; import io.fd.honeycomb.v3po.translate.write.WriteContext; import io.fd.honeycomb.v3po.translate.write.WriteFailedException; -import java.util.List; -import java.util.concurrent.CompletionStage; -import javax.annotation.Nonnull; import org.apache.commons.lang3.builder.ReflectionToStringBuilder; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527._802dot1q; @@ -42,12 +32,19 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.tag.rewrite.PushTags; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.VppBaseCallException; import org.openvpp.jvpp.dto.L2InterfaceVlanTagRewrite; import org.openvpp.jvpp.dto.L2InterfaceVlanTagRewriteReply; import org.openvpp.jvpp.future.FutureJVpp; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.annotation.Nonnull; +import java.util.List; +import java.util.concurrent.CompletionStage; + +import static io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils.booleanToByte; + /** * Writer Customizer responsible for vlan tag rewrite.<br> Sends {@code l2_interface_vlan_tag_rewrite} message to * VPP.<br> Equivalent of invoking {@code vppctl set interface l2 tag-rewrite} command. @@ -75,10 +72,11 @@ public class RewriteCustomizer extends FutureJVppCustomizer implements ChildWrit public void writeCurrentAttributes(final InstanceIdentifier<Rewrite> id, final Rewrite dataAfter, final WriteContext writeContext) throws WriteFailedException.CreateFailedException { - + final String subifName = getSubInterfaceName(id); try { - setTagRewrite(getSubInterfaceName(id), dataAfter, writeContext); - } catch (VppApiInvocationException e) { + setTagRewrite(subifName, dataAfter, writeContext); + } catch (VppBaseCallException e) { + LOG.warn("Failed to write interface {}(id=): {}", subifName, writeContext, dataAfter); throw new WriteFailedException.CreateFailedException(id, dataAfter, e); } } @@ -89,7 +87,7 @@ public class RewriteCustomizer extends FutureJVppCustomizer implements ChildWrit } private void setTagRewrite(final String ifname, final Rewrite rewrite, final WriteContext writeContext) - throws VppApiInvocationException { + throws VppBaseCallException { final int swIfIndex = interfaceContext.getIndex(ifname, writeContext.getMappingContext()); LOG.debug("Setting tag rewrite for interface {}(id=): {}", ifname, swIfIndex, rewrite); @@ -98,12 +96,7 @@ public class RewriteCustomizer extends FutureJVppCustomizer implements ChildWrit final L2InterfaceVlanTagRewriteReply reply = TranslateUtils.getReply(replyCompletionStage.toCompletableFuture()); - if (reply.retval < 0) { - LOG.debug("Failed to set tag rewrite for interface {}(id=): {}", ifname, swIfIndex, rewrite); - throw new VppApiInvocationException("l2InterfaceVlanTagRewrite", reply.context, reply.retval); - } else { - LOG.debug("Tag rewrite for interface {}(id=) set successfully: {}", ifname, swIfIndex, rewrite); - } + LOG.debug("Tag rewrite for interface {}(id=) set successfully: {}", ifname, swIfIndex, rewrite); } private L2InterfaceVlanTagRewrite getTagRewriteRequest(final int swIfIndex, final Rewrite rewrite) { @@ -142,9 +135,11 @@ public class RewriteCustomizer extends FutureJVppCustomizer implements ChildWrit @Nonnull final Rewrite dataBefore, @Nonnull final Rewrite dataAfter, @Nonnull final WriteContext writeContext) throws WriteFailedException { + final String subifName = getSubInterfaceName(id); try { - setTagRewrite(getSubInterfaceName(id), dataAfter, writeContext); - } catch (VppApiInvocationException e) { + setTagRewrite(subifName, dataAfter, writeContext); + } catch (VppBaseCallException e) { + LOG.warn("Failed to update interface {}(id=): {}", subifName, writeContext, dataAfter); throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, e); } } @@ -153,12 +148,13 @@ public class RewriteCustomizer extends FutureJVppCustomizer implements ChildWrit public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Rewrite> id, @Nonnull final Rewrite dataBefore, @Nonnull final WriteContext writeContext) throws WriteFailedException.DeleteFailedException { + final String subifName = getSubInterfaceName(id); try { - final String subifName = getSubInterfaceName(id); LOG.debug("Disabling tag rewrite for interface {}", subifName); final Rewrite rewrite = new RewriteBuilder().build(); // rewrite without push and pops will cause delete setTagRewrite(subifName, rewrite, writeContext); - } catch (VppApiInvocationException e) { + } catch (VppBaseCallException e) { + LOG.warn("Failed to delete interface {}(id=): {}", subifName, writeContext, dataBefore); throw new WriteFailedException.DeleteFailedException(id, e); } } 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 74aee7ae5..0621fc2e3 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 @@ -20,23 +20,24 @@ import com.google.common.base.Optional; import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer; 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.util.TranslateUtils; import io.fd.honeycomb.v3po.translate.write.WriteContext; 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.VppBaseCallException; 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; +import javax.annotation.Nonnull; +import java.util.concurrent.CompletionStage; + public class RoutingCustomizer extends FutureJVppCustomizer implements ChildWriterCustomizer<Routing> { private static final Logger LOG = LoggerFactory.getLogger(RoutingCustomizer.class); @@ -59,10 +60,11 @@ public class RoutingCustomizer extends FutureJVppCustomizer implements ChildWrit @Nonnull final Routing dataAfter, @Nonnull final WriteContext writeContext) throws WriteFailedException.CreateFailedException { + final String ifName = id.firstKeyOf(Interface.class).getName(); try { - setRouting(id.firstKeyOf(Interface.class).getName(), dataAfter, writeContext); - } catch (VppApiInvocationException e) { - LOG.warn("Update of Routing failed", e); + setRouting(ifName, dataAfter, writeContext); + } catch (VppBaseCallException e) { + LOG.warn("Failed to set routing for interface: {}, {}, vxlan: {}", ifName, writeContext, dataAfter); throw new WriteFailedException.CreateFailedException(id, dataAfter, e); } } @@ -73,11 +75,12 @@ public class RoutingCustomizer extends FutureJVppCustomizer implements ChildWrit @Nonnull final WriteContext writeContext) throws WriteFailedException.UpdateFailedException { + final String ifName = id.firstKeyOf(Interface.class).getName(); try { // TODO handle updates properly - setRouting(id.firstKeyOf(Interface.class).getName(), dataAfter, writeContext); - } catch (VppApiInvocationException e) { - LOG.warn("Update of Routing failed", e); + setRouting(ifName, dataAfter, writeContext); + } catch (VppBaseCallException e) { + LOG.warn("Failed to update routing for interface: {}, {}, vxlan: {}", ifName, writeContext, dataAfter); throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, e); } } @@ -88,7 +91,7 @@ public class RoutingCustomizer extends FutureJVppCustomizer implements ChildWrit // TODO implement delete } - private void setRouting(final String name, final Routing rt, final WriteContext writeContext) throws VppApiInvocationException { + private void setRouting(final String name, final Routing rt, final WriteContext writeContext) throws VppBaseCallException { final int swIfc = interfaceContext.getIndex(name, writeContext.getMappingContext()); LOG.debug("Setting routing for interface: {}, {}. Routing: {}", name, swIfc, rt); @@ -101,12 +104,7 @@ public class RoutingCustomizer extends FutureJVppCustomizer implements ChildWrit getFutureJVpp().swInterfaceSetTable(getInterfaceSetTableRequest(swIfc, (byte) 0, /* isIpv6 */ vrfId)); final SwInterfaceSetTableReply reply = TranslateUtils.getReply(swInterfaceSetTableReplyCompletionStage.toCompletableFuture()); - if (reply.retval < 0) { - LOG.debug("Failed to set routing for interface: {}, {}, vxlan: {}", name, swIfc, rt); - throw new VppApiInvocationException("swInterfaceSetTable", reply.context, reply.retval); - } else { - LOG.debug("Routing set successfully for interface: {}, {}, routing: {}", name, swIfc, rt); - } + LOG.debug("Routing set successfully for interface: {}, {}, routing: {}", name, swIfc, rt); } } @@ -117,5 +115,4 @@ public class RoutingCustomizer extends FutureJVppCustomizer implements ChildWrit swInterfaceSetTable.vrfId = vrfId; return swInterfaceSetTable; } - } diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceCustomizer.java index cb0a2c3df..7d24fdd7b 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceCustomizer.java @@ -16,24 +16,14 @@ package io.fd.honeycomb.v3po.translate.v3po.interfaces; -import static com.google.common.base.Preconditions.checkState; -import static io.fd.honeycomb.v3po.translate.v3po.util.SubInterfaceUtils.getSubInterfaceName; -import static io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils.booleanToByte; - import com.google.common.base.Optional; import com.google.common.base.Preconditions; import io.fd.honeycomb.v3po.translate.spi.write.ListWriterCustomizer; import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer; import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext; import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils; -import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException; import io.fd.honeycomb.v3po.translate.write.WriteContext; import io.fd.honeycomb.v3po.translate.write.WriteFailedException; -import java.util.List; -import java.util.Objects; -import java.util.concurrent.CompletionStage; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.CVlan; import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.Dot1qVlanId; import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.SVlan; @@ -50,6 +40,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.tags.Tag; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.VppBaseCallException; import org.openvpp.jvpp.dto.CreateSubif; import org.openvpp.jvpp.dto.CreateSubifReply; import org.openvpp.jvpp.dto.SwInterfaceSetFlags; @@ -58,6 +49,16 @@ import org.openvpp.jvpp.future.FutureJVpp; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.CompletionStage; + +import static com.google.common.base.Preconditions.checkState; +import static io.fd.honeycomb.v3po.translate.v3po.util.SubInterfaceUtils.getSubInterfaceName; +import static io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils.booleanToByte; + /** * Writer Customizer responsible for sub interface creation.<br> Sends {@code create_subif} message to VPP.<br> * Equivalent of invoking {@code vppclt create subif} command. @@ -87,31 +88,27 @@ public class SubInterfaceCustomizer extends FutureJVppCustomizer throws WriteFailedException.CreateFailedException { try { createSubInterface(id.firstKeyOf(Interface.class).getName(), dataAfter, writeContext); - } catch (VppApiInvocationException e) { + } catch (VppBaseCallException e) { + LOG.warn("Failed to create sub interface for: {}, subInterface: {}", id.firstKeyOf(Interface.class).getName(), dataAfter); throw new WriteFailedException.CreateFailedException(id, dataAfter, e); } } private void createSubInterface(@Nonnull final String superIfName, - @Nonnull final SubInterface subInterface, final WriteContext writeContext) - throws VppApiInvocationException { + @Nonnull final SubInterface subInterface, + final WriteContext writeContext) throws VppBaseCallException { final int superIfIndex = interfaceContext.getIndex(superIfName, writeContext.getMappingContext()); - LOG.debug("Creating sub interface of {}(id={}): subInterface={}", superIfName, superIfIndex, subInterface); final CompletionStage<CreateSubifReply> createSubifReplyCompletionStage = - getFutureJVpp().createSubif(getCreateSubifRequest(subInterface, superIfIndex)); + getFutureJVpp().createSubif(getCreateSubifRequest(subInterface, superIfIndex)); final CreateSubifReply reply = - TranslateUtils.getReply(createSubifReplyCompletionStage.toCompletableFuture()); - if (reply.retval < 0) { - LOG.debug("Failed to create sub interface for: {}, subInterface: {}", superIfName, subInterface); - throw new VppApiInvocationException("createSubif", reply.context, reply.retval); - } else { - setInterfaceState(reply.swIfIndex, booleanToByte(subInterface.isEnabled())); - interfaceContext.addName(reply.swIfIndex, - getSubInterfaceName(superIfName, Math.toIntExact(subInterface.getIdentifier())), - writeContext.getMappingContext()); - LOG.debug("Sub interface created successfully for: {}, subInterface: {}", superIfName, subInterface); - } + TranslateUtils.getReply(createSubifReplyCompletionStage.toCompletableFuture()); + + setInterfaceState(reply.swIfIndex, booleanToByte(subInterface.isEnabled())); + interfaceContext.addName(reply.swIfIndex, + getSubInterfaceName(superIfName, Math.toIntExact(subInterface.getIdentifier())), + writeContext.getMappingContext()); + LOG.debug("Sub interface created successfully for: {}, subInterface: {}", superIfName, subInterface); } private CreateSubif getCreateSubifRequest(@Nonnull final SubInterface subInterface, final int swIfIndex) { @@ -196,17 +193,19 @@ public class SubInterfaceCustomizer extends FutureJVppCustomizer LOG.debug("No state update will be performed. Ignoring config"); return; // TODO shouldn't we throw exception here (if there will be dedicated L2 customizer)? } + final String subIfaceName = getSubInterfaceName(id.firstKeyOf(Interface.class).getName(), + Math.toIntExact(dataAfter.getIdentifier())); try { - final String subIfaceName = getSubInterfaceName(id.firstKeyOf(Interface.class).getName(), - Math.toIntExact(dataAfter.getIdentifier())); setInterfaceState(interfaceContext.getIndex(subIfaceName, writeContext.getMappingContext()), booleanToByte(dataAfter.isEnabled())); - } catch (VppApiInvocationException e) { + } catch (VppBaseCallException e) { + LOG.warn("Failed to update interface state for: interface if={}, enabled: {}", + subIfaceName, booleanToByte(dataAfter.isEnabled())); throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, e); } } - private void setInterfaceState(final int swIfIndex, final byte enabled) throws VppApiInvocationException { + private void setInterfaceState(final int swIfIndex, final byte enabled) throws VppBaseCallException { final SwInterfaceSetFlags swInterfaceSetFlags = new SwInterfaceSetFlags(); swInterfaceSetFlags.swIfIndex = swIfIndex; swInterfaceSetFlags.adminUpDown = enabled; @@ -217,13 +216,8 @@ public class SubInterfaceCustomizer extends FutureJVppCustomizer LOG.debug("Updating interface state for: interface if={}, enabled: {}", swIfIndex, enabled); SwInterfaceSetFlagsReply reply = TranslateUtils.getReply(swInterfaceSetFlagsReplyFuture.toCompletableFuture()); - if (reply.retval < 0) { - LOG.warn("Failed to update interface state for: interface if={}, enabled: {}", swIfIndex, enabled); - throw new VppApiInvocationException("swInterfaceSetFlags", reply.context, reply.retval); - } else { - LOG.debug("Interface state updated successfully for: {}, index: {}, enabled: {}, ctxId: {}", - swIfIndex, enabled, reply.context); - } + LOG.debug("Interface state updated successfully for: {}, index: {}, enabled: {}, ctxId: {}", + swIfIndex, enabled, reply.context); } @Override diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceL2Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceL2Customizer.java index a1957f5a0..c621612c7 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceL2Customizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceL2Customizer.java @@ -21,7 +21,6 @@ import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer; 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.SubInterfaceUtils; -import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException; import io.fd.honeycomb.v3po.translate.write.WriteContext; import io.fd.honeycomb.v3po.translate.write.WriteFailedException; import javax.annotation.Nonnull; @@ -32,6 +31,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.L2; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.VppBaseCallException; import org.openvpp.jvpp.future.FutureJVpp; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -64,12 +64,7 @@ public class SubInterfaceL2Customizer extends FutureJVppCustomizer implements Ch throws WriteFailedException { final String subInterfaceName = getSubInterfaceName(id); final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, writeContext.getMappingContext()); - try { - setL2(id, subInterfaceIndex, subInterfaceName, dataAfter, writeContext); - } catch (VppApiInvocationException e) { - LOG.warn("Write of L2 failed", e); - throw new WriteFailedException.CreateFailedException(id, dataAfter, e); - } + setL2(id, subInterfaceIndex, subInterfaceName, dataAfter, writeContext); } private String getSubInterfaceName(@Nonnull final InstanceIdentifier<L2> id) { @@ -87,12 +82,7 @@ public class SubInterfaceL2Customizer extends FutureJVppCustomizer implements Ch final String subInterfaceName = getSubInterfaceName(id); final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, writeContext.getMappingContext()); // TODO handle update properly (if possible) - try { - setL2(id, subInterfaceIndex, subInterfaceName, dataAfter, writeContext); - } catch (VppApiInvocationException e) { - LOG.warn("Update of L2 failed", e); - throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, e); - } + setL2(id, subInterfaceIndex, subInterfaceName, dataAfter, writeContext); } @Override @@ -103,7 +93,7 @@ public class SubInterfaceL2Customizer extends FutureJVppCustomizer implements Ch private void setL2(final InstanceIdentifier<L2> id, final int swIfIndex, final String ifcName, final L2 l2, final WriteContext writeContext) - throws VppApiInvocationException, WriteFailedException { + throws WriteFailedException { LOG.debug("Setting L2 for sub-interface: {}", ifcName); icWriterUtils.setInterconnection(id, swIfIndex, ifcName, l2.getInterconnection(), writeContext); } diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/TapCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/TapCustomizer.java index 5f98ade94..2046caf1f 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/TapCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/TapCustomizer.java @@ -19,12 +19,9 @@ package io.fd.honeycomb.v3po.translate.v3po.interfaces; import com.google.common.base.Optional; import io.fd.honeycomb.v3po.translate.v3po.util.AbstractInterfaceTypeCustomizer; 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.util.TranslateUtils; import io.fd.honeycomb.v3po.translate.write.WriteContext; 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.InterfaceType; 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.yang.types.rev130715.PhysAddress; @@ -32,16 +29,15 @@ 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.Tap; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.openvpp.jvpp.dto.TapConnect; -import org.openvpp.jvpp.dto.TapConnectReply; -import org.openvpp.jvpp.dto.TapDelete; -import org.openvpp.jvpp.dto.TapDeleteReply; -import org.openvpp.jvpp.dto.TapModify; -import org.openvpp.jvpp.dto.TapModifyReply; +import org.openvpp.jvpp.VppBaseCallException; +import org.openvpp.jvpp.dto.*; import org.openvpp.jvpp.future.FutureJVpp; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.annotation.Nonnull; +import java.util.concurrent.CompletionStage; + public class TapCustomizer extends AbstractInterfaceTypeCustomizer<Tap> { private static final Logger LOG = LoggerFactory.getLogger(TapCustomizer.class); @@ -68,10 +64,11 @@ public class TapCustomizer extends AbstractInterfaceTypeCustomizer<Tap> { protected final void writeInterface(@Nonnull final InstanceIdentifier<Tap> id, @Nonnull final Tap dataAfter, @Nonnull final WriteContext writeContext) throws WriteFailedException.CreateFailedException { + final String ifcName = id.firstKeyOf(Interface.class).getName(); try { - createTap(id.firstKeyOf(Interface.class).getName(), dataAfter, writeContext); - } catch (VppApiInvocationException e) { - LOG.warn("Write of Tap failed", e); + createTap(ifcName, dataAfter, writeContext); + } catch (VppBaseCallException e) { + LOG.warn("Failed to set tap interface: {}, tap: {}", ifcName, dataAfter, e); throw new WriteFailedException.CreateFailedException(id, dataAfter, e); } } @@ -91,8 +88,8 @@ public class TapCustomizer extends AbstractInterfaceTypeCustomizer<Tap> { try { modifyTap(ifcName, index, dataAfter); - } catch (VppApiInvocationException e) { - LOG.warn("Write of Tap failed", e); + } catch (VppBaseCallException e) { + LOG.warn("Failed to set tap interface: {}, tap: {}", ifcName, dataAfter, e); throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, e); } } @@ -112,58 +109,43 @@ public class TapCustomizer extends AbstractInterfaceTypeCustomizer<Tap> { try { deleteTap(ifcName, index, dataBefore, writeContext); - } catch (VppApiInvocationException e) { - LOG.warn("Delete of Tap failed", e); + } catch (VppBaseCallException e) { + LOG.warn("Failed to delete tap interface: {}, tap: {}", ifcName, e); throw new WriteFailedException.DeleteFailedException(id, e); } } - private void createTap(final String swIfName, final Tap tap, final WriteContext writeContext) throws VppApiInvocationException { + private void createTap(final String swIfName, final Tap tap, final WriteContext writeContext) throws VppBaseCallException { LOG.debug("Setting tap interface: {}. Tap: {}", swIfName, tap); final CompletionStage<TapConnectReply> tapConnectFuture = getFutureJVpp().tapConnect(getTapConnectRequest(tap.getTapName(), tap.getMac(), tap.getDeviceInstance())); final TapConnectReply reply = TranslateUtils.getReply(tapConnectFuture.toCompletableFuture()); - if (reply.retval < 0) { - LOG.warn("Failed to set tap interface: {}, tap: {}", swIfName, tap); - throw new VppApiInvocationException("tap_connect", reply.context, reply.retval); - } else { - LOG.debug("Tap set successfully for: {}, tap: {}", swIfName, tap); - // Add new interface to our interface context - interfaceContext.addName(reply.swIfIndex, swIfName, writeContext.getMappingContext()); - } + LOG.debug("Tap set successfully for: {}, tap: {}", swIfName, tap); + // Add new interface to our interface context + interfaceContext.addName(reply.swIfIndex, swIfName, writeContext.getMappingContext()); } - private void modifyTap(final String swIfName, final int index, final Tap tap) throws VppApiInvocationException { + private void modifyTap(final String swIfName, final int index, final Tap tap) throws VppBaseCallException { LOG.debug("Modifying tap interface: {}. Tap: {}", swIfName, tap); final CompletionStage<TapModifyReply> vxlanAddDelTunnelReplyCompletionStage = getFutureJVpp().tapModify(getTapModifyRequest(tap.getTapName(), index, tap.getMac(), tap.getDeviceInstance())); final TapModifyReply reply = TranslateUtils.getReply(vxlanAddDelTunnelReplyCompletionStage.toCompletableFuture()); - if (reply.retval < 0) { - LOG.warn("Failed to modify tap interface: {}, tap: {}", swIfName, tap); - throw new VppApiInvocationException("tap_modify", reply.context, reply.retval); - } else { - LOG.debug("Tap modified successfully for: {}, tap: {}", swIfName, tap); - } + LOG.debug("Tap modified successfully for: {}, tap: {}", swIfName, tap); } private void deleteTap(final String swIfName, final int index, final Tap dataBefore, final WriteContext writeContext) - throws VppApiInvocationException { + throws VppBaseCallException { LOG.debug("Deleting tap interface: {}. Tap: {}", swIfName, dataBefore); final CompletionStage<TapDeleteReply> vxlanAddDelTunnelReplyCompletionStage = getFutureJVpp().tapDelete(getTapDeleteRequest(index)); final TapDeleteReply reply = TranslateUtils.getReply(vxlanAddDelTunnelReplyCompletionStage.toCompletableFuture()); - if (reply.retval < 0) { - LOG.warn("Failed to delete tap interface: {}, tap: {}", swIfName, dataBefore); - throw new VppApiInvocationException("tap_modify", reply.context, reply.retval); - } else { - LOG.debug("Tap deleted successfully for: {}, tap: {}", swIfName, dataBefore); - // Remove deleted interface from interface context - interfaceContext.removeName(swIfName, writeContext.getMappingContext()); - } + LOG.debug("Tap deleted successfully for: {}, tap: {}", swIfName, dataBefore); + // Remove deleted interface from interface context + interfaceContext.removeName(swIfName, writeContext.getMappingContext()); } private TapConnect getTapConnectRequest(final String tapName, final PhysAddress mac, final Long deviceInstance) { diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VhostUserCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VhostUserCustomizer.java index 6c45e98ac..ae25354fc 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VhostUserCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VhostUserCustomizer.java @@ -20,12 +20,9 @@ import com.google.common.base.Optional; import com.google.common.base.Preconditions; import io.fd.honeycomb.v3po.translate.v3po.util.AbstractInterfaceTypeCustomizer; 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.util.TranslateUtils; import io.fd.honeycomb.v3po.translate.write.WriteContext; 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.InterfaceType; 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.VhostUserRole; @@ -33,16 +30,15 @@ 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.VhostUser; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.openvpp.jvpp.dto.CreateVhostUserIf; -import org.openvpp.jvpp.dto.CreateVhostUserIfReply; -import org.openvpp.jvpp.dto.DeleteVhostUserIf; -import org.openvpp.jvpp.dto.DeleteVhostUserIfReply; -import org.openvpp.jvpp.dto.ModifyVhostUserIf; -import org.openvpp.jvpp.dto.ModifyVhostUserIfReply; +import org.openvpp.jvpp.VppBaseCallException; +import org.openvpp.jvpp.dto.*; import org.openvpp.jvpp.future.FutureJVpp; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.annotation.Nonnull; +import java.util.concurrent.CompletionStage; + /** * Writer Customizer responsible for passing vhost user interface CRD operations to VPP */ @@ -72,28 +68,25 @@ public class VhostUserCustomizer extends AbstractInterfaceTypeCustomizer<VhostUs protected final void writeInterface(@Nonnull final InstanceIdentifier<VhostUser> id, @Nonnull final VhostUser dataAfter, @Nonnull final WriteContext writeContext) throws WriteFailedException.CreateFailedException { + final String swIfName = id.firstKeyOf(Interface.class).getName(); try { - createVhostUserIf(id.firstKeyOf(Interface.class).getName(), dataAfter, writeContext); - } catch (VppApiInvocationException | IllegalInterfaceTypeException e) { + createVhostUserIf(swIfName, dataAfter, writeContext); + } catch (VppBaseCallException | IllegalInterfaceTypeException e) { + LOG.debug("Failed to create vhost user interface: {}, vhostUser: {}", swIfName, dataAfter); throw new WriteFailedException.CreateFailedException(id, dataAfter, e); } } - private void createVhostUserIf(final String swIfName, final VhostUser vhostUser, final WriteContext writeContext) throws VppApiInvocationException { + private void createVhostUserIf(final String swIfName, final VhostUser vhostUser, final WriteContext writeContext) throws VppBaseCallException { LOG.debug("Creating vhost user interface: name={}, vhostUser={}", swIfName, vhostUser); + final CompletionStage<CreateVhostUserIfReply> createVhostUserIfReplyCompletionStage = getFutureJVpp().createVhostUserIf(getCreateVhostUserIfRequest(vhostUser)); - final CreateVhostUserIfReply reply = TranslateUtils.getReply(createVhostUserIfReplyCompletionStage.toCompletableFuture()); - if (reply.retval < 0) { - LOG.debug("Failed to create vhost user interface: {}, vhostUser: {}", swIfName, vhostUser); - throw new VppApiInvocationException("createVhostUserIf", reply.context, reply.retval); - } else { - LOG.debug("Vhost user interface created successfully for: {}, vhostUser: {}", swIfName, vhostUser); - // Add new interface to our interface context - interfaceContext.addName(reply.swIfIndex, swIfName, writeContext.getMappingContext()); - } + LOG.debug("Vhost user interface created successfully for: {}, vhostUser: {}", swIfName, vhostUser); + // Add new interface to our interface context + interfaceContext.addName(reply.swIfIndex, swIfName, writeContext.getMappingContext()); } private CreateVhostUserIf getCreateVhostUserIfRequest(final VhostUser vhostUser) { @@ -112,14 +105,16 @@ public class VhostUserCustomizer extends AbstractInterfaceTypeCustomizer<VhostUs @Nonnull final VhostUser dataBefore, @Nonnull final VhostUser dataAfter, @Nonnull final WriteContext writeContext) throws WriteFailedException.UpdateFailedException { + final String swIfName = id.firstKeyOf(Interface.class).getName(); try { - modifyVhostUserIf(id.firstKeyOf(Interface.class).getName(), dataAfter, writeContext); - } catch (VppApiInvocationException e) { + modifyVhostUserIf(swIfName, dataAfter, writeContext); + } catch (VppBaseCallException e) { + LOG.warn("Failed to update vhost user interface: {}, vhostUser: {}", swIfName, dataAfter); throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, e); } } - private void modifyVhostUserIf(final String swIfName, final VhostUser vhostUser, final WriteContext writeContext) throws VppApiInvocationException { + private void modifyVhostUserIf(final String swIfName, final VhostUser vhostUser, final WriteContext writeContext) throws VppBaseCallException { LOG.debug("Updating vhost user interface: name={}, vhostUser={}", swIfName, vhostUser); final CompletionStage<ModifyVhostUserIfReply> modifyVhostUserIfReplyCompletionStage = getFutureJVpp() @@ -127,12 +122,7 @@ public class VhostUserCustomizer extends AbstractInterfaceTypeCustomizer<VhostUs final ModifyVhostUserIfReply reply = TranslateUtils.getReply(modifyVhostUserIfReplyCompletionStage.toCompletableFuture()); - if (reply.retval < 0) { - LOG.debug("Failed to update vhost user interface: {}, vhostUser: {}", swIfName, vhostUser); - throw new VppApiInvocationException("modifyVhostUserIf", reply.context, reply.retval); - } else { - LOG.debug("Vhost user interface updated successfully for: {}, vhostUser: {}", swIfName, vhostUser); - } + LOG.debug("Vhost user interface updated successfully for: {}, vhostUser: {}", swIfName, vhostUser); } private ModifyVhostUserIf getModifyVhostUserIfRequest(final VhostUser vhostUser, final int swIfIndex) { @@ -149,28 +139,25 @@ public class VhostUserCustomizer extends AbstractInterfaceTypeCustomizer<VhostUs public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<VhostUser> id, @Nonnull final VhostUser dataBefore, @Nonnull final WriteContext writeContext) throws WriteFailedException.DeleteFailedException { + final String swIfName = id.firstKeyOf(Interface.class).getName(); try { - deleteVhostUserIf(id.firstKeyOf(Interface.class).getName(), dataBefore, writeContext); - } catch (VppApiInvocationException e) { + deleteVhostUserIf(swIfName, dataBefore, writeContext); + } catch (VppBaseCallException e) { + LOG.warn("Failed to delete vhost user interface: {}, vhostUser: {}", swIfName, dataBefore); throw new WriteFailedException.DeleteFailedException(id, e); } } - private void deleteVhostUserIf(final String swIfName, final VhostUser vhostUser, final WriteContext writeContext) throws VppApiInvocationException { + private void deleteVhostUserIf(final String swIfName, final VhostUser vhostUser, final WriteContext writeContext) throws VppBaseCallException { LOG.debug("Deleting vhost user interface: name={}, vhostUser={}", swIfName, vhostUser); final CompletionStage<DeleteVhostUserIfReply> deleteVhostUserIfReplyCompletionStage = getFutureJVpp().deleteVhostUserIf(getDeleteVhostUserIfRequest(interfaceContext.getIndex(swIfName, writeContext.getMappingContext()))); final DeleteVhostUserIfReply reply = TranslateUtils.getReply(deleteVhostUserIfReplyCompletionStage.toCompletableFuture()); - if (reply.retval < 0) { - LOG.debug("Failed to delete vhost user interface: {}, vhostUser: {}", swIfName, vhostUser); - throw new VppApiInvocationException("modifyVhostUserIf", reply.context, reply.retval); - } else { - LOG.debug("Vhost user interface deleted successfully for: {}, vhostUser: {}", swIfName, vhostUser); - // Remove interface from our interface context - interfaceContext.removeName(swIfName, writeContext.getMappingContext()); - } + LOG.debug("Vhost user interface deleted successfully for: {}, vhostUser: {}", swIfName, vhostUser); + // Remove interface from our interface context + interfaceContext.removeName(swIfName, writeContext.getMappingContext()); } private DeleteVhostUserIf getDeleteVhostUserIfRequest(final int swIfIndex) { 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 5b2be71cc..77489eca2 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 @@ -16,19 +16,13 @@ package io.fd.honeycomb.v3po.translate.v3po.interfaces; -import static com.google.common.base.Preconditions.checkArgument; - import com.google.common.base.Optional; import com.google.common.net.InetAddresses; import io.fd.honeycomb.v3po.translate.v3po.util.AbstractInterfaceTypeCustomizer; 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.util.TranslateUtils; import io.fd.honeycomb.v3po.translate.write.WriteContext; 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.IpAddress; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; @@ -37,12 +31,19 @@ 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.Vxlan; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.VppBaseCallException; 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; +import javax.annotation.Nonnull; +import java.net.InetAddress; +import java.util.concurrent.CompletionStage; + +import static com.google.common.base.Preconditions.checkArgument; + // TODO extract common code from all Interface type specific writer customizers into a superclass public class VxlanCustomizer extends AbstractInterfaceTypeCustomizer<Vxlan> { @@ -70,10 +71,11 @@ public class VxlanCustomizer extends AbstractInterfaceTypeCustomizer<Vxlan> { protected final void writeInterface(@Nonnull final InstanceIdentifier<Vxlan> id, @Nonnull final Vxlan dataAfter, @Nonnull final WriteContext writeContext) throws WriteFailedException.CreateFailedException { + final String swIfName = id.firstKeyOf(Interface.class).getName(); try { - createVxlanTunnel(id.firstKeyOf(Interface.class).getName(), dataAfter, writeContext); - } catch (VppApiInvocationException | IllegalInterfaceTypeException e) { - LOG.warn("Write of Vxlan failed", e); + createVxlanTunnel(swIfName, dataAfter, writeContext); + } catch (VppBaseCallException | IllegalInterfaceTypeException e) { + LOG.debug("Failed to set vxlan tunnel for interface: {}, vxlan: {}", swIfName, dataAfter); throw new WriteFailedException.CreateFailedException(id, dataAfter, e); } } @@ -90,15 +92,16 @@ public class VxlanCustomizer extends AbstractInterfaceTypeCustomizer<Vxlan> { public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Vxlan> id, @Nonnull final Vxlan dataBefore, @Nonnull final WriteContext writeContext) throws WriteFailedException.DeleteFailedException { + final String swIfName = id.firstKeyOf(Interface.class).getName(); try { - deleteVxlanTunnel(id.firstKeyOf(Interface.class).getName(), dataBefore, writeContext); - } catch (VppApiInvocationException e) { - LOG.warn("Delete of Vxlan tunnel failed", e); + deleteVxlanTunnel(swIfName, dataBefore, writeContext); + } catch (VppBaseCallException e) { + LOG.debug("Failed to delete vxlan tunnel for interface: {}, vxlan: {}", swIfName, dataBefore); throw new WriteFailedException.DeleteFailedException(id, e); } } - private void createVxlanTunnel(final String swIfName, final Vxlan vxlan, final WriteContext writeContext) throws VppApiInvocationException { + private void createVxlanTunnel(final String swIfName, final Vxlan vxlan, final WriteContext writeContext) throws VppBaseCallException { final byte isIpv6 = (byte) (isIpv6(vxlan) ? 1 : 0); final InetAddress srcAddress = InetAddresses.forString(getAddressString(vxlan.getSrc())); final InetAddress dstAddress = InetAddresses.forString(getAddressString(vxlan.getDst())); @@ -113,27 +116,22 @@ public class VxlanCustomizer extends AbstractInterfaceTypeCustomizer<Vxlan> { final VxlanAddDelTunnelReply reply = TranslateUtils.getReply(vxlanAddDelTunnelReplyCompletionStage.toCompletableFuture()); - if (reply.retval < 0) { - LOG.debug("Failed to set vxlan tunnel for interface: {}, vxlan: {}", swIfName, vxlan); - throw new VppApiInvocationException("vxlanAddDelTunnel", reply.context, reply.retval); - } else { - LOG.debug("Vxlan tunnel set successfully for: {}, vxlan: {}", swIfName, vxlan); - if(interfaceContext.containsName(reply.swIfIndex, writeContext.getMappingContext())) { - // VPP keeps vxlan tunnels present even after they are delete(reserving ID for next tunnel) - // This may cause inconsistencies in mapping context when configuring tunnels like this: - // 1. Add tunnel 2. Delete tunnel 3. Read interfaces (reserved mapping e.g. vxlan_tunnel0 -> 6 - // will get into mapping context) 4. Add tunnel (this will add another mapping with the same - // reserved ID and context is invalid) - // That's why a check has to be performed here removing mapping vxlan_tunnel0 -> 6 mapping and storing - // new name for that ID - final String formerName = interfaceContext.getName(reply.swIfIndex, writeContext.getMappingContext()); - LOG.debug("Removing updated mapping of a vxlan tunnel, id: {}, former name: {}, new name: {}", - reply.swIfIndex, formerName, swIfName); - interfaceContext.removeName(formerName, writeContext.getMappingContext()); - } - // Add new interface to our interface context - interfaceContext.addName(reply.swIfIndex, swIfName, writeContext.getMappingContext()); + LOG.debug("Vxlan tunnel set successfully for: {}, vxlan: {}", swIfName, vxlan); + if(interfaceContext.containsName(reply.swIfIndex, writeContext.getMappingContext())) { + // VPP keeps vxlan tunnels present even after they are delete(reserving ID for next tunnel) + // This may cause inconsistencies in mapping context when configuring tunnels like this: + // 1. Add tunnel 2. Delete tunnel 3. Read interfaces (reserved mapping e.g. vxlan_tunnel0 -> 6 + // will get into mapping context) 4. Add tunnel (this will add another mapping with the same + // reserved ID and context is invalid) + // That's why a check has to be performed here removing mapping vxlan_tunnel0 -> 6 mapping and storing + // new name for that ID + final String formerName = interfaceContext.getName(reply.swIfIndex, writeContext.getMappingContext()); + LOG.debug("Removing updated mapping of a vxlan tunnel, id: {}, former name: {}, new name: {}", + reply.swIfIndex, formerName, swIfName); + interfaceContext.removeName(formerName, writeContext.getMappingContext()); } + // Add new interface to our interface context + interfaceContext.addName(reply.swIfIndex, swIfName, writeContext.getMappingContext()); } private boolean isIpv6(final Vxlan vxlan) { @@ -152,7 +150,7 @@ public class VxlanCustomizer extends AbstractInterfaceTypeCustomizer<Vxlan> { return addr.getIpv4Address() == null ? addr.getIpv6Address().getValue() : addr.getIpv4Address().getValue(); } - private void deleteVxlanTunnel(final String swIfName, final Vxlan vxlan, final WriteContext writeContext) throws VppApiInvocationException { + private void deleteVxlanTunnel(final String swIfName, final Vxlan vxlan, final WriteContext writeContext) throws VppBaseCallException { final byte isIpv6 = (byte) (isIpv6(vxlan) ? 1 : 0); final InetAddress srcAddress = InetAddresses.forString(getAddressString(vxlan.getSrc())); final InetAddress dstAddress = InetAddresses.forString(getAddressString(vxlan.getDst())); @@ -167,14 +165,9 @@ public class VxlanCustomizer extends AbstractInterfaceTypeCustomizer<Vxlan> { final VxlanAddDelTunnelReply reply = TranslateUtils.getReply(vxlanAddDelTunnelReplyCompletionStage.toCompletableFuture()); - if (reply.retval < 0) { - LOG.debug("Failed to delete vxlan tunnel for interface: {}, vxlan: {}", swIfName, vxlan); - throw new VppApiInvocationException("vxlanAddDelTunnel", reply.context, reply.retval); - } else { - LOG.debug("Vxlan tunnel deleted successfully for: {}, vxlan: {}", swIfName, vxlan); - // Remove interface from our interface context - interfaceContext.removeName(swIfName, writeContext.getMappingContext()); - } + LOG.debug("Vxlan tunnel deleted successfully for: {}, vxlan: {}", swIfName, vxlan); + // Remove interface from our interface context + interfaceContext.removeName(swIfName, writeContext.getMappingContext()); } private static VxlanAddDelTunnel getVxlanTunnelRequest(final byte isAdd, final byte[] srcAddr, final byte[] dstAddr, diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanGpeCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanGpeCustomizer.java index 7d9641122..216d354b4 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanGpeCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanGpeCustomizer.java @@ -22,7 +22,6 @@ import com.google.common.base.Optional; import com.google.common.net.InetAddresses; import io.fd.honeycomb.v3po.translate.v3po.util.AbstractInterfaceTypeCustomizer; 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.util.TranslateUtils; import io.fd.honeycomb.v3po.translate.write.WriteContext; import io.fd.honeycomb.v3po.translate.write.WriteFailedException; @@ -37,6 +36,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.interfaces._interface.VxlanGpe; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.VppBaseCallException; import org.openvpp.jvpp.dto.VxlanGpeAddDelTunnel; import org.openvpp.jvpp.dto.VxlanGpeAddDelTunnelReply; import org.openvpp.jvpp.future.FutureJVpp; @@ -70,10 +70,11 @@ public class VxlanGpeCustomizer extends AbstractInterfaceTypeCustomizer<VxlanGpe protected final void writeInterface(@Nonnull final InstanceIdentifier<VxlanGpe> id, @Nonnull final VxlanGpe dataAfter, @Nonnull final WriteContext writeContext) throws WriteFailedException.CreateFailedException { + final String swIfName = id.firstKeyOf(Interface.class).getName(); try { - createVxlanGpeTunnel(id.firstKeyOf(Interface.class).getName(), dataAfter, writeContext); - } catch (VppApiInvocationException | IllegalInterfaceTypeException e) { - LOG.warn("Write of VxlanGpe failed", e); + createVxlanGpeTunnel(swIfName, dataAfter, writeContext); + } catch (VppBaseCallException | IllegalInterfaceTypeException e) { + LOG.warn("Failed to set VxlanGpe tunnel for interface: {}, VxlanGpe: {}", swIfName, dataAfter); throw new WriteFailedException.CreateFailedException(id, dataAfter, e); } } @@ -90,15 +91,16 @@ public class VxlanGpeCustomizer extends AbstractInterfaceTypeCustomizer<VxlanGpe public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<VxlanGpe> id, @Nonnull final VxlanGpe dataBefore, @Nonnull final WriteContext writeContext) throws WriteFailedException.DeleteFailedException { + final String swIfName = id.firstKeyOf(Interface.class).getName(); try { - deleteVxlanGpeTunnel(id.firstKeyOf(Interface.class).getName(), dataBefore, writeContext); - } catch (VppApiInvocationException e) { - LOG.warn("Delete of VxlanGpe tunnel failed", e); + deleteVxlanGpeTunnel(swIfName, dataBefore, writeContext); + } catch (VppBaseCallException e) { + LOG.warn("Failed to delete VxlanGpe tunnel for interface: {}, VxlanGpe: {}", swIfName, dataBefore); throw new WriteFailedException.DeleteFailedException(id, e); } } - private void createVxlanGpeTunnel(final String swIfName, final VxlanGpe VxlanGpe, final WriteContext writeContext) throws VppApiInvocationException { + private void createVxlanGpeTunnel(final String swIfName, final VxlanGpe VxlanGpe, final WriteContext writeContext) throws VppBaseCallException { final byte isIpv6 = (byte) (isIpv6(VxlanGpe) ? 1 : 0); final InetAddress Local = InetAddresses.forString(getAddressString(VxlanGpe.getLocal())); final InetAddress Remote = InetAddresses.forString(getAddressString(VxlanGpe.getRemote())); @@ -115,20 +117,15 @@ public class VxlanGpeCustomizer extends AbstractInterfaceTypeCustomizer<VxlanGpe final VxlanGpeAddDelTunnelReply reply = TranslateUtils.getReply(VxlanGpeAddDelTunnelReplyCompletionStage.toCompletableFuture()); - if (reply.retval < 0) { - LOG.debug("Failed to set VxlanGpe tunnel for interface: {}, VxlanGpe: {}", swIfName, VxlanGpe); - throw new VppApiInvocationException("VxlanGpeAddDelTunnel", reply.context, reply.retval); - } else { - LOG.debug("VxlanGpe tunnel set successfully for: {}, VxlanGpe: {}", swIfName, VxlanGpe); - if(interfaceContext.containsName(reply.swIfIndex, writeContext.getMappingContext())) { - final String formerName = interfaceContext.getName(reply.swIfIndex, writeContext.getMappingContext()); - LOG.debug("Removing updated mapping of a vxlan-gpe tunnel, id: {}, former name: {}, new name: {}", - reply.swIfIndex, formerName, swIfName); - interfaceContext.removeName(formerName, writeContext.getMappingContext()); - } - // Add new interface to our interface context - interfaceContext.addName(reply.swIfIndex, swIfName, writeContext.getMappingContext()); + LOG.debug("VxlanGpe tunnel set successfully for: {}, VxlanGpe: {}", swIfName, VxlanGpe); + if(interfaceContext.containsName(reply.swIfIndex, writeContext.getMappingContext())) { + final String formerName = interfaceContext.getName(reply.swIfIndex, writeContext.getMappingContext()); + LOG.debug("Removing updated mapping of a vxlan-gpe tunnel, id: {}, former name: {}, new name: {}", + reply.swIfIndex, formerName, swIfName); + interfaceContext.removeName(formerName, writeContext.getMappingContext()); } + // Add new interface to our interface context + interfaceContext.addName(reply.swIfIndex, swIfName, writeContext.getMappingContext()); } private boolean isIpv6(final VxlanGpe VxlanGpe) { @@ -147,7 +144,7 @@ public class VxlanGpeCustomizer extends AbstractInterfaceTypeCustomizer<VxlanGpe return addr.getIpv4Address() == null ? addr.getIpv6Address().getValue() : addr.getIpv4Address().getValue(); } - private void deleteVxlanGpeTunnel(final String swIfName, final VxlanGpe VxlanGpe, final WriteContext writeContext) throws VppApiInvocationException { + private void deleteVxlanGpeTunnel(final String swIfName, final VxlanGpe VxlanGpe, final WriteContext writeContext) throws VppBaseCallException { final byte isIpv6 = (byte) (isIpv6(VxlanGpe) ? 1 : 0); final InetAddress local = InetAddresses.forString(getAddressString(VxlanGpe.getLocal())); final InetAddress remote = InetAddresses.forString(getAddressString(VxlanGpe.getRemote())); @@ -164,14 +161,9 @@ public class VxlanGpeCustomizer extends AbstractInterfaceTypeCustomizer<VxlanGpe final VxlanGpeAddDelTunnelReply reply = TranslateUtils.getReply(VxlanGpeAddDelTunnelReplyCompletionStage.toCompletableFuture()); - if (reply.retval < 0) { - LOG.debug("Failed to delete VxlanGpe tunnel for interface: {}, VxlanGpe: {}", swIfName, VxlanGpe); - throw new VppApiInvocationException("VxlanGpeAddDelTunnel", reply.context, reply.retval); - } else { - LOG.debug("VxlanGpe tunnel deleted successfully for: {}, VxlanGpe: {}", swIfName, VxlanGpe); - // Remove interface from our interface context - interfaceContext.removeName(swIfName, writeContext.getMappingContext()); - } + LOG.debug("VxlanGpe tunnel deleted successfully for: {}, VxlanGpe: {}", swIfName, VxlanGpe); + // Remove interface from our interface context + interfaceContext.removeName(swIfName, writeContext.getMappingContext()); } private static VxlanGpeAddDelTunnel getVxlanGpeTunnelRequest(final byte isAdd, final byte[] local, final byte[] remote, 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 fb891f838..5e00dd9b3 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 @@ -16,19 +16,13 @@ package io.fd.honeycomb.v3po.translate.v3po.interfaces.ip; -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - import com.google.common.base.Optional; import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer; -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.util.NamingContext; import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils; import io.fd.honeycomb.v3po.translate.write.WriteContext; import io.fd.honeycomb.v3po.translate.write.WriteFailedException; -import java.util.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; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4; @@ -38,12 +32,19 @@ 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.VppBaseCallException; 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; +import javax.annotation.Nonnull; +import java.util.concurrent.CompletionStage; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + public class Ipv4Customizer extends FutureJVppCustomizer implements ChildWriterCustomizer<Ipv4> { private static final Logger LOG = LoggerFactory.getLogger(Ipv4Customizer.class); @@ -66,13 +67,8 @@ public class Ipv4Customizer extends FutureJVppCustomizer implements ChildWriterC public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Ipv4> id, @Nonnull final Ipv4 dataAfter, @Nonnull final WriteContext writeContext) throws WriteFailedException { - try { - final String ifcName = id.firstKeyOf(Interface.class).getName(); - setIpv4(id, ifcName, dataAfter, writeContext); - } catch (VppApiInvocationException e) { - LOG.warn("Create of Ipv4 failed", e); - throw new WriteFailedException.CreateFailedException(id, dataAfter, e); - } + final String ifcName = id.firstKeyOf(Interface.class).getName(); + setIpv4(id, ifcName, dataAfter, writeContext); } @Override @@ -83,12 +79,7 @@ public class Ipv4Customizer extends FutureJVppCustomizer implements ChildWriterC final String ifcName = id.firstKeyOf(Interface.class).getName(); // TODO handle update in a better way - try { - setIpv4(id, ifcName, dataAfter, writeContext); - } catch (VppApiInvocationException e) { - LOG.warn("Update of Ipv4 failed", e); - throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, e); - } + setIpv4(id, ifcName, dataAfter, writeContext); } @Override @@ -99,14 +90,14 @@ public class Ipv4Customizer extends FutureJVppCustomizer implements ChildWriterC private void setIpv4(final InstanceIdentifier<Ipv4> id, final String name, final Ipv4 ipv4, final WriteContext writeContext) - throws WriteFailedException, VppApiInvocationException { + throws WriteFailedException { final int swIfc = interfaceContext.getIndex(name, writeContext.getMappingContext()); for (Address ipv4Addr : ipv4.getAddress()) { Subnet subnet = ipv4Addr.getSubnet(); if (subnet instanceof PrefixLength) { - setPrefixLengthSubnet(name, swIfc, ipv4Addr, (PrefixLength) subnet); + setPrefixLengthSubnet(id, name, swIfc, ipv4Addr, (PrefixLength) subnet); } else if (subnet instanceof Netmask) { setNetmaskSubnet(); } else { @@ -125,35 +116,36 @@ public class Ipv4Customizer extends FutureJVppCustomizer implements ChildWriterC throw new UnsupportedOperationException("Unimplemented"); } - private void setPrefixLengthSubnet(final String name, final int swIfc, final Address ipv4Addr, - final PrefixLength subnet) throws VppApiInvocationException { - Short plen = subnet.getPrefixLength(); - LOG.debug("Setting Subnet(prefix-length) for interface: {}, {}. Subnet: {}, Ipv4: {}", name, swIfc, subnet, - ipv4Addr); + private void setPrefixLengthSubnet(final InstanceIdentifier<Ipv4> id, final String name, final int swIfc, + final Address ipv4Addr, final PrefixLength subnet) + throws WriteFailedException { + try { + Short plen = subnet.getPrefixLength(); + LOG.debug("Setting Subnet(prefix-length) for interface: {}, {}. Subnet: {}, Ipv4: {}", name, swIfc, subnet, + ipv4Addr); - byte[] addr = TranslateUtils.ipv4AddressNoZoneToArray(ipv4Addr.getIp()); + byte[] addr = TranslateUtils.ipv4AddressNoZoneToArray(ipv4Addr.getIp()); - checkArgument(plen > 0, "Invalid length"); - checkNotNull(addr, "Null address"); + checkArgument(plen > 0, "Invalid length"); + checkNotNull(addr, "Null address"); - final CompletionStage<SwInterfaceAddDelAddressReply> swInterfaceAddDelAddressReplyCompletionStage = - getFutureJVpp().swInterfaceAddDelAddress(getSwInterfaceAddDelAddressRequest( - 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 SwInterfaceAddDelAddressReply reply = - TranslateUtils.getReply(swInterfaceAddDelAddressReplyCompletionStage.toCompletableFuture()); + final SwInterfaceAddDelAddressReply reply = + TranslateUtils.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", reply.context, reply.retval); - } else { LOG.debug("Subnet(prefix-length) set successfully for interface: {}, {}, Subnet: {}, Ipv4: {}", name, - swIfc, subnet, ipv4Addr); + swIfc, subnet, ipv4Addr); + } catch (VppBaseCallException e) { + LOG.warn("Failed to set Subnet(prefix-length) for interface: {}, {}, Subnet: {}, Ipv4: {}", name, swIfc, + subnet, ipv4Addr); + throw new WriteFailedException(id, "Unable to handle subnet of type " + subnet.getClass(), e); } } - private SwInterfaceAddDelAddress getSwInterfaceAddDelAddressRequest(final int swIfc, final byte isAdd, final byte ipv6, +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(); @@ -165,5 +157,4 @@ public class Ipv4Customizer extends FutureJVppCustomizer implements ChildWriterC swInterfaceAddDelAddress.addressLength = length; return swInterfaceAddDelAddress; } - } diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/EthernetCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/EthernetCustomizer.java index e1c3e2df6..5bbf33935 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/EthernetCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/EthernetCustomizer.java @@ -66,7 +66,7 @@ public class EthernetCustomizer extends FutureJVppCustomizer @Nonnull final ReadContext ctx) throws ReadFailedException { final InterfaceKey key = id.firstKeyOf(Interface.class); - final SwInterfaceDetails iface = InterfaceUtils.getVppInterfaceDetails(getFutureJVpp(), key.getName(), + final SwInterfaceDetails iface = InterfaceUtils.getVppInterfaceDetails(getFutureJVpp(), id, key.getName(), interfaceContext.getIndex(key.getName(), ctx.getMappingContext()), ctx.getModificationCache()); if(iface.linkMtu != 0) { diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterconnectionReadUtils.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterconnectionReadUtils.java index 886549ac3..f5c0e5972 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterconnectionReadUtils.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterconnectionReadUtils.java @@ -29,6 +29,8 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.Interconnection; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.interconnection.BridgeBasedBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.VppBaseCallException; import org.openvpp.jvpp.dto.BridgeDomainDetails; import org.openvpp.jvpp.dto.BridgeDomainDetailsReplyDump; import org.openvpp.jvpp.dto.BridgeDomainDump; @@ -59,15 +61,15 @@ final class InterconnectionReadUtils { } @Nullable - Interconnection readInterconnection(@Nonnull final String ifaceName, @Nonnull final ReadContext ctx) + Interconnection readInterconnection(@Nonnull final InstanceIdentifier<?> id, @Nonnull final String ifaceName, @Nonnull final ReadContext ctx) throws ReadFailedException { final int ifaceId = interfaceContext.getIndex(ifaceName, ctx.getMappingContext()); - final SwInterfaceDetails iface = InterfaceUtils.getVppInterfaceDetails(futureJvpp, ifaceName, + final SwInterfaceDetails iface = InterfaceUtils.getVppInterfaceDetails(futureJvpp, id, ifaceName, ifaceId, ctx.getModificationCache()); LOG.debug("Interface details for interface: {}, details: {}", ifaceName, iface); - final BridgeDomainDetailsReplyDump dumpReply = getDumpReply(); + final BridgeDomainDetailsReplyDump dumpReply = getDumpReply(id); final Optional<BridgeDomainSwIfDetails> bdForInterface = getBridgeDomainForInterface(ifaceId, dumpReply); if (bdForInterface.isPresent()) { final BridgeDomainSwIfDetails bdSwIfDetails = bdForInterface.get(); @@ -107,15 +109,19 @@ final class InterconnectionReadUtils { return reply.bridgeDomainDetails.stream().filter(a -> a.bdId == bdId).findFirst(); } - private BridgeDomainDetailsReplyDump getDumpReply() { - // We need to perform full bd dump, because there is no way - // to ask VPP for BD details given interface id/name (TODO add it to vpp.api?) - // TODO cache dump result - final BridgeDomainDump request = new BridgeDomainDump(); - request.bdId = -1; - - final CompletableFuture<BridgeDomainDetailsReplyDump> bdCompletableFuture = - futureJvpp.bridgeDomainSwIfDump(request).toCompletableFuture(); - return TranslateUtils.getReply(bdCompletableFuture); + private BridgeDomainDetailsReplyDump getDumpReply(@Nonnull final InstanceIdentifier<?> id) throws ReadFailedException { + try { + // We need to perform full bd dump, because there is no way + // to ask VPP for BD details given interface id/name (TODO add it to vpp.api?) + // TODO cache dump result + final BridgeDomainDump request = new BridgeDomainDump(); + request.bdId = -1; + + final CompletableFuture<BridgeDomainDetailsReplyDump> bdCompletableFuture = + futureJvpp.bridgeDomainSwIfDump(request).toCompletableFuture(); + return TranslateUtils.getReply(bdCompletableFuture); + } catch (VppBaseCallException e) { + throw new ReadFailedException(id,e); + } } } 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 d54929ea1..d83030d6e 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 @@ -23,13 +23,6 @@ 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.util.TranslateUtils; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -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.ietf.interfaces.rev140508.InterfacesStateBuilder; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus; @@ -39,6 +32,7 @@ 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.jvpp.VppBaseCallException; import org.openvpp.jvpp.dto.SwInterfaceDetails; import org.openvpp.jvpp.dto.SwInterfaceDetailsReplyDump; import org.openvpp.jvpp.dto.SwInterfaceDump; @@ -46,6 +40,14 @@ import org.openvpp.jvpp.future.FutureJVpp; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.annotation.Nonnull; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; + /** * Customizer for reading ietf-interfaces:interfaces-state/interface */ @@ -75,7 +77,7 @@ public class InterfaceCustomizer extends FutureJVppCustomizer final InterfaceKey key = id.firstKeyOf(id.getTargetType()); // Pass cached details from getAllIds to getDetails to avoid additional dumps - final SwInterfaceDetails iface = InterfaceUtils.getVppInterfaceDetails(getFutureJVpp(), key.getName(), + final SwInterfaceDetails iface = InterfaceUtils.getVppInterfaceDetails(getFutureJVpp(), id, key.getName(), interfaceContext.getIndex(key.getName(), ctx.getMappingContext()), ctx.getModificationCache()); LOG.debug("Interface details for interface: {}, details: {}", key.getName(), iface); @@ -105,41 +107,47 @@ public class InterfaceCustomizer extends FutureJVppCustomizer @Override public List<InterfaceKey> getAllIds(@Nonnull final InstanceIdentifier<Interface> id, @Nonnull final ReadContext context) throws ReadFailedException { - LOG.trace("Dumping all interfaces to get all IDs"); - - final SwInterfaceDump request = new SwInterfaceDump(); - request.nameFilter = "".getBytes(); - request.nameFilterValid = 0; - - final CompletableFuture<SwInterfaceDetailsReplyDump> swInterfaceDetailsReplyDumpCompletableFuture = - getFutureJVpp().swInterfaceDump(request).toCompletableFuture(); - final SwInterfaceDetailsReplyDump ifaces = TranslateUtils.getReply(swInterfaceDetailsReplyDumpCompletableFuture); - - if (null == ifaces || null == ifaces.swInterfaceDetails) { - LOG.debug("No interfaces found in VPP"); - return Collections.emptyList(); + try { + final List<InterfaceKey> interfacesKeys; + LOG.trace("Dumping all interfaces to get all IDs"); + + final SwInterfaceDump request = new SwInterfaceDump(); + request.nameFilter = "".getBytes(); + request.nameFilterValid = 0; + + final CompletableFuture<SwInterfaceDetailsReplyDump> swInterfaceDetailsReplyDumpCompletableFuture = + getFutureJVpp().swInterfaceDump(request).toCompletableFuture(); + final SwInterfaceDetailsReplyDump ifaces = TranslateUtils.getReply(swInterfaceDetailsReplyDumpCompletableFuture); + + if (null == ifaces || null == ifaces.swInterfaceDetails) { + LOG.debug("No interfaces found in VPP"); + return Collections.emptyList(); + } + + // Cache interfaces dump in per-tx context to later be used in readCurrentAttributes + context.getModificationCache().put(DUMPED_IFCS_CONTEXT_KEY, ifaces.swInterfaceDetails.stream() + .collect(Collectors.toMap(t -> t.swIfIndex, swInterfaceDetails -> swInterfaceDetails))); + + interfacesKeys = 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, context.getMappingContext())) { + interfaceContext.addName(elt.swIfIndex, TranslateUtils.toString(elt.interfaceName), context.getMappingContext()); + } + LOG.trace("Interface with name: {}, VPP name: {} and index: {} found in VPP", + interfaceContext.getName(elt.swIfIndex, context.getMappingContext()), elt.interfaceName, elt.swIfIndex); + + return new InterfaceKey(interfaceContext.getName(elt.swIfIndex, context.getMappingContext())); + }) + .collect(Collectors.toList()); + + LOG.debug("Interfaces found in VPP: {}", interfacesKeys); + return interfacesKeys; + } catch (VppBaseCallException e) { + LOG.warn("getAllIds exception :" + e.toString()); + throw new ReadFailedException( id, e); } - - // Cache interfaces dump in per-tx context to later be used in readCurrentAttributes - context.getModificationCache().put(DUMPED_IFCS_CONTEXT_KEY, ifaces.swInterfaceDetails.stream() - .collect(Collectors.toMap(t -> t.swIfIndex, swInterfaceDetails -> swInterfaceDetails))); - - final List<InterfaceKey> interfacesKeys = 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, context.getMappingContext())) { - interfaceContext.addName(elt.swIfIndex, TranslateUtils.toString(elt.interfaceName), context.getMappingContext()); - } - LOG.trace("Interface with name: {}, VPP name: {} and index: {} found in VPP", - interfaceContext.getName(elt.swIfIndex, context.getMappingContext()), elt.interfaceName, elt.swIfIndex); - - return new InterfaceKey(interfaceContext.getName(elt.swIfIndex, context.getMappingContext())); - }) - .collect(Collectors.toList()); - - LOG.debug("Interfaces found in VPP: {}", interfacesKeys); - return interfacesKeys; } @Override 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 a61c3890e..ba0a99147 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,27 +16,20 @@ package io.fd.honeycomb.v3po.translate.v3po.interfacesstate; -import static com.google.common.base.Preconditions.checkNotNull; -import static io.fd.honeycomb.v3po.translate.v3po.interfacesstate.InterfaceCustomizer.getCachedInterfaceDump; -import static java.util.Objects.requireNonNull; - import com.google.common.base.Preconditions; import io.fd.honeycomb.v3po.translate.ModificationCache; +import io.fd.honeycomb.v3po.translate.read.ReadFailedException; import io.fd.honeycomb.v3po.translate.util.RWUtils; import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils; -import java.math.BigInteger; -import java.util.Map; -import java.util.concurrent.CompletionStage; -import java.util.stream.Collector; -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.InterfaceType; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Gauge64; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.Tap; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VhostUser; -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.VxlanGpeTunnel; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanTunnel; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.VppBaseCallException; import org.openvpp.jvpp.dto.SwInterfaceDetails; import org.openvpp.jvpp.dto.SwInterfaceDetailsReplyDump; import org.openvpp.jvpp.dto.SwInterfaceDump; @@ -44,6 +37,18 @@ import org.openvpp.jvpp.future.FutureJVpp; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.annotation.Nonnull; +import java.math.BigInteger; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.CompletionStage; +import java.util.stream.Collector; +import java.util.stream.Collectors; + +import static com.google.common.base.Preconditions.checkNotNull; +import static io.fd.honeycomb.v3po.translate.v3po.interfacesstate.InterfaceCustomizer.getCachedInterfaceDump; +import static java.util.Objects.requireNonNull; + public final class InterfaceUtils { private static final Logger LOG = LoggerFactory.getLogger(InterfaceUtils.class); @@ -110,7 +115,7 @@ public final class InterfaceUtils { * @throws IllegalArgumentException if vppPhysAddress.length < 6 */ public static String vppPhysAddrToYang(@Nonnull final byte[] vppPhysAddress) { - requireNonNull(vppPhysAddress, "Empty physical address bytes"); + Objects.requireNonNull(vppPhysAddress, "Empty physical address bytes"); Preconditions.checkArgument(PHYSICAL_ADDRESS_LENGTH <= vppPhysAddress.length, "Invalid physical address size %s, expected >= 6", vppPhysAddress.length); StringBuilder physAddr = new StringBuilder(); @@ -151,17 +156,21 @@ public final class InterfaceUtils { * Queries VPP for interface description given interface key. * * @param futureJvpp VPP Java Future API + * @param id InstanceIdentifier, which is passed in ReadFailedException * @param name interface name * @param index VPP index of the interface * @param ctx per-tx scope context containing cached dump with all the interfaces. If the cache is not * available or outdated, another dump will be performed. * @return SwInterfaceDetails DTO or null if interface was not found * @throws IllegalArgumentException If interface cannot be found + * @throws ReadFailedException If read operation had failed */ @Nonnull public static SwInterfaceDetails getVppInterfaceDetails(@Nonnull final FutureJVpp futureJvpp, + @Nonnull final InstanceIdentifier<?> id, @Nonnull final String name, final int index, - @Nonnull final ModificationCache ctx) { + @Nonnull final ModificationCache ctx) + throws ReadFailedException { requireNonNull(futureJvpp, "futureJvpp should not be null"); requireNonNull(name, "name should not be null"); requireNonNull(ctx, "ctx should not be null"); @@ -177,27 +186,33 @@ public final class InterfaceUtils { return allInterfaces.get(index); } - CompletionStage<SwInterfaceDetailsReplyDump> requestFuture = futureJvpp.swInterfaceDump(request); - SwInterfaceDetailsReplyDump ifaces = TranslateUtils.getReply(requestFuture.toCompletableFuture()); - if (null == ifaces || null == ifaces.swInterfaceDetails || ifaces.swInterfaceDetails.isEmpty()) { - request.nameFilterValid = 0; + SwInterfaceDetailsReplyDump ifaces = null; + try { + CompletionStage<SwInterfaceDetailsReplyDump> requestFuture = futureJvpp.swInterfaceDump(request); + ifaces = TranslateUtils.getReply(requestFuture.toCompletableFuture()); + if (null == ifaces || null == ifaces.swInterfaceDetails || ifaces.swInterfaceDetails.isEmpty()) { + request.nameFilterValid = 0; - LOG.warn("VPP returned null instead of interface by key {} and its not cached", name); - LOG.warn("Iterating through all the interfaces to find interface: {}", name); + LOG.warn("VPP returned null instead of interface by key {} and its not cached", name); + LOG.warn("Iterating through all the interfaces to find interface: {}", name); - // Or else just perform full dump and do inefficient filtering - requestFuture = futureJvpp.swInterfaceDump(request); - ifaces = TranslateUtils.getReply(requestFuture.toCompletableFuture()); + // Or else just perform full dump and do inefficient filtering + requestFuture = futureJvpp.swInterfaceDump(request); + ifaces = TranslateUtils.getReply(requestFuture.toCompletableFuture()); - // Update the cache - allInterfaces.clear(); - allInterfaces - .putAll(ifaces.swInterfaceDetails.stream().collect(Collectors.toMap(d -> d.swIfIndex, d -> d))); + // Update the cache + allInterfaces.clear(); + allInterfaces + .putAll(ifaces.swInterfaceDetails.stream().collect(Collectors.toMap(d -> d.swIfIndex, d -> d))); - if (allInterfaces.containsKey(index)) { - return allInterfaces.get(index); + if (allInterfaces.containsKey(index)) { + return allInterfaces.get(index); + } + throw new IllegalArgumentException("Unable to find interface " + name); } - throw new IllegalArgumentException("Unable to find interface " + name); + } catch (VppBaseCallException e) { + LOG.warn("getVppInterfaceDetails exception :", e); + throw new ReadFailedException(id); } // SwInterfaceDump's name filter does prefix match, so we need additional filtering: diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/L2Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/L2Customizer.java index 63e51389c..e1496e36b 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/L2Customizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/L2Customizer.java @@ -21,7 +21,6 @@ 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.util.NamingContext; -import javax.annotation.Nonnull; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceStateAugmentationBuilder; @@ -34,6 +33,12 @@ import org.openvpp.jvpp.future.FutureJVpp; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.annotation.Nonnull; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; + +import static com.google.common.base.Preconditions.checkState; + /** * Customizer for reading ietf-interfaces:interfaces-state/interface/iface_name/v3po:l2 */ @@ -63,10 +68,10 @@ public class L2Customizer extends FutureJVppCustomizer implements ChildReaderCus @Override public void readCurrentAttributes(@Nonnull final InstanceIdentifier<L2> id, @Nonnull final L2Builder builder, @Nonnull final ReadContext ctx) throws ReadFailedException { + LOG.debug("Reading attributes for L2: {}", id); final InterfaceKey key = id.firstKeyOf(Interface.class); final String ifaceName = key.getName(); - - builder.setInterconnection(icReadUtils.readInterconnection(ifaceName, ctx)); + builder.setInterconnection(icReadUtils.readInterconnection(id, ifaceName, ctx)); } } diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/RewriteCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/RewriteCustomizer.java index 143fb4d68..4600395be 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/RewriteCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/RewriteCustomizer.java @@ -87,7 +87,7 @@ public class RewriteCustomizer extends FutureJVppCustomizer final String subInterfaceName = getSubInterfaceName(id); LOG.debug("Reading attributes for sub interface: {}", subInterfaceName); - final SwInterfaceDetails iface = InterfaceUtils.getVppInterfaceDetails(getFutureJVpp(), subInterfaceName, + final SwInterfaceDetails iface = InterfaceUtils.getVppInterfaceDetails(getFutureJVpp(), id, subInterfaceName, interfaceContext.getIndex(subInterfaceName, ctx.getMappingContext()), ctx.getModificationCache()); LOG.debug("VPP sub-interface details: {}", ReflectionToStringBuilder.toString(iface)); diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceCustomizer.java index 5adb43874..998b188d0 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceCustomizer.java @@ -62,6 +62,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan import org.opendaylight.yangtools.concepts.Builder; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.VppBaseCallException; import org.openvpp.jvpp.dto.SwInterfaceDetails; import org.openvpp.jvpp.dto.SwInterfaceDetailsReplyDump; import org.openvpp.jvpp.dto.SwInterfaceDump; @@ -89,43 +90,46 @@ public class SubInterfaceCustomizer extends FutureJVppCustomizer @Override public List<SubInterfaceKey> getAllIds(@Nonnull final InstanceIdentifier<SubInterface> id, @Nonnull final ReadContext context) throws ReadFailedException { - // Relying here that parent InterfaceCustomizer was invoked first (PREORDER) - // to fill in the context with initial ifc mapping - final InterfaceKey key = id.firstKeyOf(Interface.class); - final String ifaceName = key.getName(); - final int ifaceId = interfaceContext.getIndex(ifaceName, context.getMappingContext()); - - // TODO if we know that full dump was already performed we could use cache - // (checking if getCachedInterfaceDump() returns non empty map is not enough, because - // we could be part of particular iface state read - final SwInterfaceDump request = new SwInterfaceDump(); - request.nameFilter = "".getBytes(); - request.nameFilterValid = 0; - - final CompletableFuture<SwInterfaceDetailsReplyDump> swInterfaceDetailsReplyDumpCompletableFuture = - getFutureJVpp().swInterfaceDump(request).toCompletableFuture(); - final SwInterfaceDetailsReplyDump ifaces = - TranslateUtils.getReply(swInterfaceDetailsReplyDumpCompletableFuture); - - if (null == ifaces || null == ifaces.swInterfaceDetails) { - LOG.warn("Looking for sub-interfaces, but no interfaces found in VPP"); - return Collections.emptyList(); - } - - // Cache interfaces dump in per-tx context to later be used in readCurrentAttributes - context.getModificationCache().put(DUMPED_IFCS_CONTEXT_KEY, ifaces.swInterfaceDetails.stream() - .collect(Collectors.toMap(t -> t.swIfIndex, swInterfaceDetails -> swInterfaceDetails))); - - final List<SubInterfaceKey> interfacesKeys = ifaces.swInterfaceDetails.stream() - .filter(elt -> elt != null) - // accept only sub-interfaces for current iface: - .filter(elt -> elt.subId != 0 && elt.supSwIfIndex == ifaceId) - .map(details -> new SubInterfaceKey(new Long(details.subId))) - .collect(Collectors.toList()); - - LOG.debug("Sub-interfaces of {} found in VPP: {}", ifaceName, interfacesKeys); + try { + // Relying here that parent InterfaceCustomizer was invoked first (PREORDER) + // to fill in the context with initial ifc mapping + final InterfaceKey key = id.firstKeyOf(Interface.class); + final String ifaceName = key.getName(); + final int ifaceId = interfaceContext.getIndex(ifaceName, context.getMappingContext()); + + // TODO if we know that full dump was already performed we could use cache + // (checking if getCachedInterfaceDump() returns non empty map is not enough, because + // we could be part of particular iface state read + final SwInterfaceDump request = new SwInterfaceDump(); + request.nameFilter = "".getBytes(); + request.nameFilterValid = 0; + + final CompletableFuture<SwInterfaceDetailsReplyDump> swInterfaceDetailsReplyDumpCompletableFuture = + getFutureJVpp().swInterfaceDump(request).toCompletableFuture(); + final SwInterfaceDetailsReplyDump ifaces = + TranslateUtils.getReply(swInterfaceDetailsReplyDumpCompletableFuture); + + if (null == ifaces || null == ifaces.swInterfaceDetails) { + LOG.warn("Looking for sub-interfaces, but no interfaces found in VPP"); + return Collections.emptyList(); + } - return interfacesKeys; + // Cache interfaces dump in per-tx context to later be used in readCurrentAttributes + context.getModificationCache().put(DUMPED_IFCS_CONTEXT_KEY, ifaces.swInterfaceDetails.stream() + .collect(Collectors.toMap(t -> t.swIfIndex, swInterfaceDetails -> swInterfaceDetails))); + + final List<SubInterfaceKey> interfacesKeys = ifaces.swInterfaceDetails.stream() + .filter(elt -> elt != null) + // accept only sub-interfaces for current iface: + .filter(elt -> elt.subId != 0 && elt.supSwIfIndex == ifaceId) + .map(details -> new SubInterfaceKey(new Long(details.subId))) + .collect(Collectors.toList()); + + LOG.debug("Sub-interfaces of {} found in VPP: {}", ifaceName, interfacesKeys); + return interfacesKeys; + } catch (VppBaseCallException e) { + throw new ReadFailedException(id,e); + } } @Override @@ -147,7 +151,7 @@ public class SubInterfaceCustomizer extends FutureJVppCustomizer final String subInterfaceName = getSubInterfaceName(id); LOG.debug("Reading attributes for sub interface: {}", subInterfaceName); - final SwInterfaceDetails iface = InterfaceUtils.getVppInterfaceDetails(getFutureJVpp(), subInterfaceName, + final SwInterfaceDetails iface = InterfaceUtils.getVppInterfaceDetails(getFutureJVpp(), id, subInterfaceName, interfaceContext.getIndex(subInterfaceName, ctx.getMappingContext()), ctx.getModificationCache()); LOG.debug("VPP sub-interface details: {}", ReflectionToStringBuilder.toString(iface)); diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceL2Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceL2Customizer.java index baff29466..0c6d50b76 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceL2Customizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceL2Customizer.java @@ -72,6 +72,6 @@ public class SubInterfaceL2Customizer extends FutureJVppCustomizer implements Ch final SubInterfaceKey subInterfacekey = id.firstKeyOf(SubInterface.class); final String subInterfaceName = getSubInterfaceName(parentInterfacekey.getName(), subInterfacekey.getIdentifier().intValue()); - builder.setInterconnection(icReadUtils.readInterconnection(subInterfaceName, ctx)); + builder.setInterconnection(icReadUtils.readInterconnection(id, subInterfaceName, ctx)); } } diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/TapCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/TapCustomizer.java index d4fe30b57..44256956c 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/TapCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/TapCustomizer.java @@ -16,20 +16,12 @@ package io.fd.honeycomb.v3po.translate.v3po.interfacesstate; -import static io.fd.honeycomb.v3po.translate.v3po.interfacesstate.InterfaceUtils.isInterfaceOfType; - import io.fd.honeycomb.v3po.translate.read.ReadContext; 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.util.NamingContext; import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.concurrent.CompletionStage; -import java.util.stream.Collectors; -import javax.annotation.Nonnull; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceStateAugmentationBuilder; @@ -38,6 +30,7 @@ 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.jvpp.VppBaseCallException; import org.openvpp.jvpp.dto.SwInterfaceTapDetails; import org.openvpp.jvpp.dto.SwInterfaceTapDetailsReplyDump; import org.openvpp.jvpp.dto.SwInterfaceTapDump; @@ -45,6 +38,15 @@ import org.openvpp.jvpp.future.FutureJVpp; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.annotation.Nonnull; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletionStage; +import java.util.stream.Collectors; + +import static io.fd.honeycomb.v3po.translate.v3po.interfacesstate.InterfaceUtils.isInterfaceOfType; + public class TapCustomizer extends FutureJVppCustomizer implements ChildReaderCustomizer<Tap, TapBuilder> { @@ -73,44 +75,49 @@ public class TapCustomizer extends FutureJVppCustomizer public void readCurrentAttributes(@Nonnull final InstanceIdentifier<Tap> id, @Nonnull final TapBuilder builder, @Nonnull final ReadContext ctx) throws ReadFailedException { - final InterfaceKey key = id.firstKeyOf(Interface.class); - // Relying here that parent InterfaceCustomizer was invoked first (PREORDER) - // to fill in the context with initial ifc mapping - final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext()); - if (!isInterfaceOfType(ctx.getModificationCache(), index, org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.Tap.class)) { - return; - } - - LOG.debug("Reading attributes for tap interface: {}", key.getName()); - - @SuppressWarnings("unchecked") - Map<Integer, SwInterfaceTapDetails> mappedTaps = - (Map<Integer, SwInterfaceTapDetails>) ctx.getModificationCache().get(DUMPED_TAPS_CONTEXT_KEY); - - if(mappedTaps == null) { - // Full Tap dump has to be performed here, no filter or anything is here to help so at least we cache it - final SwInterfaceTapDump request = new SwInterfaceTapDump(); - final CompletionStage<SwInterfaceTapDetailsReplyDump> swInterfaceTapDetailsReplyDumpCompletionStage = - getFutureJVpp().swInterfaceTapDump(request); - final SwInterfaceTapDetailsReplyDump reply = - TranslateUtils.getReply(swInterfaceTapDetailsReplyDumpCompletionStage.toCompletableFuture()); - - if(null == reply || null == reply.swInterfaceTapDetails) { - mappedTaps = Collections.emptyMap(); - } else { - final List<SwInterfaceTapDetails> swInterfaceTapDetails = reply.swInterfaceTapDetails; - // Cache interfaces dump in per-tx context to later be used in readCurrentAttributes - mappedTaps = swInterfaceTapDetails.stream() - .collect(Collectors.toMap(t -> t.swIfIndex, swInterfaceDetails -> swInterfaceDetails)); + try { + final InterfaceKey key = id.firstKeyOf(Interface.class); + // Relying here that parent InterfaceCustomizer was invoked first (PREORDER) + // to fill in the context with initial ifc mapping + final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext()); + if (!isInterfaceOfType(ctx.getModificationCache(), index, org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.Tap.class)) { + return; } - ctx.getModificationCache().put(DUMPED_TAPS_CONTEXT_KEY, mappedTaps); - } + LOG.debug("Reading attributes for tap interface: {}", key.getName()); + + @SuppressWarnings("unchecked") + Map<Integer, SwInterfaceTapDetails> mappedTaps = + (Map<Integer, SwInterfaceTapDetails>) ctx.getModificationCache().get(DUMPED_TAPS_CONTEXT_KEY); + + if(mappedTaps == null) { + // Full Tap dump has to be performed here, no filter or anything is here to help so at least we cache it + final SwInterfaceTapDump request = new SwInterfaceTapDump(); + final CompletionStage<SwInterfaceTapDetailsReplyDump> swInterfaceTapDetailsReplyDumpCompletionStage = + getFutureJVpp().swInterfaceTapDump(request); + final SwInterfaceTapDetailsReplyDump reply = + TranslateUtils.getReply(swInterfaceTapDetailsReplyDumpCompletionStage.toCompletableFuture()); + + if(null == reply || null == reply.swInterfaceTapDetails) { + mappedTaps = Collections.emptyMap(); + } else { + final List<SwInterfaceTapDetails> swInterfaceTapDetails = reply.swInterfaceTapDetails; + // Cache interfaces dump in per-tx context to later be used in readCurrentAttributes + mappedTaps = swInterfaceTapDetails.stream() + .collect(Collectors.toMap(t -> t.swIfIndex, swInterfaceDetails -> swInterfaceDetails)); + } + + ctx.getModificationCache().put(DUMPED_TAPS_CONTEXT_KEY, mappedTaps); + } - final SwInterfaceTapDetails swInterfaceTapDetails = mappedTaps.get(index); - LOG.trace("Tap interface: {} attributes returned from VPP: {}", key.getName(), swInterfaceTapDetails); + final SwInterfaceTapDetails swInterfaceTapDetails = mappedTaps.get(index); + LOG.trace("Tap interface: {} attributes returned from VPP: {}", key.getName(), swInterfaceTapDetails); - builder.setTapName(TranslateUtils.toString(swInterfaceTapDetails.devName)); - LOG.debug("Tap interface: {}, id: {} attributes read as: {}", key.getName(), index, builder); + builder.setTapName(TranslateUtils.toString(swInterfaceTapDetails.devName)); + LOG.debug("Tap interface: {}, id: {} attributes read as: {}", key.getName(), index, builder); + } catch (VppBaseCallException e) { + LOG.warn("Failed to readCurrentAttributes for: {}", id); + throw new ReadFailedException(id); + } } } diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VhostUserCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VhostUserCustomizer.java index de7514524..7085392f6 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VhostUserCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VhostUserCustomizer.java @@ -16,21 +16,12 @@ package io.fd.honeycomb.v3po.translate.v3po.interfacesstate; -import static io.fd.honeycomb.v3po.translate.v3po.interfacesstate.InterfaceUtils.isInterfaceOfType; - import io.fd.honeycomb.v3po.translate.read.ReadContext; 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.util.NamingContext; import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils; -import java.math.BigInteger; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.concurrent.CompletionStage; -import java.util.stream.Collectors; -import javax.annotation.Nonnull; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VhostUserRole; @@ -40,6 +31,7 @@ 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.jvpp.VppBaseCallException; import org.openvpp.jvpp.dto.SwInterfaceVhostUserDetails; import org.openvpp.jvpp.dto.SwInterfaceVhostUserDetailsReplyDump; import org.openvpp.jvpp.dto.SwInterfaceVhostUserDump; @@ -47,6 +39,16 @@ import org.openvpp.jvpp.future.FutureJVpp; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.annotation.Nonnull; +import java.math.BigInteger; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletionStage; +import java.util.stream.Collectors; + +import static io.fd.honeycomb.v3po.translate.v3po.interfacesstate.InterfaceUtils.isInterfaceOfType; + public class VhostUserCustomizer extends FutureJVppCustomizer implements ChildReaderCustomizer<VhostUser, VhostUserBuilder> { @@ -75,51 +77,56 @@ public class VhostUserCustomizer extends FutureJVppCustomizer public void readCurrentAttributes(@Nonnull final InstanceIdentifier<VhostUser> id, @Nonnull final VhostUserBuilder builder, @Nonnull final ReadContext ctx) throws ReadFailedException { - final InterfaceKey key = id.firstKeyOf(Interface.class); - // Relying here that parent InterfaceCustomizer was invoked first (PREORDER) - // to fill in the context with initial ifc mapping - final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext()); - if (!isInterfaceOfType(ctx.getModificationCache(), index, org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VhostUser.class)) { - return; - } + try { + final InterfaceKey key = id.firstKeyOf(Interface.class); + // Relying here that parent InterfaceCustomizer was invoked first (PREORDER) + // to fill in the context with initial ifc mapping + final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext()); + if (!isInterfaceOfType(ctx.getModificationCache(), index, org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VhostUser.class)) { + return; + } - LOG.debug("Reading attributes for vhpost user interface: {}", key.getName()); - - @SuppressWarnings("unchecked") - Map<Integer, SwInterfaceVhostUserDetails> mappedVhostUsers = - (Map<Integer, SwInterfaceVhostUserDetails>) ctx.getModificationCache().get(DUMPED_VHOST_USERS_CONTEXT_KEY); - - if(mappedVhostUsers == null) { - // Full VhostUser dump has to be performed here, no filter or anything is here to help so at least we cache it - final SwInterfaceVhostUserDump request = new SwInterfaceVhostUserDump(); - final CompletionStage<SwInterfaceVhostUserDetailsReplyDump> swInterfaceVhostUserDetailsReplyDumpCompletionStage = - getFutureJVpp().swInterfaceVhostUserDump(request); - final SwInterfaceVhostUserDetailsReplyDump reply = - TranslateUtils.getReply(swInterfaceVhostUserDetailsReplyDumpCompletionStage.toCompletableFuture()); - - if(null == reply || null == reply.swInterfaceVhostUserDetails) { - mappedVhostUsers = Collections.emptyMap(); - } else { - final List<SwInterfaceVhostUserDetails> swInterfaceVhostUserDetails = reply.swInterfaceVhostUserDetails; - // Cache interfaces dump in per-tx context to later be used in readCurrentAttributes - mappedVhostUsers = swInterfaceVhostUserDetails.stream() - .collect(Collectors.toMap(t -> t.swIfIndex, swInterfaceDetails -> swInterfaceDetails)); + LOG.debug("Reading attributes for vhpost user interface: {}", key.getName()); + + @SuppressWarnings("unchecked") + Map<Integer, SwInterfaceVhostUserDetails> mappedVhostUsers = + (Map<Integer, SwInterfaceVhostUserDetails>) ctx.getModificationCache().get(DUMPED_VHOST_USERS_CONTEXT_KEY); + + if(mappedVhostUsers == null) { + // Full VhostUser dump has to be performed here, no filter or anything is here to help so at least we cache it + final SwInterfaceVhostUserDump request = new SwInterfaceVhostUserDump(); + final CompletionStage<SwInterfaceVhostUserDetailsReplyDump> swInterfaceVhostUserDetailsReplyDumpCompletionStage = + getFutureJVpp().swInterfaceVhostUserDump(request); + final SwInterfaceVhostUserDetailsReplyDump reply = + TranslateUtils.getReply(swInterfaceVhostUserDetailsReplyDumpCompletionStage.toCompletableFuture()); + + if(null == reply || null == reply.swInterfaceVhostUserDetails) { + mappedVhostUsers = Collections.emptyMap(); + } else { + final List<SwInterfaceVhostUserDetails> swInterfaceVhostUserDetails = reply.swInterfaceVhostUserDetails; + // Cache interfaces dump in per-tx context to later be used in readCurrentAttributes + mappedVhostUsers = swInterfaceVhostUserDetails.stream() + .collect(Collectors.toMap(t -> t.swIfIndex, swInterfaceDetails -> swInterfaceDetails)); + } + + ctx.getModificationCache().put(DUMPED_VHOST_USERS_CONTEXT_KEY, mappedVhostUsers); } - ctx.getModificationCache().put(DUMPED_VHOST_USERS_CONTEXT_KEY, mappedVhostUsers); + // Relying here that parent InterfaceCustomizer was invoked first to fill in the context with initial ifc mapping + final SwInterfaceVhostUserDetails swInterfaceVhostUserDetails = mappedVhostUsers.get(index); + LOG.trace("Vhost user interface: {} attributes returned from VPP: {}", key.getName(), swInterfaceVhostUserDetails); + + builder.setRole(swInterfaceVhostUserDetails.isServer == 1 ? VhostUserRole.Server : VhostUserRole.Client); + builder.setFeatures(BigInteger.valueOf(swInterfaceVhostUserDetails.features)); + builder.setNumMemoryRegions((long) swInterfaceVhostUserDetails.numRegions); + builder.setSocket(TranslateUtils.toString(swInterfaceVhostUserDetails.sockFilename)); + builder.setVirtioNetHdrSize((long) swInterfaceVhostUserDetails.virtioNetHdrSz); + builder.setConnectError(Integer.toString(swInterfaceVhostUserDetails.sockErrno)); + + LOG.debug("Vhost user interface: {}, id: {} attributes read as: {}", key.getName(), index, builder); + } catch (VppBaseCallException e) { + LOG.warn("Failed to readCurrentAttributes for: {}", id); + throw new ReadFailedException(id); } - - // Relying here that parent InterfaceCustomizer was invoked first to fill in the context with initial ifc mapping - final SwInterfaceVhostUserDetails swInterfaceVhostUserDetails = mappedVhostUsers.get(index); - LOG.trace("Vhost user interface: {} attributes returned from VPP: {}", key.getName(), swInterfaceVhostUserDetails); - - builder.setRole(swInterfaceVhostUserDetails.isServer == 1 ? VhostUserRole.Server : VhostUserRole.Client); - builder.setFeatures(BigInteger.valueOf(swInterfaceVhostUserDetails.features)); - builder.setNumMemoryRegions((long) swInterfaceVhostUserDetails.numRegions); - builder.setSocket(TranslateUtils.toString(swInterfaceVhostUserDetails.sockFilename)); - builder.setVirtioNetHdrSize((long) swInterfaceVhostUserDetails.virtioNetHdrSz); - builder.setConnectError(Integer.toString(swInterfaceVhostUserDetails.sockErrno)); - - LOG.debug("Vhost user interface: {}, id: {} attributes read as: {}", key.getName(), index, builder); } } diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanCustomizer.java index b870fe260..41f4b6edc 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanCustomizer.java @@ -16,19 +16,12 @@ package io.fd.honeycomb.v3po.translate.v3po.interfacesstate; -import static com.google.common.base.Preconditions.checkState; - import io.fd.honeycomb.v3po.translate.read.ReadContext; 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.util.NamingContext; import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Arrays; -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.IpAddress; 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.Ipv6Address; @@ -42,6 +35,7 @@ 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.jvpp.VppBaseCallException; import org.openvpp.jvpp.dto.VxlanTunnelDetails; import org.openvpp.jvpp.dto.VxlanTunnelDetailsReplyDump; import org.openvpp.jvpp.dto.VxlanTunnelDump; @@ -49,6 +43,14 @@ import org.openvpp.jvpp.future.FutureJVpp; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.annotation.Nonnull; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Arrays; +import java.util.concurrent.CompletionStage; + +import static com.google.common.base.Preconditions.checkState; + public class VxlanCustomizer extends FutureJVppCustomizer implements ChildReaderCustomizer<Vxlan, VxlanBuilder> { @@ -76,57 +78,62 @@ public class VxlanCustomizer extends FutureJVppCustomizer public void readCurrentAttributes(@Nonnull final InstanceIdentifier<Vxlan> id, @Nonnull final VxlanBuilder builder, @Nonnull final ReadContext ctx) throws ReadFailedException { - final InterfaceKey key = id.firstKeyOf(Interface.class); - // Relying here that parent InterfaceCustomizer was invoked first (PREORDER) - // to fill in the context with initial ifc mapping - final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext()); - if (!InterfaceUtils.isInterfaceOfType(ctx.getModificationCache(), index, VxlanTunnel.class)) { - return; - } + try { + final InterfaceKey key = id.firstKeyOf(Interface.class); + // Relying here that parent InterfaceCustomizer was invoked first (PREORDER) + // to fill in the context with initial ifc mapping + final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext()); + if (!InterfaceUtils.isInterfaceOfType(ctx.getModificationCache(), index, VxlanTunnel.class)) { + return; + } - LOG.debug("Reading attributes for vxlan tunnel: {}", key.getName()); - // Dump just a single - final VxlanTunnelDump request = new VxlanTunnelDump(); - request.swIfIndex = index; - - final CompletionStage<VxlanTunnelDetailsReplyDump> swInterfaceVxlanDetailsReplyDumpCompletionStage = - getFutureJVpp().vxlanTunnelDump(request); - final VxlanTunnelDetailsReplyDump reply = - TranslateUtils.getReply(swInterfaceVxlanDetailsReplyDumpCompletionStage.toCompletableFuture()); - - // VPP keeps vxlan tunnel interfaces even after they were deleted (optimization) - // However there ar no longer any vxlan tunnel specific fields assigned to it and this call - // returns nothing - if (reply == null || reply.vxlanTunnelDetails == null || reply.vxlanTunnelDetails.isEmpty()) { - LOG.debug( - "Vxlan tunnel {}, id {} has no attributes assigned in VPP. Probably is a leftover interface placeholder" + - "after delete", key.getName(), index); - return; - } + LOG.debug("Reading attributes for vxlan tunnel: {}", key.getName()); + // Dump just a single + final VxlanTunnelDump request = new VxlanTunnelDump(); + request.swIfIndex = index; + + final CompletionStage<VxlanTunnelDetailsReplyDump> swInterfaceVxlanDetailsReplyDumpCompletionStage = + getFutureJVpp().vxlanTunnelDump(request); + final VxlanTunnelDetailsReplyDump reply = + TranslateUtils.getReply(swInterfaceVxlanDetailsReplyDumpCompletionStage.toCompletableFuture()); + + // VPP keeps vxlan tunnel interfaces even after they were deleted (optimization) + // However there ar no longer any vxlan tunnel specific fields assigned to it and this call + // returns nothing + if (reply == null || reply.vxlanTunnelDetails == null || reply.vxlanTunnelDetails.isEmpty()) { + LOG.debug( + "Vxlan tunnel {}, id {} has no attributes assigned in VPP. Probably is a leftover interface placeholder" + + "after delete", key.getName(), index); + return; + } + + checkState(reply.vxlanTunnelDetails.size() == 1, + "Unexpected number of returned vxlan tunnels: {} for tunnel: {}", reply.vxlanTunnelDetails, key.getName()); + LOG.trace("Vxlan tunnel: {} attributes returned from VPP: {}", key.getName(), reply); - checkState(reply.vxlanTunnelDetails.size() == 1, - "Unexpected number of returned vxlan tunnels: {} for tunnel: {}", reply.vxlanTunnelDetails, key.getName()); - LOG.trace("Vxlan tunnel: {} attributes returned from VPP: {}", key.getName(), reply); - - final VxlanTunnelDetails swInterfaceVxlanDetails = reply.vxlanTunnelDetails.get(0); - if (swInterfaceVxlanDetails.isIpv6 == 1) { - final Ipv6Address dstIpv6 = - new Ipv6Address(parseAddress(swInterfaceVxlanDetails.dstAddress).getHostAddress()); - builder.setDst(new IpAddress(dstIpv6)); - final Ipv6Address srcIpv6 = - new Ipv6Address(parseAddress(swInterfaceVxlanDetails.srcAddress).getHostAddress()); - builder.setSrc(new IpAddress(srcIpv6)); - } else { - final byte[] dstBytes = Arrays.copyOfRange(swInterfaceVxlanDetails.dstAddress, 0, 4); - final Ipv4Address dstIpv4 = new Ipv4Address(parseAddress(dstBytes).getHostAddress()); - builder.setDst(new IpAddress(dstIpv4)); - final byte[] srcBytes = Arrays.copyOfRange(swInterfaceVxlanDetails.srcAddress, 0, 4); - final Ipv4Address srcIpv4 = new Ipv4Address(parseAddress(srcBytes).getHostAddress()); - builder.setSrc(new IpAddress(srcIpv4)); + final VxlanTunnelDetails swInterfaceVxlanDetails = reply.vxlanTunnelDetails.get(0); + if (swInterfaceVxlanDetails.isIpv6 == 1) { + final Ipv6Address dstIpv6 = + new Ipv6Address(parseAddress(swInterfaceVxlanDetails.dstAddress).getHostAddress()); + builder.setDst(new IpAddress(dstIpv6)); + final Ipv6Address srcIpv6 = + new Ipv6Address(parseAddress(swInterfaceVxlanDetails.srcAddress).getHostAddress()); + builder.setSrc(new IpAddress(srcIpv6)); + } else { + final byte[] dstBytes = Arrays.copyOfRange(swInterfaceVxlanDetails.dstAddress, 0, 4); + final Ipv4Address dstIpv4 = new Ipv4Address(parseAddress(dstBytes).getHostAddress()); + builder.setDst(new IpAddress(dstIpv4)); + final byte[] srcBytes = Arrays.copyOfRange(swInterfaceVxlanDetails.srcAddress, 0, 4); + final Ipv4Address srcIpv4 = new Ipv4Address(parseAddress(srcBytes).getHostAddress()); + builder.setSrc(new IpAddress(srcIpv4)); + } + builder.setEncapVrfId((long) swInterfaceVxlanDetails.encapVrfId); + builder.setVni( new VxlanVni((long) swInterfaceVxlanDetails.vni)); + LOG.debug("Vxlan tunnel: {}, id: {} attributes read as: {}", key.getName(), index, builder); + } catch (VppBaseCallException e) { + LOG.warn("Failed to readCurrentAttributes for: {}", id); + throw new ReadFailedException( id, e ); } - builder.setEncapVrfId((long) swInterfaceVxlanDetails.encapVrfId); - builder.setVni(new VxlanVni((long) swInterfaceVxlanDetails.vni)); - LOG.debug("Vxlan tunnel: {}, id: {} attributes read as: {}", key.getName(), index, builder); } @Nonnull diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanGpeCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanGpeCustomizer.java index 254b83961..d364eca1a 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanGpeCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanGpeCustomizer.java @@ -43,6 +43,9 @@ 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.jvpp.VppBaseCallException; +import org.openvpp.jvpp.VppCallbackException; +import org.openvpp.jvpp.VppInvocationException; import org.openvpp.jvpp.dto.VxlanGpeTunnelDetails; import org.openvpp.jvpp.dto.VxlanGpeTunnelDetailsReplyDump; import org.openvpp.jvpp.dto.VxlanGpeTunnelDump; @@ -77,59 +80,64 @@ public class VxlanGpeCustomizer extends FutureJVppCustomizer public void readCurrentAttributes(@Nonnull final InstanceIdentifier<VxlanGpe> id, @Nonnull final VxlanGpeBuilder builder, @Nonnull final ReadContext ctx) throws ReadFailedException { - final InterfaceKey key = id.firstKeyOf(Interface.class); - // Relying here that parent InterfaceCustomizer was invoked first (PREORDER) - // to fill in the context with initial ifc mapping - final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext()); - if (!InterfaceUtils.isInterfaceOfType(ctx.getModificationCache(), index, VxlanGpeTunnel.class)) { - return; - } + try { + final InterfaceKey key = id.firstKeyOf(Interface.class); + // Relying here that parent InterfaceCustomizer was invoked first (PREORDER) + // to fill in the context with initial ifc mapping + final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext()); + if (!InterfaceUtils.isInterfaceOfType(ctx.getModificationCache(), index, VxlanGpeTunnel.class)) { + return; + } - LOG.debug("Reading attributes for VxlanGpe tunnel: {}", key.getName()); - // Dump just a single - final VxlanGpeTunnelDump request = new VxlanGpeTunnelDump(); - request.swIfIndex = index; + LOG.debug("Reading attributes for VxlanGpe tunnel: {}", key.getName()); + // Dump just a single + final VxlanGpeTunnelDump request = new VxlanGpeTunnelDump(); + request.swIfIndex = index; - final CompletionStage<VxlanGpeTunnelDetailsReplyDump> swInterfaceVxlanGpeDetailsReplyDumpCompletionStage = - getFutureJVpp().vxlanGpeTunnelDump(request); - final VxlanGpeTunnelDetailsReplyDump reply = - TranslateUtils.getReply(swInterfaceVxlanGpeDetailsReplyDumpCompletionStage.toCompletableFuture()); + final CompletionStage<VxlanGpeTunnelDetailsReplyDump> swInterfaceVxlanGpeDetailsReplyDumpCompletionStage = + getFutureJVpp().vxlanGpeTunnelDump(request); + final VxlanGpeTunnelDetailsReplyDump reply = + TranslateUtils.getReply(swInterfaceVxlanGpeDetailsReplyDumpCompletionStage.toCompletableFuture()); - // VPP keeps VxlanGpe tunnel interfaces even after they were deleted (optimization) - // However there are no longer any VxlanGpe tunnel specific fields assigned to it and this call - // returns nothing - if (reply == null || reply.vxlanGpeTunnelDetails == null || reply.vxlanGpeTunnelDetails.isEmpty()) { - LOG.debug( - "VxlanGpe tunnel {}, id {} has no attributes assigned in VPP. Probably is a leftover interface placeholder" + - "after delete", key.getName(), index); - return; - } + // VPP keeps VxlanGpe tunnel interfaces even after they were deleted (optimization) + // However there are no longer any VxlanGpe tunnel specific fields assigned to it and this call + // returns nothing + if (reply == null || reply.vxlanGpeTunnelDetails == null || reply.vxlanGpeTunnelDetails.isEmpty()) { + LOG.debug( + "VxlanGpe tunnel {}, id {} has no attributes assigned in VPP. Probably is a leftover interface placeholder" + + "after delete", key.getName(), index); + return; + } - checkState(reply.vxlanGpeTunnelDetails.size() == 1, - "Unexpected number of returned VxlanGpe tunnels: {} for tunnel: {}", reply.vxlanGpeTunnelDetails, key.getName()); - LOG.trace("VxlanGpe tunnel: {} attributes returned from VPP: {}", key.getName(), reply); + checkState(reply.vxlanGpeTunnelDetails.size() == 1, + "Unexpected number of returned VxlanGpe tunnels: {} for tunnel: {}", reply.vxlanGpeTunnelDetails, key.getName()); + LOG.trace("VxlanGpe tunnel: {} attributes returned from VPP: {}", key.getName(), reply); - final VxlanGpeTunnelDetails swInterfaceVxlanGpeDetails = reply.vxlanGpeTunnelDetails.get(0); - if (swInterfaceVxlanGpeDetails.isIpv6 == 1) { - final Ipv6Address remote6 = - new Ipv6Address(parseAddress(swInterfaceVxlanGpeDetails.remote).getHostAddress()); - builder.setRemote(new IpAddress(remote6)); - final Ipv6Address local6 = - new Ipv6Address(parseAddress(swInterfaceVxlanGpeDetails.local).getHostAddress()); - builder.setLocal(new IpAddress(local6)); - } else { - final byte[] dstBytes = Arrays.copyOfRange(swInterfaceVxlanGpeDetails.remote, 0, 4); - final Ipv4Address remote4 = new Ipv4Address(parseAddress(dstBytes).getHostAddress()); - builder.setRemote(new IpAddress(remote4)); - final byte[] srcBytes = Arrays.copyOfRange(swInterfaceVxlanGpeDetails.local, 0, 4); - final Ipv4Address local4 = new Ipv4Address(parseAddress(srcBytes).getHostAddress()); - builder.setLocal(new IpAddress(local4)); - } - builder.setVni(new VxlanGpeVni((long) swInterfaceVxlanGpeDetails.vni)); + final VxlanGpeTunnelDetails swInterfaceVxlanGpeDetails = reply.vxlanGpeTunnelDetails.get(0); + if (swInterfaceVxlanGpeDetails.isIpv6 == 1) { + final Ipv6Address remote6 = + new Ipv6Address(parseAddress(swInterfaceVxlanGpeDetails.remote).getHostAddress()); + builder.setRemote(new IpAddress(remote6)); + final Ipv6Address local6 = + new Ipv6Address(parseAddress(swInterfaceVxlanGpeDetails.local).getHostAddress()); + builder.setLocal(new IpAddress(local6)); + } else { + final byte[] dstBytes = Arrays.copyOfRange(swInterfaceVxlanGpeDetails.remote, 0, 4); + final Ipv4Address remote4 = new Ipv4Address(parseAddress(dstBytes).getHostAddress()); + builder.setRemote(new IpAddress(remote4)); + final byte[] srcBytes = Arrays.copyOfRange(swInterfaceVxlanGpeDetails.local, 0, 4); + final Ipv4Address local4 = new Ipv4Address(parseAddress(srcBytes).getHostAddress()); + builder.setLocal(new IpAddress(local4)); + } + builder.setVni(new VxlanGpeVni((long) swInterfaceVxlanGpeDetails.vni)); builder.setNextProtocol(VxlanGpeNextProtocol.forValue(swInterfaceVxlanGpeDetails.protocol)); - builder.setEncapVrfId((long) swInterfaceVxlanGpeDetails.encapVrfId); - builder.setDecapVrfId((long) swInterfaceVxlanGpeDetails.decapVrfId); - LOG.debug("VxlanGpe tunnel: {}, id: {} attributes read as: {}", key.getName(), index, builder); + builder.setEncapVrfId((long) swInterfaceVxlanGpeDetails.encapVrfId); + builder.setDecapVrfId((long) swInterfaceVxlanGpeDetails.decapVrfId); + LOG.debug("VxlanGpe tunnel: {}, id: {} attributes read as: {}", key.getName(), index, builder); + } catch (VppBaseCallException e) { + LOG.warn("Failed to readCurrentAttributes for: {}", id); + throw new ReadFailedException( id, e ); + } } @Nonnull 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 750ff575e..a8f13c635 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 @@ -16,32 +16,33 @@ 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 com.google.common.base.Optional; import com.google.common.base.Preconditions; import io.fd.honeycomb.v3po.translate.spi.write.ListWriterCustomizer; import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer; import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext; import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils; -import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException; import io.fd.honeycomb.v3po.translate.write.WriteContext; import io.fd.honeycomb.v3po.translate.write.WriteFailedException; -import java.util.List; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.BridgeDomains; 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.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.VppBaseCallException; 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; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.List; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + public class BridgeDomainCustomizer extends FutureJVppCustomizer implements ListWriterCustomizer<BridgeDomain, BridgeDomainKey> { @@ -64,7 +65,8 @@ public class BridgeDomainCustomizer } private BridgeDomainAddDelReply addOrUpdateBridgeDomain(final int bdId, @Nonnull final BridgeDomain bd) - throws VppApiInvocationException { + throws VppBaseCallException { + final BridgeDomainAddDelReply reply; final BridgeDomainAddDel request = new BridgeDomainAddDel(); request.bdId = bdId; request.flood = booleanToByte(bd.isFlood()); @@ -74,15 +76,8 @@ public class BridgeDomainCustomizer request.arpTerm = booleanToByte(bd.isArpTermination()); request.isAdd = ADD_OR_UPDATE_BD; - final BridgeDomainAddDelReply reply = - TranslateUtils.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); - } - + reply = TranslateUtils.getReply(getFutureJVpp().bridgeDomainAddDel(request).toCompletableFuture()); + LOG.debug("Bridge domain {} (id={}) add/update successful", bd.getName(), bdId); return reply; } @@ -102,7 +97,7 @@ public class BridgeDomainCustomizer } addOrUpdateBridgeDomain(index, dataBefore); bdContext.addName(index, bdName, ctx.getMappingContext()); - } catch (VppApiInvocationException e) { + } catch (VppBaseCallException e) { LOG.warn("Failed to create bridge domain", e); throw new WriteFailedException.CreateFailedException(id, dataBefore, e); } @@ -119,20 +114,19 @@ public class BridgeDomainCustomizer @Nonnull final BridgeDomain dataBefore, @Nonnull final WriteContext ctx) throws WriteFailedException.DeleteFailedException { LOG.debug("deleteCurrentAttributes: id={}, dataBefore={}, ctx={}", id, dataBefore, ctx); - final String bdName = id.firstKeyOf(BridgeDomain.class).getName(); - int bdId = bdContext.getIndex(bdName, ctx.getMappingContext()); - final BridgeDomainAddDel request = new BridgeDomainAddDel(); - request.bdId = bdId; + int bdId = bdId = bdContext.getIndex(bdName, ctx.getMappingContext()); + try { - final BridgeDomainAddDelReply reply = - TranslateUtils.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 { + final BridgeDomainAddDel request = new BridgeDomainAddDel(); + request.bdId = bdId; + + final BridgeDomainAddDelReply reply = + TranslateUtils.getReply(getFutureJVpp().bridgeDomainAddDel(request).toCompletableFuture()); LOG.debug("Bridge domain {} (id={}) deleted successfully", bdName, bdId); + } catch (VppBaseCallException e) { + LOG.warn("Bridge domain {} (id={}) delete failed", bdName, bdId); + throw new WriteFailedException.DeleteFailedException(id,e); } } @@ -149,7 +143,7 @@ public class BridgeDomainCustomizer try { addOrUpdateBridgeDomain(bdContext.getIndex(bdName, ctx.getMappingContext()), dataAfter); - } catch (VppApiInvocationException e) { + } catch (VppBaseCallException 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/VersionCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VersionCustomizer.java index 8122fd245..5dc6596ad 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 @@ -29,6 +29,9 @@ 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.jvpp.VppBaseCallException; +import org.openvpp.jvpp.VppCallbackException; +import org.openvpp.jvpp.VppInvocationException; import org.openvpp.jvpp.dto.ShowVersion; import org.openvpp.jvpp.dto.ShowVersionReply; import org.openvpp.jvpp.future.FutureJVpp; @@ -60,15 +63,19 @@ public final class VersionCustomizer @Override public void readCurrentAttributes(@Nonnull InstanceIdentifier<Version> id, @Nonnull final VersionBuilder builder, @Nonnull final ReadContext context) throws ReadFailedException { - // Execute with timeout - final CompletionStage<ShowVersionReply> showVersionFuture = getFutureJVpp().showVersion(new ShowVersion()); - final ShowVersionReply reply = TranslateUtils.getReply(showVersionFuture.toCompletableFuture(), id, - DEFAULT_TIMEOUT_IN_SECONDS); + try { + // Execute with timeout + final CompletionStage<ShowVersionReply> showVersionFuture = getFutureJVpp().showVersion(new ShowVersion()); + final ShowVersionReply reply = TranslateUtils.getReply(showVersionFuture.toCompletableFuture(), id, + DEFAULT_TIMEOUT_IN_SECONDS); - builder.setBranch(TranslateUtils.toString(reply.version)); - builder.setName(TranslateUtils.toString(reply.program)); - builder.setBuildDate(TranslateUtils.toString(reply.buildDate)); - builder.setBuildDirectory(TranslateUtils.toString(reply.buildDirectory)); + builder.setBranch(TranslateUtils.toString(reply.version)); + builder.setName(TranslateUtils.toString(reply.program)); + builder.setBuildDate(TranslateUtils.toString(reply.buildDate)); + builder.setBuildDirectory(TranslateUtils.toString(reply.buildDirectory)); + } catch (VppBaseCallException e) { + throw new ReadFailedException(id); + } } } diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/RewriteCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/RewriteCustomizerTest.java index 068f9147e..655bda525 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/RewriteCustomizerTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/RewriteCustomizerTest.java @@ -16,23 +16,14 @@ package io.fd.honeycomb.v3po.translate.v3po.interfaces; -import static io.fd.honeycomb.v3po.translate.v3po.test.ContextTestUtils.getMapping; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.verify; -import static org.mockito.MockitoAnnotations.initMocks; - import com.google.common.base.Optional; import io.fd.honeycomb.v3po.translate.MappingContext; +import io.fd.honeycomb.v3po.translate.v3po.test.TestHelperUtils; import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext; import io.fd.honeycomb.v3po.translate.v3po.util.TagRewriteOperation; -import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException; import io.fd.honeycomb.v3po.translate.write.WriteContext; import io.fd.honeycomb.v3po.translate.write.WriteFailedException; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; @@ -41,6 +32,7 @@ import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.cont import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.*; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.SubinterfaceAugmentation; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527._802dot1q; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.interfaces._interface.SubInterfaces; @@ -50,10 +42,24 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.l2.RewriteBuilder; import org.opendaylight.yangtools.yang.binding.ChildOf; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.VppBaseCallException; +import org.openvpp.jvpp.VppInvocationException; import org.openvpp.jvpp.dto.L2InterfaceVlanTagRewrite; import org.openvpp.jvpp.dto.L2InterfaceVlanTagRewriteReply; import org.openvpp.jvpp.future.FutureJVpp; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + +import static io.fd.honeycomb.v3po.translate.v3po.test.ContextTestUtils.getMapping; +import static junit.framework.TestCase.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.verify; +import static org.mockito.MockitoAnnotations.initMocks; + public class RewriteCustomizerTest { @Mock @@ -106,23 +112,32 @@ public class RewriteCustomizerTest { return request; } - private void whenL2InterfaceVlanTagRewriteThen(final int retval) throws ExecutionException, InterruptedException { + /** + * Positive response + */ + private void whenL2InterfaceVlanTagRewriteThen() throws ExecutionException, InterruptedException, VppInvocationException { final CompletableFuture<L2InterfaceVlanTagRewriteReply> replyFuture = new CompletableFuture<>(); final L2InterfaceVlanTagRewriteReply reply = new L2InterfaceVlanTagRewriteReply(); - reply.retval = retval; replyFuture.complete(reply); doReturn(replyFuture).when(api).l2InterfaceVlanTagRewrite(any(L2InterfaceVlanTagRewrite.class)); } - private void whenL2InterfaceVlanTagRewriteThenSuccess() throws ExecutionException, InterruptedException { - whenL2InterfaceVlanTagRewriteThen(0); + /** + * Failure response send + */ + private void whenL2InterfaceVlanTagRewriteFailedThen(final int retval) throws ExecutionException, InterruptedException, VppInvocationException { + doReturn(TestHelperUtils.<L2InterfaceVlanTagRewriteReply>createFutureException(retval)).when(api).l2InterfaceVlanTagRewrite(any(L2InterfaceVlanTagRewrite.class)); + } + + private void whenL2InterfaceVlanTagRewriteThenSuccess() throws ExecutionException, InterruptedException, VppInvocationException { + whenL2InterfaceVlanTagRewriteThen(); } - private void whenL2InterfaceVlanTagRewriteThenFailure() throws ExecutionException, InterruptedException { - whenL2InterfaceVlanTagRewriteThen(-1); + private void whenL2InterfaceVlanTagRewriteThenFailure() throws ExecutionException, InterruptedException, VppInvocationException { + whenL2InterfaceVlanTagRewriteFailedThen(-1); } - private void verifyL2InterfaceVlanTagRewriteWasInvoked(final L2InterfaceVlanTagRewrite expected) { + private void verifyL2InterfaceVlanTagRewriteWasInvoked(final L2InterfaceVlanTagRewrite expected) throws VppInvocationException { ArgumentCaptor<L2InterfaceVlanTagRewrite> argumentCaptor = ArgumentCaptor.forClass(L2InterfaceVlanTagRewrite.class); verify(api).l2InterfaceVlanTagRewrite(argumentCaptor.capture()); final L2InterfaceVlanTagRewrite actual = argumentCaptor.getValue(); @@ -133,7 +148,7 @@ public class RewriteCustomizerTest { assertEquals(expected.tag2, actual.tag2); } - private void verifyL2InterfaceVlanTagRewriteDeleteWasInvoked() { + private void verifyL2InterfaceVlanTagRewriteDeleteWasInvoked() throws VppInvocationException { final L2InterfaceVlanTagRewrite request = new L2InterfaceVlanTagRewrite(); request.swIfIndex = VLAN_IF_INDEX; verifyL2InterfaceVlanTagRewriteWasInvoked(request); @@ -165,7 +180,7 @@ public class RewriteCustomizerTest { try { customizer.writeCurrentAttributes(id, vlanTagRewrite, writeContext); } catch (WriteFailedException.CreateFailedException e) { - assertEquals(VppApiInvocationException.class, e.getCause().getClass()); + assertTrue(e.getCause() instanceof VppBaseCallException); verifyL2InterfaceVlanTagRewriteWasInvoked(generateL2InterfaceVlanTagRewrite(VLAN_IF_INDEX, op)); return; } @@ -196,7 +211,7 @@ public class RewriteCustomizerTest { try { customizer.updateCurrentAttributes(id, before, after, writeContext); } catch (WriteFailedException.UpdateFailedException e) { - assertEquals(VppApiInvocationException.class, e.getCause().getClass()); + assertTrue(e.getCause() instanceof VppBaseCallException); verifyL2InterfaceVlanTagRewriteWasInvoked(generateL2InterfaceVlanTagRewrite(VLAN_IF_INDEX, TagRewriteOperation.pop_1)); return; } @@ -223,7 +238,7 @@ public class RewriteCustomizerTest { try { customizer.deleteCurrentAttributes(id, null, writeContext); } catch (WriteFailedException.DeleteFailedException e) { - assertEquals(VppApiInvocationException.class, e.getCause().getClass()); + Assert.assertTrue(e.getCause() instanceof VppBaseCallException); verifyL2InterfaceVlanTagRewriteDeleteWasInvoked(); return; } diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceCustomizerTest.java index a97e43697..5ed37aa40 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceCustomizerTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceCustomizerTest.java @@ -30,8 +30,8 @@ import static org.mockito.MockitoAnnotations.initMocks; import com.google.common.base.Optional; import io.fd.honeycomb.v3po.translate.MappingContext; +import io.fd.honeycomb.v3po.translate.v3po.test.TestHelperUtils; import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext; -import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException; import io.fd.honeycomb.v3po.translate.write.WriteContext; import io.fd.honeycomb.v3po.translate.write.WriteFailedException; import java.util.ArrayList; @@ -66,12 +66,25 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.tags.TagBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.tags.TagKey; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.VppBaseCallException; +import org.openvpp.jvpp.VppInvocationException; import org.openvpp.jvpp.dto.CreateSubif; import org.openvpp.jvpp.dto.CreateSubifReply; import org.openvpp.jvpp.dto.SwInterfaceSetFlags; import org.openvpp.jvpp.dto.SwInterfaceSetFlagsReply; import org.openvpp.jvpp.future.FutureJVpp; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.*; +import static org.mockito.MockitoAnnotations.initMocks; + public class SubInterfaceCustomizerTest { @Mock @@ -116,7 +129,7 @@ public class SubInterfaceCustomizerTest { } private static Tag generateTag(final short index, final Class<? extends Dot1qTagVlanType> tagType, - final Dot1qTag.VlanId vlanId) { + final Dot1qTag.VlanId vlanId) { TagBuilder tag = new TagBuilder(); tag.setIndex(index); tag.setKey(new TagKey(index)); @@ -160,35 +173,40 @@ public class SubInterfaceCustomizerTest { SubinterfaceAugmentation.class).child(SubInterfaces.class).child(SubInterface.class, new SubInterfaceKey(index)); } - private void whenCreateSubifThen(final int retval) throws ExecutionException, InterruptedException { + private void whenCreateSubifThen() throws ExecutionException, InterruptedException, VppBaseCallException { final CompletableFuture<CreateSubifReply> replyFuture = new CompletableFuture<>(); final CreateSubifReply reply = new CreateSubifReply(); - reply.retval = retval; replyFuture.complete(reply); doReturn(replyFuture).when(api).createSubif(any(CreateSubif.class)); } - private void whenSwInterfaceSetFlagsThen(final int retval) throws ExecutionException, InterruptedException { + /** + * Failure response send + */ + private void whenCreateSubifFailedThen(final int retval) throws ExecutionException, InterruptedException, VppBaseCallException { + doReturn(TestHelperUtils.<CreateSubifReply>createFutureException(retval)).when(api).createSubif(any(CreateSubif.class)); + } + + private void whenSwInterfaceSetFlagsThen(final int retval) throws ExecutionException, InterruptedException, VppBaseCallException { final CompletableFuture<SwInterfaceSetFlagsReply> replyFuture = new CompletableFuture<>(); final SwInterfaceSetFlagsReply reply = new SwInterfaceSetFlagsReply(); - reply.retval = retval; replyFuture.complete(reply); doReturn(replyFuture).when(api).swInterfaceSetFlags(any(SwInterfaceSetFlags.class)); } - private void whenCreateSubifThenSuccess() throws ExecutionException, InterruptedException { - whenCreateSubifThen(0); + private void whenCreateSubifThenSuccess() throws ExecutionException, InterruptedException, VppBaseCallException { + whenCreateSubifThen(); } - private void whenCreateSubifThenFailure() throws ExecutionException, InterruptedException { - whenCreateSubifThen(-1); + private void whenCreateSubifThenFailure() throws ExecutionException, InterruptedException, VppBaseCallException { + whenCreateSubifFailedThen(-1); } - - private void whenSwInterfaceSetFlagsThenSuccess() throws ExecutionException, InterruptedException { + + private void whenSwInterfaceSetFlagsThenSuccess() throws ExecutionException, InterruptedException, VppBaseCallException { whenSwInterfaceSetFlagsThen(0); } - private CreateSubif verifyCreateSubifWasInvoked(final CreateSubif expected) { + private CreateSubif verifyCreateSubifWasInvoked(final CreateSubif expected) throws VppBaseCallException { ArgumentCaptor<CreateSubif> argumentCaptor = ArgumentCaptor.forClass(CreateSubif.class); verify(api).createSubif(argumentCaptor.capture()); final CreateSubif actual = argumentCaptor.getValue(); @@ -208,7 +226,7 @@ public class SubInterfaceCustomizerTest { return actual; } - private SwInterfaceSetFlags verifySwInterfaceSetFlagsWasInvoked(final SwInterfaceSetFlags expected) { + private SwInterfaceSetFlags verifySwInterfaceSetFlagsWasInvoked(final SwInterfaceSetFlags expected) throws VppBaseCallException{ ArgumentCaptor<SwInterfaceSetFlags> argumentCaptor = ArgumentCaptor.forClass(SwInterfaceSetFlags.class); verify(api).swInterfaceSetFlags(argumentCaptor.capture()); final SwInterfaceSetFlags actual = argumentCaptor.getValue(); @@ -249,7 +267,7 @@ public class SubInterfaceCustomizerTest { try { customizer.writeCurrentAttributes(id, subInterface, writeContext); } catch (WriteFailedException.CreateFailedException e) { - assertEquals(VppApiInvocationException.class, e.getCause().getClass()); + assertTrue(e.getCause() instanceof VppBaseCallException ); verifyCreateSubifWasInvoked(generateSubInterfaceRequest(SUPER_IF_ID)); verify(mappingContext, times(0)).put( eq(getMappingIid(subIfaceName, "test-instance")), diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/TapCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/TapCustomizerTest.java index 61a94f8d2..ea6990f60 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/TapCustomizerTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/TapCustomizerTest.java @@ -87,7 +87,6 @@ public class TapCustomizerTest { final CompletableFuture<Object> reply = new CompletableFuture<>(); final TapConnectReply t = new TapConnectReply(); t.swIfIndex = idx++; - t.retval = 0; reply.complete(t); return reply; } @@ -112,7 +111,6 @@ public class TapCustomizerTest { final CompletableFuture<TapModifyReply> replyModif = new CompletableFuture<>(); final TapModifyReply tmodif = new TapModifyReply(); tmodif.swIfIndex = 0; - tmodif.retval = 0; replyModif.complete(tmodif); doReturn(replyModif).when(vppApi).tapModify(any(TapModify.class)); @@ -136,7 +134,6 @@ public class TapCustomizerTest { final CompletableFuture<TapDeleteReply> replyDelete = new CompletableFuture<>(); final TapDeleteReply tmodif = new TapDeleteReply(); - tmodif.retval = 0; replyDelete.complete(tmodif); doReturn(replyDelete).when(vppApi).tapDelete(any(TapDelete.class)); diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VhostUserCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VhostUserCustomizerTest.java index 660430690..714466ec8 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VhostUserCustomizerTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VhostUserCustomizerTest.java @@ -18,30 +18,13 @@ package io.fd.honeycomb.v3po.translate.v3po.interfaces; import static io.fd.honeycomb.v3po.translate.v3po.test.ContextTestUtils.getMapping; import static io.fd.honeycomb.v3po.translate.v3po.test.ContextTestUtils.getMappingIid; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doReturn; -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 static org.mockito.MockitoAnnotations.initMocks; - import io.fd.honeycomb.v3po.translate.MappingContext; import io.fd.honeycomb.v3po.translate.ModificationCache; +import io.fd.honeycomb.v3po.translate.v3po.test.TestHelperUtils; 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.util.TranslateUtils; import io.fd.honeycomb.v3po.translate.write.WriteContext; import io.fd.honeycomb.v3po.translate.write.WriteFailedException; -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.mockito.ArgumentCaptor; @@ -54,14 +37,21 @@ 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.VhostUser; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.VhostUserBuilder; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.openvpp.jvpp.dto.CreateVhostUserIf; -import org.openvpp.jvpp.dto.CreateVhostUserIfReply; -import org.openvpp.jvpp.dto.DeleteVhostUserIf; -import org.openvpp.jvpp.dto.DeleteVhostUserIfReply; -import org.openvpp.jvpp.dto.ModifyVhostUserIf; -import org.openvpp.jvpp.dto.ModifyVhostUserIfReply; +import org.openvpp.jvpp.VppBaseCallException; +import org.openvpp.jvpp.VppInvocationException; +import org.openvpp.jvpp.dto.*; import org.openvpp.jvpp.future.FutureJVpp; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; +import java.util.concurrent.ExecutionException; + +import static org.junit.Assert.*; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.*; +import static org.mockito.MockitoAnnotations.initMocks; + public class VhostUserCustomizerTest { @Mock @@ -92,61 +82,79 @@ public class VhostUserCustomizerTest { customizer = new VhostUserCustomizer(api, namingContext); } - private void whenCreateVhostUserIfThen(final int retval) throws ExecutionException, InterruptedException { + private void whenCreateVhostUserIfThen() throws ExecutionException, InterruptedException, VppInvocationException { final CompletionStage<CreateVhostUserIfReply> replyCS = mock(CompletionStage.class); final CompletableFuture<CreateVhostUserIfReply> replyFuture = mock(CompletableFuture.class); when(replyCS.toCompletableFuture()).thenReturn(replyFuture); final CreateVhostUserIfReply reply = new CreateVhostUserIfReply(); - reply.retval = retval; when(replyFuture.get()).thenReturn(reply); when(api.createVhostUserIf(any(CreateVhostUserIf.class))).thenReturn(replyCS); } - private void whenCreateVhostUserIfThenSuccess() throws ExecutionException, InterruptedException { - whenCreateVhostUserIfThen(0); + /** + * Failure response send + */ + private void whenCreateVhostUserIfFailedThen(final int retval) throws ExecutionException, InterruptedException, VppInvocationException { + doReturn(TestHelperUtils.<CreateVhostUserIfReply>createFutureException(retval)).when(api).createVhostUserIf(any(CreateVhostUserIf.class)); + } + + private void whenCreateVhostUserIfThenSuccess() throws ExecutionException, InterruptedException, VppInvocationException { + whenCreateVhostUserIfThen(); } - private void whenVxlanAddDelTunnelThenFailure() throws ExecutionException, InterruptedException { - whenCreateVhostUserIfThen(-1); + private void whenVxlanAddDelTunnelThenFailure() throws ExecutionException, InterruptedException, VppInvocationException { + whenCreateVhostUserIfFailedThen(-1); } - private void whenModifyVhostUserIfThen(final int retval) throws ExecutionException, InterruptedException { + private void whenModifyVhostUserIfThen() throws ExecutionException, InterruptedException, VppInvocationException { final CompletionStage<ModifyVhostUserIfReply> replyCS = mock(CompletionStage.class); final CompletableFuture<ModifyVhostUserIfReply> replyFuture = mock(CompletableFuture.class); when(replyCS.toCompletableFuture()).thenReturn(replyFuture); final ModifyVhostUserIfReply reply = new ModifyVhostUserIfReply(); - reply.retval = retval; when(replyFuture.get()).thenReturn(reply); when(api.modifyVhostUserIf(any(ModifyVhostUserIf.class))).thenReturn(replyCS); } - private void whenModifyVhostUserIfThenSuccess() throws ExecutionException, InterruptedException { - whenModifyVhostUserIfThen(0); + /** + * Failure response send + */ + private void whenModifyVhostUserIfFailedThen(final int retval) throws ExecutionException, InterruptedException, VppInvocationException { + doReturn(TestHelperUtils.<ModifyVhostUserIfReply>createFutureException(retval)).when(api).modifyVhostUserIf(any(ModifyVhostUserIf.class)); + } + + private void whenModifyVhostUserIfThenSuccess() throws ExecutionException, InterruptedException, VppInvocationException { + whenModifyVhostUserIfThen(); } - private void whenModifyVhostUserIfThenFailure() throws ExecutionException, InterruptedException { - whenModifyVhostUserIfThen(-1); + private void whenModifyVhostUserIfThenFailure() throws ExecutionException, InterruptedException, VppInvocationException { + whenModifyVhostUserIfFailedThen(-1); } - private void whenDeleteVhostUserIfThen(final int retval) throws ExecutionException, InterruptedException { + private void whenDeleteVhostUserIfThen() throws ExecutionException, InterruptedException, VppInvocationException { final CompletionStage<DeleteVhostUserIfReply> replyCS = mock(CompletionStage.class); final CompletableFuture<DeleteVhostUserIfReply> replyFuture = mock(CompletableFuture.class); when(replyCS.toCompletableFuture()).thenReturn(replyFuture); final DeleteVhostUserIfReply reply = new DeleteVhostUserIfReply(); - reply.retval = retval; when(replyFuture.get()).thenReturn(reply); when(api.deleteVhostUserIf(any(DeleteVhostUserIf.class))).thenReturn(replyCS); } - private void whenDeleteVhostUserIfThenSuccess() throws ExecutionException, InterruptedException { - whenDeleteVhostUserIfThen(0); + /** + * Failure response send + */ + private void whenDeleteVhostUserIfFailedThen(final int retval) throws ExecutionException, InterruptedException, VppInvocationException { + doReturn(TestHelperUtils.<DeleteVhostUserIfReply>createFutureException(retval)).when(api).deleteVhostUserIf(any(DeleteVhostUserIf.class)); + } + + private void whenDeleteVhostUserIfThenSuccess() throws ExecutionException, InterruptedException, VppInvocationException { + whenDeleteVhostUserIfThen(); } - private void whenDeleteVhostUserIfThenFailure() throws ExecutionException, InterruptedException { - whenDeleteVhostUserIfThen(-1); + private void whenDeleteVhostUserIfThenFailure() throws ExecutionException, InterruptedException, VppInvocationException { + whenDeleteVhostUserIfFailedThen(-1); } - private CreateVhostUserIf verifyCreateVhostUserIfWasInvoked(final VhostUser vhostUser) { + private CreateVhostUserIf verifyCreateVhostUserIfWasInvoked(final VhostUser vhostUser) throws VppInvocationException { ArgumentCaptor<CreateVhostUserIf> argumentCaptor = ArgumentCaptor.forClass(CreateVhostUserIf.class); verify(api).createVhostUserIf(argumentCaptor.capture()); final CreateVhostUserIf actual = argumentCaptor.getValue(); @@ -160,7 +168,7 @@ public class VhostUserCustomizerTest { return actual; } - private ModifyVhostUserIf verifyModifyVhostUserIfWasInvoked(final VhostUser vhostUser, final int swIfIndex) { + private ModifyVhostUserIf verifyModifyVhostUserIfWasInvoked(final VhostUser vhostUser, final int swIfIndex) throws VppInvocationException { ArgumentCaptor<ModifyVhostUserIf> argumentCaptor = ArgumentCaptor.forClass(ModifyVhostUserIf.class); verify(api).modifyVhostUserIf(argumentCaptor.capture()); final ModifyVhostUserIf actual = argumentCaptor.getValue(); @@ -173,7 +181,7 @@ public class VhostUserCustomizerTest { return actual; } - private DeleteVhostUserIf verifyDeleteVhostUserIfWasInvoked(final int swIfIndex) { + private DeleteVhostUserIf verifyDeleteVhostUserIfWasInvoked(final int swIfIndex) throws VppInvocationException { ArgumentCaptor<DeleteVhostUserIf> argumentCaptor = ArgumentCaptor.forClass(DeleteVhostUserIf.class); verify(api).deleteVhostUserIf(argumentCaptor.capture()); final DeleteVhostUserIf actual = argumentCaptor.getValue(); @@ -208,7 +216,7 @@ public class VhostUserCustomizerTest { try { customizer.writeCurrentAttributes(ID, vhostUser, writeContext); } catch (WriteFailedException.CreateFailedException e) { - assertEquals(VppApiInvocationException.class, e.getCause().getClass()); + assertTrue(e.getCause() instanceof VppBaseCallException); verifyCreateVhostUserIfWasInvoked(vhostUser); verifyZeroInteractions(mappingContext); return; @@ -239,7 +247,7 @@ public class VhostUserCustomizerTest { try { customizer.updateCurrentAttributes(ID, vhostUserBefore, vhostUserAfter, writeContext); } catch (WriteFailedException.UpdateFailedException e) { - assertEquals(VppApiInvocationException.class, e.getCause().getClass()); + assertTrue(e.getCause() instanceof VppBaseCallException); verifyModifyVhostUserIfWasInvoked(vhostUserAfter, IFACE_ID); return; } @@ -268,7 +276,7 @@ public class VhostUserCustomizerTest { try { customizer.deleteCurrentAttributes(ID, vhostUser, writeContext); } catch (WriteFailedException.DeleteFailedException e) { - assertEquals(VppApiInvocationException.class, e.getCause().getClass()); + assertTrue(e.getCause() instanceof VppBaseCallException); verifyDeleteVhostUserIfWasInvoked(IFACE_ID); // Delete from context not invoked if delete from VPP failed verify(mappingContext, times(0)).delete(eq(getMappingIid(IFACE_NAME, "test-instance"))); diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanCustomizerTest.java index 312ec9c01..e716dc6dc 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanCustomizerTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanCustomizerTest.java @@ -16,32 +16,14 @@ package io.fd.honeycomb.v3po.translate.v3po.interfaces; -import static io.fd.honeycomb.v3po.translate.v3po.test.ContextTestUtils.getMapping; -import static io.fd.honeycomb.v3po.translate.v3po.test.ContextTestUtils.getMappingIid; -import static java.util.Collections.singletonList; -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.Matchers.eq; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.mockito.MockitoAnnotations.initMocks; - import com.google.common.base.Optional; import com.google.common.net.InetAddresses; import io.fd.honeycomb.v3po.translate.MappingContext; import io.fd.honeycomb.v3po.translate.ModificationCache; +import io.fd.honeycomb.v3po.translate.v3po.test.TestHelperUtils; import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext; -import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException; import io.fd.honeycomb.v3po.translate.write.WriteContext; import io.fd.honeycomb.v3po.translate.write.WriteFailedException; -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.mockito.ArgumentCaptor; @@ -59,10 +41,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.Vxlan; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.VxlanBuilder; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.VppBaseCallException; +import org.openvpp.jvpp.VppInvocationException; import org.openvpp.jvpp.dto.VxlanAddDelTunnel; import org.openvpp.jvpp.dto.VxlanAddDelTunnelReply; import org.openvpp.jvpp.future.FutureJVpp; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; +import java.util.concurrent.ExecutionException; + +import static io.fd.honeycomb.v3po.translate.v3po.test.ContextTestUtils.getMapping; +import static io.fd.honeycomb.v3po.translate.v3po.test.ContextTestUtils.getMappingIid; +import static java.util.Collections.singletonList; +import static org.junit.Assert.*; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.*; +import static org.mockito.MockitoAnnotations.initMocks; + public class VxlanCustomizerTest { private static final byte ADD_VXLAN = 1; @@ -97,25 +94,31 @@ public class VxlanCustomizerTest { .augmentation(VppInterfaceAugmentation.class).child(Vxlan.class); } - private void whenVxlanAddDelTunnelThen(final int retval) throws ExecutionException, InterruptedException { + private void whenVxlanAddDelTunnelThen() throws ExecutionException, InterruptedException, VppInvocationException { final CompletionStage<VxlanAddDelTunnelReply> replyCS = mock(CompletionStage.class); final CompletableFuture<VxlanAddDelTunnelReply> replyFuture = mock(CompletableFuture.class); when(replyCS.toCompletableFuture()).thenReturn(replyFuture); final VxlanAddDelTunnelReply reply = new VxlanAddDelTunnelReply(); - reply.retval = retval; when(replyFuture.get()).thenReturn(reply); when(api.vxlanAddDelTunnel(any(VxlanAddDelTunnel.class))).thenReturn(replyCS); } - private void whenVxlanAddDelTunnelThenSuccess() throws ExecutionException, InterruptedException { - whenVxlanAddDelTunnelThen(0); + /** + * Failure response send + */ + private void whenVxlanAddDelTunnelFailedThen(final int retval) throws ExecutionException, InterruptedException, VppInvocationException { + doReturn(TestHelperUtils.<VxlanAddDelTunnelReply>createFutureException(retval)).when(api).vxlanAddDelTunnel(any(VxlanAddDelTunnel.class)); + } + + private void whenVxlanAddDelTunnelThenSuccess() throws ExecutionException, InterruptedException, VppInvocationException { + whenVxlanAddDelTunnelThen(); } - private void whenVxlanAddDelTunnelThenFailure() throws ExecutionException, InterruptedException { - whenVxlanAddDelTunnelThen(-1); + private void whenVxlanAddDelTunnelThenFailure() throws ExecutionException, InterruptedException, VppInvocationException { + whenVxlanAddDelTunnelFailedThen(-1); } - private VxlanAddDelTunnel verifyVxlanAddDelTunnelWasInvoked(final Vxlan vxlan) { + private VxlanAddDelTunnel verifyVxlanAddDelTunnelWasInvoked(final Vxlan vxlan) throws VppInvocationException { ArgumentCaptor<VxlanAddDelTunnel> argumentCaptor = ArgumentCaptor.forClass(VxlanAddDelTunnel.class); verify(api).vxlanAddDelTunnel(argumentCaptor.capture()); final VxlanAddDelTunnel actual = argumentCaptor.getValue(); @@ -127,12 +130,12 @@ public class VxlanCustomizerTest { assertEquals(vxlan.getVni().getValue().intValue(), actual.vni); return actual; } - private void verifyVxlanAddWasInvoked(final Vxlan vxlan) { + private void verifyVxlanAddWasInvoked(final Vxlan vxlan) throws VppInvocationException { final VxlanAddDelTunnel actual = verifyVxlanAddDelTunnelWasInvoked(vxlan); assertEquals(ADD_VXLAN, actual.isAdd); } - private void verifyVxlanDeleteWasInvoked(final Vxlan vxlan) { + private void verifyVxlanDeleteWasInvoked(final Vxlan vxlan) throws VppInvocationException { final VxlanAddDelTunnel actual = verifyVxlanAddDelTunnelWasInvoked(vxlan); assertEquals(DEL_VXLAN, actual.isAdd); } @@ -191,7 +194,7 @@ public class VxlanCustomizerTest { try { customizer.writeCurrentAttributes(id, vxlan, writeContext); } catch (WriteFailedException.CreateFailedException e) { - assertEquals(VppApiInvocationException.class, e.getCause().getClass()); + assertTrue(e.getCause() instanceof VppBaseCallException); verifyVxlanAddWasInvoked(vxlan); // Mapping not stored due to failure verify(mappingContext, times(0)).put(eq(getMappingIid(ifaceName, "test-instance")), eq(getMapping(ifaceName, 0).get())); @@ -233,7 +236,7 @@ public class VxlanCustomizerTest { try { customizer.deleteCurrentAttributes(id, vxlan, writeContext); } catch (WriteFailedException.DeleteFailedException e) { - assertEquals(VppApiInvocationException.class, e.getCause().getClass()); + assertTrue(e.getCause() instanceof VppBaseCallException); verifyVxlanDeleteWasInvoked(vxlan); verify(mappingContext, times(0)).delete(eq(getMappingIid(ifaceName, "test-instance"))); return; diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanGpeCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanGpeCustomizerTest.java index 44e8559b4..77404aa45 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanGpeCustomizerTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanGpeCustomizerTest.java @@ -19,9 +19,7 @@ package io.fd.honeycomb.v3po.translate.v3po.interfaces; import static io.fd.honeycomb.v3po.translate.v3po.test.ContextTestUtils.getMapping; import static io.fd.honeycomb.v3po.translate.v3po.test.ContextTestUtils.getMappingIid; import static java.util.Collections.singletonList; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; +import static org.junit.Assert.*; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.doReturn; @@ -35,8 +33,8 @@ import com.google.common.base.Optional; import com.google.common.net.InetAddresses; import io.fd.honeycomb.v3po.translate.MappingContext; import io.fd.honeycomb.v3po.translate.ModificationCache; +import io.fd.honeycomb.v3po.translate.v3po.test.TestHelperUtils; import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext; -import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException; import io.fd.honeycomb.v3po.translate.write.WriteContext; import io.fd.honeycomb.v3po.translate.write.WriteFailedException; import java.util.concurrent.CompletableFuture; @@ -60,6 +58,10 @@ 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.VxlanGpe; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.VxlanGpeBuilder; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.VppBaseCallException; +import org.openvpp.jvpp.VppInvocationException; +import org.openvpp.jvpp.dto.VxlanAddDelTunnel; +import org.openvpp.jvpp.dto.VxlanAddDelTunnelReply; import org.openvpp.jvpp.dto.VxlanGpeAddDelTunnel; import org.openvpp.jvpp.dto.VxlanGpeAddDelTunnelReply; import org.openvpp.jvpp.future.FutureJVpp; @@ -98,25 +100,31 @@ public class VxlanGpeCustomizerTest { .augmentation(VppInterfaceAugmentation.class).child(VxlanGpe.class); } - private void whenVxlanGpeAddDelTunnelThen(final int retval) throws ExecutionException, InterruptedException { + private void whenVxlanGpeAddDelTunnelThen() throws ExecutionException, InterruptedException, VppBaseCallException { final CompletionStage<VxlanGpeAddDelTunnelReply> replyCS = mock(CompletionStage.class); final CompletableFuture<VxlanGpeAddDelTunnelReply> replyFuture = mock(CompletableFuture.class); when(replyCS.toCompletableFuture()).thenReturn(replyFuture); final VxlanGpeAddDelTunnelReply reply = new VxlanGpeAddDelTunnelReply(); - reply.retval = retval; when(replyFuture.get()).thenReturn(reply); when(api.vxlanGpeAddDelTunnel(any(VxlanGpeAddDelTunnel.class))).thenReturn(replyCS); } - private void whenVxlanGpeAddDelTunnelThenSuccess() throws ExecutionException, InterruptedException { - whenVxlanGpeAddDelTunnelThen(0); + private void whenVxlanGpeAddDelTunnelThenSuccess() throws ExecutionException, InterruptedException, VppBaseCallException { + whenVxlanGpeAddDelTunnelThen(); } - private void whenVxlanGpeAddDelTunnelThenFailure() throws ExecutionException, InterruptedException { - whenVxlanGpeAddDelTunnelThen(-1); + private void whenVxlanGpeAddDelTunnelThenFailure() throws ExecutionException, InterruptedException, VppBaseCallException { + whenVxlanGpeAddDelTunnelFailedThen(-1); } - private VxlanGpeAddDelTunnel verifyVxlanGpeAddDelTunnelWasInvoked(final VxlanGpe vxlanGpe) { + /** + * Failure response send + */ + private void whenVxlanGpeAddDelTunnelFailedThen(final int retval) throws ExecutionException, InterruptedException, VppBaseCallException { + doReturn(TestHelperUtils.<VxlanAddDelTunnelReply>createFutureException(retval)).when(api).vxlanGpeAddDelTunnel(any(VxlanGpeAddDelTunnel.class)); + } + + private VxlanGpeAddDelTunnel verifyVxlanGpeAddDelTunnelWasInvoked(final VxlanGpe vxlanGpe) throws VppBaseCallException{ ArgumentCaptor<VxlanGpeAddDelTunnel> argumentCaptor = ArgumentCaptor.forClass(VxlanGpeAddDelTunnel.class); verify(api).vxlanGpeAddDelTunnel(argumentCaptor.capture()); final VxlanGpeAddDelTunnel actual = argumentCaptor.getValue(); @@ -129,12 +137,12 @@ public class VxlanGpeCustomizerTest { assertEquals(vxlanGpe.getDecapVrfId().intValue(), actual.decapVrfId); return actual; } - private void verifyVxlanGpeAddWasInvoked(final VxlanGpe vxlanGpe) { + private void verifyVxlanGpeAddWasInvoked(final VxlanGpe vxlanGpe) throws VppBaseCallException{ final VxlanGpeAddDelTunnel actual = verifyVxlanGpeAddDelTunnelWasInvoked(vxlanGpe); assertEquals(ADD_VXLAN_GPE, actual.isAdd); } - private void verifyVxlanGpeDeleteWasInvoked(final VxlanGpe vxlanGpe) { + private void verifyVxlanGpeDeleteWasInvoked(final VxlanGpe vxlanGpe) throws VppBaseCallException{ final VxlanGpeAddDelTunnel actual = verifyVxlanGpeAddDelTunnelWasInvoked(vxlanGpe); assertEquals(DEL_VXLAN_GPE, actual.isAdd); } @@ -195,7 +203,7 @@ public class VxlanGpeCustomizerTest { try { customizer.writeCurrentAttributes(id, vxlanGpe, writeContext); } catch (WriteFailedException.CreateFailedException e) { - assertEquals(VppApiInvocationException.class, e.getCause().getClass()); + assertTrue(e.getCause() instanceof VppBaseCallException); verifyVxlanGpeAddWasInvoked(vxlanGpe); // Mapping not stored due to failure verify(mappingContext, times(0)).put(eq(getMappingIid(ifaceName, "test-instance")), eq(getMapping(ifaceName, 0).get())); @@ -237,7 +245,7 @@ public class VxlanGpeCustomizerTest { try { customizer.deleteCurrentAttributes(id, vxlanGpe, writeContext); } catch (WriteFailedException.DeleteFailedException e) { - assertEquals(VppApiInvocationException.class, e.getCause().getClass()); + assertTrue(e.getCause() instanceof VppBaseCallException); verifyVxlanGpeDeleteWasInvoked(vxlanGpe); verify(mappingContext, times(0)).delete(eq(getMappingIid(ifaceName, "test-instance"))); return; 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 a43bb136f..1e5dad7d1 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 @@ -49,6 +49,7 @@ 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.InterfaceKey; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; +import org.openvpp.jvpp.VppInvocationException; import org.openvpp.jvpp.dto.SwInterfaceDetails; import org.openvpp.jvpp.dto.SwInterfaceDump; @@ -93,7 +94,7 @@ public class InterfaceCustomizerTest extends } private void verifyBridgeDomainDumpUpdateWasInvoked(final int nameFilterValid, final String ifaceName, - final int dumpIfcsInvocationCount) { + final int dumpIfcsInvocationCount) throws VppInvocationException { // TODO adding equals methods for jvpp DTOs would make ArgumentCaptor usage obsolete ArgumentCaptor<SwInterfaceDump> argumentCaptor = ArgumentCaptor.forClass(SwInterfaceDump.class); verify(api, times(dumpIfcsInvocationCount)).swInterfaceDump(argumentCaptor.capture()); diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/L2CustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/L2CustomizerTest.java index bb935bca0..6ddeaebda 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/L2CustomizerTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/L2CustomizerTest.java @@ -51,6 +51,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.l2.base.attributes.interconnection.BridgeBasedBuilder; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; +import org.openvpp.jvpp.VppInvocationException; import org.openvpp.jvpp.dto.BridgeDomainDetails; import org.openvpp.jvpp.dto.BridgeDomainDetailsReplyDump; import org.openvpp.jvpp.dto.BridgeDomainDump; @@ -93,7 +94,7 @@ public class L2CustomizerTest extends ChildReaderCustomizerTest<L2, L2Builder> { private void whenBridgeDomainSwIfDumpThenReturn(final List<BridgeDomainSwIfDetails> bdSwIfList, final List<BridgeDomainDetails> bridgeDomainDetailses) - throws ExecutionException, InterruptedException { + throws ExecutionException, InterruptedException, VppInvocationException { final BridgeDomainDetailsReplyDump reply = new BridgeDomainDetailsReplyDump(); reply.bridgeDomainSwIfDetails = bdSwIfList; reply.bridgeDomainDetails = bridgeDomainDetailses; diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanCustomizerTest.java index 71e1952bf..64c14ebff 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanCustomizerTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanCustomizerTest.java @@ -43,6 +43,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.interfaces.state._interface.Vxlan; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.VxlanBuilder; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.VppInvocationException; import org.openvpp.jvpp.dto.SwInterfaceDetails; import org.openvpp.jvpp.dto.VxlanTunnelDetails; import org.openvpp.jvpp.dto.VxlanTunnelDetailsReplyDump; @@ -72,7 +73,7 @@ public class VxlanCustomizerTest extends ChildReaderCustomizerTest<Vxlan, VxlanB } @Override - protected void setUpAfter() throws UnknownHostException { + protected void setUpAfter() throws UnknownHostException, VppInvocationException { final CompletableFuture<VxlanTunnelDetailsReplyDump> vxlanTunnelDetailsReplyDumpCompletionStage = new CompletableFuture<>(); diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanGpeCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanGpeCustomizerTest.java index e795bcbf8..7c96a03e9 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanGpeCustomizerTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanGpeCustomizerTest.java @@ -43,6 +43,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.interfaces.state._interface.VxlanGpe; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.VxlanGpeBuilder; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.VppBaseCallException; import org.openvpp.jvpp.dto.SwInterfaceDetails; import org.openvpp.jvpp.dto.VxlanGpeTunnelDetails; import org.openvpp.jvpp.dto.VxlanGpeTunnelDetailsReplyDump; @@ -72,7 +73,7 @@ public class VxlanGpeCustomizerTest extends ChildReaderCustomizerTest<VxlanGpe, } @Override - protected void setUpAfter() throws UnknownHostException { + protected void setUpAfter() throws UnknownHostException, VppBaseCallException { final CompletableFuture<VxlanGpeTunnelDetailsReplyDump> vxlanGpeTunnelDetailsReplyDumpCompletionStage = new CompletableFuture<>(); diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/InterfaceTestUtils.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/InterfaceTestUtils.java index b7486253f..c88cefa9e 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/InterfaceTestUtils.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/InterfaceTestUtils.java @@ -16,18 +16,20 @@ package io.fd.honeycomb.v3po.translate.v3po.test; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; +import org.openvpp.jvpp.VppBaseCallException; +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 java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; import java.util.concurrent.ExecutionException; -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 static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; public final class InterfaceTestUtils { private InterfaceTestUtils() { @@ -35,7 +37,7 @@ public final class InterfaceTestUtils { } public static void whenSwInterfaceDumpThenReturn(final FutureJVpp api, final List<SwInterfaceDetails> interfaceList) - throws ExecutionException, InterruptedException { + throws ExecutionException, InterruptedException, VppBaseCallException { final CompletionStage<SwInterfaceDetailsReplyDump> replyCS = mock(CompletionStage.class); final CompletableFuture<SwInterfaceDetailsReplyDump> replyFuture = mock(CompletableFuture.class); when(replyCS.toCompletableFuture()).thenReturn(replyFuture); diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/TestHelperUtils.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/TestHelperUtils.java new file mode 100644 index 000000000..598b62f05 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/TestHelperUtils.java @@ -0,0 +1,35 @@ +/* + * 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 org.openvpp.jvpp.VppCallbackException; +import org.openvpp.jvpp.dto.JVppReply; + +import java.util.concurrent.CompletableFuture; + +public class TestHelperUtils { + /** + * Static helper method for creation of Exception failure state in CompletableFuture object + * @param retval result of the operation in exception + * @return CompletableFuture with VppCallbackException as a cause + */ + public static CompletableFuture<? extends JVppReply> createFutureException(final int retval) { + final CompletableFuture<? extends JVppReply> replyFuture = new CompletableFuture<>(); + replyFuture.completeExceptionally(new VppCallbackException("test-call", 1, retval)); + return replyFuture; + } +} 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 a7cf231da..8f3c12083 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 @@ -17,25 +17,13 @@ package io.fd.honeycomb.v3po.translate.v3po.vpp; import static io.fd.honeycomb.v3po.translate.v3po.test.ContextTestUtils.getMapping; import static io.fd.honeycomb.v3po.translate.v3po.test.ContextTestUtils.getMappingIid; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doReturn; -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 com.google.common.base.Optional; import io.fd.honeycomb.v3po.translate.MappingContext; import io.fd.honeycomb.v3po.translate.ModificationCache; +import io.fd.honeycomb.v3po.translate.v3po.test.TestHelperUtils; import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext; import io.fd.honeycomb.v3po.translate.write.WriteContext; import io.fd.honeycomb.v3po.translate.write.WriteFailedException; -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.mockito.ArgumentCaptor; @@ -43,10 +31,21 @@ import org.mockito.Mock; import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.Mappings; 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.openvpp.jvpp.VppInvocationException; import org.openvpp.jvpp.dto.BridgeDomainAddDel; import org.openvpp.jvpp.dto.BridgeDomainAddDelReply; import org.openvpp.jvpp.future.FutureJVpp; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; +import java.util.concurrent.ExecutionException; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.*; +import static org.mockito.MockitoAnnotations.initMocks; + public class BridgeDomainCustomizerTest { private static final byte ADD_OR_UPDATE_BD = (byte) 1; @@ -94,7 +93,7 @@ public class BridgeDomainCustomizerTest { .build(); } - private void verifyBridgeDomainAddOrUpdateWasInvoked(final BridgeDomain bd, final int bdId) { + private void verifyBridgeDomainAddOrUpdateWasInvoked(final BridgeDomain bd, final int bdId) throws VppInvocationException { final byte arpTerm = BridgeDomainTestUtils.booleanToByte(bd.isArpTermination()); final byte flood = BridgeDomainTestUtils.booleanToByte(bd.isFlood()); final byte forward = BridgeDomainTestUtils.booleanToByte(bd.isForward()); @@ -114,7 +113,7 @@ public class BridgeDomainCustomizerTest { assertEquals(bdId, actual.bdId); } - private void verifyBridgeDomainDeleteWasInvoked(final int bdId) { + private void verifyBridgeDomainDeleteWasInvoked(final int bdId) throws VppInvocationException { ArgumentCaptor<BridgeDomainAddDel> argumentCaptor = ArgumentCaptor.forClass(BridgeDomainAddDel.class); verify(api).bridgeDomainAddDel(argumentCaptor.capture()); final BridgeDomainAddDel actual = argumentCaptor.getValue(); @@ -127,22 +126,25 @@ public class BridgeDomainCustomizerTest { assertEquals(ZERO, actual.isAdd); } - private void whenBridgeDomainAddDelThen(final int retval) throws ExecutionException, InterruptedException { + private void whenBridgeDomainAddDelThen() throws ExecutionException, InterruptedException, VppInvocationException { 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 whenBridgeDomainAddDelThenSuccess() throws ExecutionException, InterruptedException { - whenBridgeDomainAddDelThen(0); + private void whenBridgeDomainAddDelFailedThen(final int retval) throws ExecutionException, InterruptedException, VppInvocationException { + doReturn(TestHelperUtils.<BridgeDomainAddDelReply>createFutureException(retval)).when(api).bridgeDomainAddDel(any(BridgeDomainAddDel.class)); + } + + private void whenBridgeDomainAddDelThenSuccess() throws ExecutionException, InterruptedException, VppInvocationException { + whenBridgeDomainAddDelThen(); } - private void whenBridgeDomainAddDelThenFailure() throws ExecutionException, InterruptedException { - whenBridgeDomainAddDelThen(-1); + private void whenBridgeDomainAddDelThenFailure() throws ExecutionException, InterruptedException, VppInvocationException { + whenBridgeDomainAddDelFailedThen(-1); } @Test 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 d54401237..2bb37d108 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 @@ -18,14 +18,6 @@ package io.fd.honeycomb.v3po.translate.v3po.vpp; import static io.fd.honeycomb.v3po.translate.v3po.test.ContextTestUtils.getMapping; import static io.fd.honeycomb.v3po.translate.v3po.test.ContextTestUtils.getMappingIid; -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyZeroInteractions; -import static org.mockito.Mockito.when; - import com.google.common.base.Optional; import com.google.common.collect.Iterators; import com.google.common.collect.Lists; @@ -36,11 +28,6 @@ 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.mockito.ArgumentCaptor; @@ -55,10 +42,21 @@ 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.jvpp.VppInvocationException; import org.openvpp.jvpp.dto.BridgeDomainAddDel; import org.openvpp.jvpp.dto.BridgeDomainAddDelReply; import org.openvpp.jvpp.future.FutureJVpp; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; +import java.util.concurrent.ExecutionException; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.*; + public class VppTest { private static final byte ADD_OR_UPDATE_BD = 1; @@ -102,17 +100,16 @@ public class VppTest { .build(); } - private void whenBridgeDomainAddDelThen(final int retval) throws ExecutionException, InterruptedException { + private void whenBridgeDomainAddDelThen(final int retval) throws ExecutionException, VppInvocationException, 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) { + private void verifyBridgeDomainAddDel(final BridgeDomain bd, final int bdId) throws VppInvocationException { final byte arpTerm = BridgeDomainTestUtils.booleanToByte(bd.isArpTermination()); final byte flood = BridgeDomainTestUtils.booleanToByte(bd.isFlood()); final byte forward = BridgeDomainTestUtils.booleanToByte(bd.isForward()); @@ -132,7 +129,7 @@ public class VppTest { assertEquals(bdId, actual.bdId); } - private void verifyBridgeDomainDeleteWasInvoked(final int bdId) { + private void verifyBridgeDomainDeleteWasInvoked(final int bdId) throws VppInvocationException { ArgumentCaptor<BridgeDomainAddDel> argumentCaptor = ArgumentCaptor.forClass(BridgeDomainAddDel.class); verify(api).bridgeDomainAddDel(argumentCaptor.capture()); final BridgeDomainAddDel actual = argumentCaptor.getValue(); 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 index 0ddef2248..ed79838b4 100644 --- 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 @@ -55,7 +55,6 @@ public class VersionCustomizerTest extends ChildReaderCustomizerTest<Version, Ve public void testReadCurrentAttributes() throws Exception { final CompletableFuture<ShowVersionReply> replyFuture = new CompletableFuture<>(); final ShowVersionReply reply = new ShowVersionReply(); - reply.retval = 0; reply.version = new byte[]{}; reply.program = new byte[]{}; reply.buildDate = new byte[]{}; 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 79146fad3..6b91a2416 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 @@ -65,6 +65,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.bridge.domain.L2FibKey; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.VppInvocationException; import org.openvpp.jvpp.dto.BridgeDomainDetails; import org.openvpp.jvpp.dto.BridgeDomainDetailsReplyDump; import org.openvpp.jvpp.dto.BridgeDomainDump; @@ -112,10 +113,9 @@ public class VppStateTest { .build(); } - private void whenShowVersionThenReturn(int retval, Version version) throws ExecutionException, InterruptedException { + private void whenShowVersionThenReturn(int retval, Version version) throws ExecutionException, InterruptedException, VppInvocationException { final CompletableFuture<ShowVersionReply> replyFuture = new CompletableFuture<>(); final ShowVersionReply reply = new ShowVersionReply(); - reply.retval = 0; // success reply.buildDate = version.getBuildDate().getBytes(); reply.program = version.getName().getBytes(); reply.version = version.getBranch().getBytes(); @@ -125,7 +125,7 @@ public class VppStateTest { when(api.showVersion(any(ShowVersion.class))).thenReturn(replyFuture); } - private void whenL2FibTableDumpThenReturn(final List<L2FibTableEntry> entryList) throws ExecutionException, InterruptedException { + private void whenL2FibTableDumpThenReturn(final List<L2FibTableEntry> entryList) throws ExecutionException, InterruptedException, VppInvocationException { final CompletionStage<L2FibTableEntryReplyDump> replyCS = mock(CompletionStage.class); final CompletableFuture<L2FibTableEntryReplyDump> replyFuture = mock(CompletableFuture.class); when(replyCS.toCompletableFuture()).thenReturn(replyFuture); @@ -135,7 +135,7 @@ public class VppStateTest { when(api.l2FibTableDump(any(L2FibTableDump.class))).thenReturn(replyCS); } - private void whenBridgeDomainDumpThenReturn(final List<BridgeDomainDetails> bdList) throws ExecutionException, InterruptedException { + private void whenBridgeDomainDumpThenReturn(final List<BridgeDomainDetails> bdList) throws ExecutionException, InterruptedException, VppInvocationException { final CompletionStage<BridgeDomainDetailsReplyDump> replyCS = mock(CompletionStage.class); final CompletableFuture<BridgeDomainDetailsReplyDump> replyFuture = mock(CompletableFuture.class); when(replyCS.toCompletableFuture()).thenReturn(replyFuture); diff --git a/v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/FutureJVppCustomizer.java b/v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/FutureJVppCustomizer.java index 61495b71c..3f4f1f5ce 100644 --- a/v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/FutureJVppCustomizer.java +++ b/v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/FutureJVppCustomizer.java @@ -18,9 +18,10 @@ package io.fd.honeycomb.v3po.translate.v3po.util; import com.google.common.annotations.Beta; import com.google.common.base.Preconditions; -import javax.annotation.Nonnull; import org.openvpp.jvpp.future.FutureJVpp; +import javax.annotation.Nonnull; + /** * Abstract utility to hold the vppApi reference. */ diff --git a/v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/TranslateUtils.java b/v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/TranslateUtils.java index 3c1ef7f28..9c3fea615 100644 --- a/v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/TranslateUtils.java +++ b/v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/TranslateUtils.java @@ -16,21 +16,23 @@ package io.fd.honeycomb.v3po.translate.v3po.util; -import static com.google.common.base.Preconditions.checkArgument; - import com.google.common.base.Splitter; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.VppBaseCallException; +import org.openvpp.jvpp.dto.JVppReply; + +import javax.annotation.Nonnegative; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.function.BiConsumer; -import javax.annotation.Nonnegative; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.openvpp.jvpp.dto.JVppReply; + +import static com.google.common.base.Preconditions.checkArgument; public final class TranslateUtils { @@ -38,23 +40,26 @@ public final class TranslateUtils { private TranslateUtils() {} - public static <REP extends JVppReply<?>> REP getReply(Future<REP> future) { + public static <REP extends JVppReply<?>> REP getReply(Future<REP> future) throws VppBaseCallException { 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); + // Execution exception could generally contains any exception + // when using exceptions instead of return codes just rethrow it for processing on corresponding place + if (e instanceof ExecutionException && ( e.getCause() instanceof VppBaseCallException)) { + throw (VppBaseCallException) (e.getCause()); + } + throw new IllegalStateException(e); } } public static <REP extends JVppReply<?>> REP getReply(@Nonnull Future<REP> future, @Nonnull final InstanceIdentifier<?> replyType, @Nonnegative final int timeoutInSeconds) - throws ReadTimeoutException { + throws ReadTimeoutException, VppBaseCallException { try { checkArgument(timeoutInSeconds > 0, "Timeout cannot be < 0"); return future.get(timeoutInSeconds, TimeUnit.SECONDS); @@ -62,9 +67,11 @@ public final class TranslateUtils { 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); + // Execution exception could generally contains any exception + // when using exceptions instead of return codes just rethrow it for processing on corresponding place + if ( e.getCause() instanceof VppBaseCallException) + throw (VppBaseCallException)(e.getCause()); + throw new IllegalStateException(e); } catch (TimeoutException e) { throw new ReadTimeoutException(replyType, e); } diff --git a/v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/VppApiInvocationException.java b/v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/VppApiInvocationException.java deleted file mode 100644 index 4c50304c6..000000000 --- a/v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/VppApiInvocationException.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.v3po.translate.v3po.util; - -import com.google.common.annotations.Beta; -import com.google.common.base.Preconditions; -import javax.annotation.Nonnull; - -/** - * Thrown when Vpp jAPI method invocation failed. - */ -@Beta -public class VppApiInvocationException extends Exception { - private final String methodName; - private final int ctxId; - private final int errorCode; - - /** - * Constructs an VppApiInvocationFailedException with the specified api method name and error code. - * - * @param methodName method name that failed to invoke - * @param ctxId api request context identifier - * @param errorCode negative error code value associated with this failure - * @throws NullPointerException if apiMethodName is null - * @throws IllegalArgumentException if errorCode is nonnegative - */ - public VppApiInvocationException(@Nonnull final String methodName, final int ctxId, final int errorCode) { - super(String.format("vppApi.%s failed with error code: %d (ctxId=%d) ", methodName, errorCode, ctxId)); - this.methodName = Preconditions.checkNotNull(methodName, "apiMethodName is null!"); - this.ctxId = ctxId; - Preconditions.checkArgument(errorCode < 0); - this.errorCode = errorCode; - } - - /** - * Returns method name that failed to invoke. - * - * @return method name - */ - public String getMethodName() { - return methodName; - } - - /** - * Returns api request context identifier. - * - * @return value of context identifier - */ - public int getCtxId() { - return ctxId; - } - - /** - * Returns the error code associated with this failure. - * - * @return a negative integer error code - */ - public int getErrorCode() { - return errorCode; - } -} diff --git a/v3po/vpp-translate-utils/src/test/java/io/fd/honeycomb/v3po/translate/v3po/util/VppApiInvocationExceptionTest.java b/v3po/vpp-translate-utils/src/test/java/io/fd/honeycomb/v3po/translate/v3po/util/VppApiInvocationExceptionTest.java deleted file mode 100644 index 184beceef..000000000 --- a/v3po/vpp-translate-utils/src/test/java/io/fd/honeycomb/v3po/translate/v3po/util/VppApiInvocationExceptionTest.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.v3po.translate.v3po.util; - -import java.util.Random; -import org.junit.Assert; -import org.junit.Test; - -public class VppApiInvocationExceptionTest { - - @Test - public void testInstantiation() { - final String apiMethodName = "methodName"; - final int ctxId = 1; - final int code = -1; - VppApiInvocationException e = new VppApiInvocationException(apiMethodName, ctxId, code); - Assert.assertEquals(apiMethodName, e.getMethodName()); - Assert.assertEquals(ctxId, e.getCtxId()); - Assert.assertEquals(code, e.getErrorCode()); - Assert.assertTrue(e.getMessage().contains(apiMethodName)); - Assert.assertTrue(e.getMessage().contains(String.valueOf(code))); - Assert.assertTrue(e.getMessage().contains(String.valueOf(ctxId))); - } - - @Test(expected = IllegalArgumentException.class) - public void testInstantiationFailed() { - final int code = new Random().nextInt(Integer.MAX_VALUE); - VppApiInvocationException e = new VppApiInvocationException("apiMethodName", 1, code); - } -} |