Check expected interface type in sub-Interface nodes
authorMaros Marsalek <[email protected]>
Fri, 13 May 2016 08:04:11 +0000 (10:04 +0200)
committerMaros Marsalek <[email protected]>
Tue, 17 May 2016 15:13:08 +0000 (17:13 +0200)
+ Pass full WriteContext to the write customizers, making
them more flexible

Change-Id: I75c55aed02f9300eee20eabb4a3e84e294ed1e0f
Signed-off-by: Maros Marsalek <[email protected]>
22 files changed:
v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/write/CompositeChildWriter.java
v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/write/CompositeListWriter.java
v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/write/CompositeRootWriter.java
v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/write/RootWriterCustomizer.java
v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/NoopWriterCustomizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/EthernetCustomizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/InterfaceCustomizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/L2Customizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/RoutingCustomizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/TapCustomizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VhostUserCustomizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanCustomizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4Customizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv6Customizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainCustomizer.java
v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/InterfaceTypeTestUtils.java [new file with mode: 0644]
v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/TapCustomizerTest.java
v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VhostUserCustomizerTest.java
v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanCustomizerTest.java
v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainCustomizerTest.java
v3po/vpp-translate-utils/pom.xml
v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/AbstractInterfaceTypeCustomizer.java [new file with mode: 0644]

index 54a09f2..6e0841d 100644 (file)
@@ -66,20 +66,20 @@ public class CompositeChildWriter<D extends DataObject> extends AbstractComposit
     @Override
     protected void writeCurrentAttributes(@Nonnull final InstanceIdentifier<D> id, @Nonnull final D data,
                                           @Nonnull final WriteContext ctx) throws WriteFailedException {
-        customizer.writeCurrentAttributes(id, data, ctx.getContext());
+        customizer.writeCurrentAttributes(id, data, ctx);
     }
 
     @Override
     protected void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<D> id, @Nonnull final D dataBefore,
                                            @Nonnull WriteContext ctx) throws WriteFailedException {
-        customizer.deleteCurrentAttributes(id, dataBefore, ctx.getContext());
+        customizer.deleteCurrentAttributes(id, dataBefore, ctx);
     }
 
     @Override
     protected void updateCurrentAttributes(@Nonnull final InstanceIdentifier<D> id, @Nonnull final D dataBefore,
                                            @Nonnull final D dataAfter, @Nonnull WriteContext ctx)
         throws WriteFailedException {
-        customizer.updateCurrentAttributes(id, dataBefore, dataAfter, ctx.getContext());
+        customizer.updateCurrentAttributes(id, dataBefore, dataAfter, ctx);
     }
 
     @Override
index 967edb6..1ac39b8 100644 (file)
@@ -40,14 +40,9 @@ public class CompositeListWriter<D extends DataObject & Identifiable<K>, K exten
     AbstractCompositeWriter<D>
     implements ChildWriter<D> {
 
-    public static final Function<DataObject, Object> INDEX_FUNCTION = new Function<DataObject, Object>() {
-        @Override
-        public Object apply(final DataObject input) {
-            return input instanceof Identifiable<?>
-                ? ((Identifiable<?>) input).getKey()
-                : input;
-        }
-    };
+    public static final Function<DataObject, Object> INDEX_FUNCTION = input -> input instanceof Identifiable<?>
+        ? ((Identifiable<?>) input).getKey()
+        : input;
 
 
     private final ListWriterCustomizer<D, K> customizer;
@@ -83,20 +78,20 @@ public class CompositeListWriter<D extends DataObject & Identifiable<K>, K exten
     @Override
     protected void writeCurrentAttributes(@Nonnull final InstanceIdentifier<D> id, @Nonnull final D data,
                                           @Nonnull final WriteContext ctx) throws WriteFailedException {
-        customizer.writeCurrentAttributes(id, data, ctx.getContext());
+        customizer.writeCurrentAttributes(id, data, ctx);
     }
 
     @Override
     protected void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<D> id, @Nonnull final D dataBefore,
                                            @Nonnull final WriteContext ctx) throws WriteFailedException {
-        customizer.deleteCurrentAttributes(id, dataBefore, ctx.getContext());
+        customizer.deleteCurrentAttributes(id, dataBefore, ctx);
     }
 
     @Override
     protected void updateCurrentAttributes(@Nonnull final InstanceIdentifier<D> id, @Nonnull final D dataBefore,
                                            @Nonnull final D dataAfter, @Nonnull final WriteContext ctx)
         throws WriteFailedException {
-        customizer.updateCurrentAttributes(id, dataBefore, dataAfter, ctx.getContext());
+        customizer.updateCurrentAttributes(id, dataBefore, dataAfter, ctx);
     }
 
     @Override
index 5e4ff86..6f46359 100644 (file)
@@ -65,13 +65,13 @@ public class CompositeRootWriter<D extends DataObject> extends AbstractComposite
                                           @Nonnull final WriteContext ctx) throws WriteFailedException {
         // TODO wrap all customizer invocations in try catch, and wrap runtime exceptions in ReadFailed
         // TODO same for readers
-        customizer.writeCurrentAttributes(id, data, ctx.getContext());
+        customizer.writeCurrentAttributes(id, data, ctx);
     }
 
     @Override
     protected void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<D> id, @Nonnull final D dataBefore,
                                            @Nonnull final WriteContext ctx) throws WriteFailedException {
-        customizer.deleteCurrentAttributes(id, dataBefore, ctx.getContext());
+        customizer.deleteCurrentAttributes(id, dataBefore, ctx);
     }
 
     @Override
@@ -79,6 +79,6 @@ public class CompositeRootWriter<D extends DataObject> extends AbstractComposite
                                            @Nonnull final D dataBefore,
                                            @Nonnull final D dataAfter,
                                            @Nonnull final WriteContext ctx) throws WriteFailedException {
-        customizer.updateCurrentAttributes(id, dataBefore, dataAfter, ctx.getContext());
+        customizer.updateCurrentAttributes(id, dataBefore, dataAfter, ctx);
     }
 }
index 2cdcff3..0ada8e9 100644 (file)
@@ -17,7 +17,7 @@
 package io.fd.honeycomb.v3po.translate.spi.write;
 
 import com.google.common.annotations.Beta;
-import io.fd.honeycomb.v3po.translate.Context;
+import io.fd.honeycomb.v3po.translate.write.WriteContext;
 import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
 import javax.annotation.Nonnull;
 import org.opendaylight.yangtools.yang.binding.DataObject;
@@ -42,7 +42,7 @@ public interface RootWriterCustomizer<D extends DataObject> {
      */
     void writeCurrentAttributes(@Nonnull final InstanceIdentifier<D> id,
                                 @Nonnull final D dataAfter,
-                                @Nonnull final Context writeContext) throws WriteFailedException;
+                                @Nonnull final WriteContext writeContext) throws WriteFailedException;
 
     /**
      * Handle update operation. U from CRUD.
@@ -57,7 +57,7 @@ public interface RootWriterCustomizer<D extends DataObject> {
     void updateCurrentAttributes(@Nonnull final InstanceIdentifier<D> id,
                                  @Nonnull final D dataBefore,
                                  @Nonnull final D dataAfter,
-                                 @Nonnull final Context writeContext) throws WriteFailedException;
+                                 @Nonnull final WriteContext writeContext) throws WriteFailedException;
 
     /**
      * Handle delete operation. D from CRUD.
@@ -70,5 +70,5 @@ public interface RootWriterCustomizer<D extends DataObject> {
      */
     void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<D> id,
                                  @Nonnull final D dataBefore,
-                                 @Nonnull final Context writeContext) throws WriteFailedException;
+                                 @Nonnull final WriteContext writeContext) throws WriteFailedException;
 }
index 2663258..9f9c9f5 100644 (file)
@@ -17,7 +17,7 @@
 package io.fd.honeycomb.v3po.translate.util.write;
 
 import io.fd.honeycomb.v3po.translate.spi.write.RootWriterCustomizer;
-import io.fd.honeycomb.v3po.translate.Context;
+import io.fd.honeycomb.v3po.translate.write.WriteContext;
 import javax.annotation.Nonnull;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
@@ -30,20 +30,20 @@ public class NoopWriterCustomizer<D extends DataObject> implements RootWriterCus
 
     @Override
     public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<D> id, @Nonnull final D dataAfter,
-                                       @Nonnull final Context ctx) {
+                                       @Nonnull final WriteContext ctx) {
 
     }
 
     @Override
     public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<D> id, @Nonnull final D dataBefore,
                                         @Nonnull final D dataAfter,
-                                        @Nonnull final Context ctx) {
+                                        @Nonnull final WriteContext ctx) {
 
     }
 
     @Override
     public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<D> id, @Nonnull final D dataBefore,
-                                        @Nonnull final Context ctx) {
+                                        @Nonnull final WriteContext ctx) {
 
     }
 }
index cdcea45..e8d6e39 100644 (file)
 package io.fd.honeycomb.v3po.translate.v3po.interfaces;
 
 import com.google.common.base.Optional;
-import io.fd.honeycomb.v3po.translate.Context;
-import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer;
-import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.AbstractInterfaceTypeCustomizer;
+import io.fd.honeycomb.v3po.translate.write.WriteContext;
 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.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.Ethernet;
 import org.opendaylight.yangtools.yang.binding.DataObject;
@@ -29,7 +30,7 @@ import org.openvpp.jvpp.future.FutureJVpp;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class EthernetCustomizer extends FutureJVppCustomizer implements ChildWriterCustomizer<Ethernet> {
+public class EthernetCustomizer extends AbstractInterfaceTypeCustomizer<Ethernet> {
 
     private static final Logger LOG = LoggerFactory.getLogger(EthernetCustomizer.class);
 
@@ -37,6 +38,11 @@ public class EthernetCustomizer extends FutureJVppCustomizer implements ChildWri
         super(vppApi);
     }
 
+    @Override
+    protected Class<? extends InterfaceType> getExpectedInterfaceType() {
+        return EthernetCsmacd.class;
+    }
+
     @Nonnull
     @Override
     public Optional<Ethernet> extract(@Nonnull final InstanceIdentifier<Ethernet> currentId,
@@ -45,27 +51,24 @@ public class EthernetCustomizer extends FutureJVppCustomizer implements ChildWri
     }
 
     @Override
-    public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Ethernet> id,
-                                       @Nonnull final Ethernet dataAfter, @Nonnull final Context writeContext) {
+    protected final void writeInterface(@Nonnull final InstanceIdentifier<Ethernet> id,
+                                       @Nonnull final Ethernet dataAfter, @Nonnull final WriteContext writeContext) {
         // TODO
         LOG.warn("Unsupported, ignoring configuration {}", dataAfter);
-
     }
 
     @Override
     public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<Ethernet> id,
                                         @Nonnull final Ethernet dataBefore, @Nonnull final Ethernet dataAfter,
-                                        @Nonnull final Context writeContext) {
+                                        @Nonnull final WriteContext writeContext) {
         // TODO
         LOG.warn("Unsupported, ignoring configuration {}", dataAfter);
-
     }
 
     @Override
     public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Ethernet> id,
-                                        @Nonnull final Ethernet dataBefore, @Nonnull final Context writeContext) {
+                                        @Nonnull final Ethernet dataBefore, @Nonnull final WriteContext writeContext) {
         // TODO
         LOG.warn("Unsupported, ignoring configuration delete {}", id);
-
     }
 }
index b6d8748..e6ed62a 100644 (file)
 
 package io.fd.honeycomb.v3po.translate.v3po.interfaces;
 
-import io.fd.honeycomb.v3po.translate.Context;
 import io.fd.honeycomb.v3po.translate.spi.write.ListWriterCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException;
 import io.fd.honeycomb.v3po.translate.v3po.utils.V3poUtils;
+import io.fd.honeycomb.v3po.translate.write.WriteContext;
 import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
 import java.util.List;
 import java.util.concurrent.CompletionStage;
@@ -53,7 +53,7 @@ public class InterfaceCustomizer extends FutureJVppCustomizer implements ListWri
     @Override
     public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Interface> id,
                                        @Nonnull final Interface dataAfter,
-                                       @Nonnull final Context writeContext)
+                                       @Nonnull final WriteContext writeContext)
         throws WriteFailedException {
 
         try {
@@ -68,7 +68,7 @@ public class InterfaceCustomizer extends FutureJVppCustomizer implements ListWri
     public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<Interface> id,
                                         @Nonnull final Interface dataBefore,
                                         @Nonnull final Interface dataAfter,
-                                        @Nonnull final Context writeContext)
+                                        @Nonnull final WriteContext writeContext)
         throws WriteFailedException.UpdateFailedException {
 
         try {
@@ -82,7 +82,7 @@ public class InterfaceCustomizer extends FutureJVppCustomizer implements ListWri
     @Override
     public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Interface> id,
                                         @Nonnull final Interface dataBefore,
-                                        @Nonnull final Context writeContext) {
+                                        @Nonnull final WriteContext writeContext) {
 
         // TODO Handle deletes
     }
index ee731e7..fc43cdb 100644 (file)
@@ -19,12 +19,12 @@ package io.fd.honeycomb.v3po.translate.v3po.interfaces;
 import static com.google.common.base.Preconditions.checkArgument;
 
 import com.google.common.base.Optional;
-import io.fd.honeycomb.v3po.translate.Context;
 import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException;
 import io.fd.honeycomb.v3po.translate.v3po.utils.V3poUtils;
+import io.fd.honeycomb.v3po.translate.write.WriteContext;
 import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
 import java.util.concurrent.CompletionStage;
 import javax.annotation.Nonnull;
@@ -65,7 +65,7 @@ public class L2Customizer extends FutureJVppCustomizer implements ChildWriterCus
 
     @Override
     public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<L2> id, @Nonnull final L2 dataAfter,
-                                       @Nonnull final Context writeContext)
+                                       @Nonnull final WriteContext writeContext)
         throws WriteFailedException {
 
         final String ifcName = id.firstKeyOf(Interface.class).getName();
@@ -80,7 +80,7 @@ public class L2Customizer extends FutureJVppCustomizer implements ChildWriterCus
 
     @Override
     public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<L2> id, @Nonnull final L2 dataBefore,
-                                        @Nonnull final L2 dataAfter, @Nonnull final Context writeContext)
+                                        @Nonnull final L2 dataAfter, @Nonnull final WriteContext writeContext)
         throws WriteFailedException {
 
         final String ifcName = id.firstKeyOf(Interface.class).getName();
@@ -96,7 +96,7 @@ public class L2Customizer extends FutureJVppCustomizer implements ChildWriterCus
 
     @Override
     public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<L2> id, @Nonnull final L2 dataBefore,
-                                        @Nonnull final Context writeContext) {
+                                        @Nonnull final WriteContext writeContext) {
         // TODO implement delete (if possible)
     }
 
index b15050c..4d17ba0 100644 (file)
 package io.fd.honeycomb.v3po.translate.v3po.interfaces;
 
 import com.google.common.base.Optional;
-import io.fd.honeycomb.v3po.translate.Context;
 import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException;
 import io.fd.honeycomb.v3po.translate.v3po.utils.V3poUtils;
+import io.fd.honeycomb.v3po.translate.write.WriteContext;
 import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
 import java.util.concurrent.CompletionStage;
 import javax.annotation.Nonnull;
@@ -56,7 +56,7 @@ public class RoutingCustomizer extends FutureJVppCustomizer implements ChildWrit
 
     @Override
     public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Routing> id,
-                                       @Nonnull final Routing dataAfter, @Nonnull final Context writeContext)
+                                       @Nonnull final Routing dataAfter, @Nonnull final WriteContext writeContext)
         throws WriteFailedException.CreateFailedException {
 
         try {
@@ -70,7 +70,7 @@ public class RoutingCustomizer extends FutureJVppCustomizer implements ChildWrit
     @Override
     public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<Routing> id,
                                         @Nonnull final Routing dataBefore, @Nonnull final Routing dataAfter,
-                                        @Nonnull final Context writeContext)
+                                        @Nonnull final WriteContext writeContext)
         throws WriteFailedException.UpdateFailedException {
 
         try {
@@ -84,7 +84,7 @@ public class RoutingCustomizer extends FutureJVppCustomizer implements ChildWrit
 
     @Override
     public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Routing> id,
-                                        @Nonnull final Routing dataBefore, @Nonnull final Context writeContext) {
+                                        @Nonnull final Routing dataBefore, @Nonnull final WriteContext writeContext) {
         // TODO implement delete
     }
 
index f05238d..72679fe 100644 (file)
 package io.fd.honeycomb.v3po.translate.v3po.interfaces;
 
 import com.google.common.base.Optional;
-import io.fd.honeycomb.v3po.translate.Context;
-import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer;
-import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
+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.utils.V3poUtils;
+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;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentation;
@@ -42,7 +42,7 @@ import org.openvpp.jvpp.future.FutureJVpp;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class TapCustomizer extends FutureJVppCustomizer implements ChildWriterCustomizer<Tap> {
+public class TapCustomizer extends AbstractInterfaceTypeCustomizer<Tap> {
 
     private static final Logger LOG = LoggerFactory.getLogger(TapCustomizer.class);
     private final NamingContext interfaceContext;
@@ -60,8 +60,13 @@ public class TapCustomizer extends FutureJVppCustomizer implements ChildWriterCu
     }
 
     @Override
-    public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Tap> id, @Nonnull final Tap dataAfter,
-                                       @Nonnull final Context writeContext)
+    protected Class<? extends InterfaceType> getExpectedInterfaceType() {
+        return org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.Tap.class;
+    }
+
+    @Override
+    protected final void writeInterface(@Nonnull final InstanceIdentifier<Tap> id, @Nonnull final Tap dataAfter,
+                                       @Nonnull final WriteContext writeContext)
         throws WriteFailedException.CreateFailedException {
         try {
             createTap(id.firstKeyOf(Interface.class).getName(), dataAfter);
@@ -73,7 +78,7 @@ public class TapCustomizer extends FutureJVppCustomizer implements ChildWriterCu
 
     @Override
     public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<Tap> id, @Nonnull final Tap dataBefore,
-                                        @Nonnull final Tap dataAfter, @Nonnull final Context writeContext)
+                                        @Nonnull final Tap dataAfter, @Nonnull final WriteContext writeContext)
         throws WriteFailedException.UpdateFailedException {
         final String ifcName = id.firstKeyOf(Interface.class).getName();
 
@@ -94,7 +99,7 @@ public class TapCustomizer extends FutureJVppCustomizer implements ChildWriterCu
 
     @Override
     public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Tap> id, @Nonnull final Tap dataBefore,
-                                        @Nonnull final Context writeContext)
+                                        @Nonnull final WriteContext writeContext)
         throws WriteFailedException.DeleteFailedException {
         final String ifcName = id.firstKeyOf(Interface.class).getName();
 
index 4066976..ebefff3 100644 (file)
@@ -18,15 +18,15 @@ package io.fd.honeycomb.v3po.translate.v3po.interfaces;
 
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
-import io.fd.honeycomb.v3po.translate.Context;
-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.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.utils.V3poUtils;
+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;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentation;
@@ -46,7 +46,7 @@ import org.slf4j.LoggerFactory;
 /**
  * Writer Customizer responsible for passing vhost user interface CRD operations to VPP
  */
-public class VhostUserCustomizer extends FutureJVppCustomizer implements ChildWriterCustomizer<VhostUser> {
+public class VhostUserCustomizer extends AbstractInterfaceTypeCustomizer<VhostUser> {
 
     private static final Logger LOG = LoggerFactory.getLogger(VhostUserCustomizer.class);
     private final NamingContext interfaceContext;
@@ -64,12 +64,17 @@ public class VhostUserCustomizer extends FutureJVppCustomizer implements ChildWr
     }
 
     @Override
-    public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<VhostUser> id,
-                                       @Nonnull final VhostUser dataAfter, @Nonnull final Context writeContext)
+    protected Class<? extends InterfaceType> getExpectedInterfaceType() {
+        return org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VhostUser.class;
+    }
+
+    @Override
+    protected final void writeInterface(@Nonnull final InstanceIdentifier<VhostUser> id,
+                                       @Nonnull final VhostUser dataAfter, @Nonnull final WriteContext writeContext)
             throws WriteFailedException.CreateFailedException {
         try {
             createVhostUserIf(id.firstKeyOf(Interface.class).getName(), dataAfter);
-        } catch (VppApiInvocationException e) {
+        } catch (VppApiInvocationException | IllegalInterfaceTypeException e) {
             throw new WriteFailedException.CreateFailedException(id, dataAfter, e);
         }
     }
@@ -105,12 +110,13 @@ public class VhostUserCustomizer extends FutureJVppCustomizer implements ChildWr
     @Override
     public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<VhostUser> id,
                                         @Nonnull final VhostUser dataBefore, @Nonnull final VhostUser dataAfter,
-                                        @Nonnull final Context writeContext)
+                                        @Nonnull final WriteContext writeContext)
             throws WriteFailedException.UpdateFailedException {
         if (dataBefore.equals(dataAfter)) {
             LOG.debug("dataBefore equals dataAfter, update will not be performed");
             return;
         }
+
         try {
             modifyVhostUserIf(id.firstKeyOf(Interface.class).getName(), dataAfter);
         } catch (VppApiInvocationException e) {
@@ -146,7 +152,7 @@ public class VhostUserCustomizer extends FutureJVppCustomizer implements ChildWr
 
     @Override
     public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<VhostUser> id,
-                                        @Nonnull final VhostUser dataBefore, @Nonnull final Context writeContext)
+                                        @Nonnull final VhostUser dataBefore, @Nonnull final WriteContext writeContext)
             throws WriteFailedException.DeleteFailedException {
         try {
             deleteVhostUserIf(id.firstKeyOf(Interface.class).getName(), dataBefore);
index 6244a20..9d11b59 100644 (file)
@@ -20,19 +20,20 @@ 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.Context;
-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.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.utils.V3poUtils;
+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;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanTunnel;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.Vxlan;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
@@ -42,7 +43,8 @@ import org.openvpp.jvpp.future.FutureJVpp;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class VxlanCustomizer extends FutureJVppCustomizer implements ChildWriterCustomizer<Vxlan> {
+// TODO extract common code from all Interface type specific writer customizers into a superclass
+public class VxlanCustomizer extends AbstractInterfaceTypeCustomizer<Vxlan> {
 
     private static final Logger LOG = LoggerFactory.getLogger(VxlanCustomizer.class);
     private final NamingContext interfaceContext;
@@ -60,12 +62,17 @@ public class VxlanCustomizer extends FutureJVppCustomizer implements ChildWriter
     }
 
     @Override
-    public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Vxlan> id, @Nonnull final Vxlan dataAfter,
-                                       @Nonnull final Context writeContext)
+    protected Class<? extends InterfaceType> getExpectedInterfaceType() {
+        return VxlanTunnel.class;
+    }
+
+    @Override
+    protected final void writeInterface(@Nonnull final InstanceIdentifier<Vxlan> id, @Nonnull final Vxlan dataAfter,
+                                       @Nonnull final WriteContext writeContext)
             throws WriteFailedException.CreateFailedException {
         try {
             createVxlanTunnel(id.firstKeyOf(Interface.class).getName(), dataAfter);
-        } catch (VppApiInvocationException e) {
+        } catch (VppApiInvocationException | IllegalInterfaceTypeException e) {
             LOG.warn("Write of Vxlan failed", e);
             throw new WriteFailedException.CreateFailedException(id, dataAfter, e);
         }
@@ -73,9 +80,8 @@ public class VxlanCustomizer extends FutureJVppCustomizer implements ChildWriter
 
     @Override
     public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<Vxlan> id, @Nonnull final Vxlan dataBefore,
-                                        @Nonnull final Vxlan dataAfter, @Nonnull final Context writeContext)
+                                        @Nonnull final Vxlan dataAfter, @Nonnull final WriteContext writeContext)
             throws WriteFailedException.UpdateFailedException {
-
         if (dataBefore.equals(dataAfter)) {
             LOG.debug("dataBefore equals dataAfter, update will not be performed");
             return;
@@ -86,7 +92,7 @@ public class VxlanCustomizer extends FutureJVppCustomizer implements ChildWriter
 
     @Override
     public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Vxlan> id, @Nonnull final Vxlan dataBefore,
-                                        @Nonnull final Context writeContext)
+                                        @Nonnull final WriteContext writeContext)
             throws WriteFailedException.DeleteFailedException {
         try {
             deleteVxlanTunnel(id.firstKeyOf(Interface.class).getName(), dataBefore);
@@ -97,9 +103,6 @@ public class VxlanCustomizer extends FutureJVppCustomizer implements ChildWriter
     }
 
     private void createVxlanTunnel(final String swIfName, final Vxlan vxlan) throws VppApiInvocationException {
-        // TODO check that the type of interface is vxlan-tunnel (it is expressed in YANG, but not validated on DataTree level)
-        // DO the same for other interface aguments/types
-
         final byte isIpv6 = (byte) (isIpv6(vxlan) ? 1 : 0);
         final InetAddress srcAddress = InetAddresses.forString(getAddressString(vxlan.getSrc()));
         final InetAddress dstAddress = InetAddresses.forString(getAddressString(vxlan.getDst()));
@@ -137,9 +140,7 @@ public class VxlanCustomizer extends FutureJVppCustomizer implements ChildWriter
     }
 
     private String getAddressString(final IpAddress addr) {
-        return addr.getIpv4Address() == null
-                ? addr.getIpv6Address().getValue()
-                : addr.getIpv4Address().getValue();
+        return addr.getIpv4Address() == null ? addr.getIpv6Address().getValue() : addr.getIpv4Address().getValue();
     }
 
     private void deleteVxlanTunnel(final String swIfName, final Vxlan vxlan) throws VppApiInvocationException {
index de2015c..a54f6c5 100644 (file)
@@ -20,12 +20,12 @@ 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.Context;
 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.utils.V3poUtils;
+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;
@@ -64,7 +64,7 @@ public class Ipv4Customizer extends FutureJVppCustomizer implements ChildWriterC
 
     @Override
     public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Ipv4> id,
-                                       @Nonnull final Ipv4 dataAfter, @Nonnull final Context writeContext)
+                                       @Nonnull final Ipv4 dataAfter, @Nonnull final WriteContext writeContext)
         throws WriteFailedException {
         try {
             final String ifcName = id.firstKeyOf(Interface.class).getName();
@@ -78,7 +78,7 @@ public class Ipv4Customizer extends FutureJVppCustomizer implements ChildWriterC
     @Override
     public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<Ipv4> id,
                                         @Nonnull final Ipv4 dataBefore, @Nonnull final Ipv4 dataAfter,
-                                        @Nonnull final Context writeContext)
+                                        @Nonnull final WriteContext writeContext)
         throws WriteFailedException {
         final String ifcName = id.firstKeyOf(Interface.class).getName();
 
@@ -93,7 +93,7 @@ public class Ipv4Customizer extends FutureJVppCustomizer implements ChildWriterC
 
     @Override
     public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Ipv4> id,
-                                        @Nonnull final Ipv4 dataBefore, @Nonnull final Context writeContext) {
+                                        @Nonnull final Ipv4 dataBefore, @Nonnull final WriteContext writeContext) {
         // TODO implement delete
     }
 
index e3ad392..0fe8643 100644 (file)
@@ -17,9 +17,9 @@
 package io.fd.honeycomb.v3po.translate.v3po.interfaces.ip;
 
 import com.google.common.base.Optional;
-import io.fd.honeycomb.v3po.translate.Context;
 import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
+import io.fd.honeycomb.v3po.translate.write.WriteContext;
 import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface1;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv6;
@@ -46,7 +46,7 @@ public class Ipv6Customizer extends FutureJVppCustomizer implements ChildWriterC
 
     @Override
     public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Ipv6> id,
-                                       @Nonnull final Ipv6 dataAfter, @Nonnull final Context writeContext) {
+                                       @Nonnull final Ipv6 dataAfter, @Nonnull final WriteContext writeContext) {
         // TODO
         LOG.warn("Unsupported, ignoring configuration {}", dataAfter);
     }
@@ -54,13 +54,13 @@ public class Ipv6Customizer extends FutureJVppCustomizer implements ChildWriterC
     @Override
     public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<Ipv6> id,
                                         @Nonnull final Ipv6 dataBefore, @Nonnull final Ipv6 dataAfter,
-                                        @Nonnull final Context writeContext) {
+                                        @Nonnull final WriteContext writeContext) {
         LOG.warn("Unsupported, ignoring configuration {}", dataAfter);
     }
 
     @Override
     public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Ipv6> id,
-                                        @Nonnull final Ipv6 dataBefore, @Nonnull final Context writeContext) {
+                                        @Nonnull final Ipv6 dataBefore, @Nonnull final WriteContext writeContext) {
         LOG.warn("Unsupported, ignoring configuration delete {}", id);
         // TODO
     }
index a3e2f73..672a05f 100644 (file)
@@ -20,12 +20,12 @@ import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
 
 import com.google.common.base.Preconditions;
-import io.fd.honeycomb.v3po.translate.Context;
 import io.fd.honeycomb.v3po.translate.spi.write.ListWriterCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException;
 import io.fd.honeycomb.v3po.translate.v3po.utils.V3poUtils;
+import io.fd.honeycomb.v3po.translate.write.WriteContext;
 import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
 import java.util.List;
 import javax.annotation.Nonnull;
@@ -88,7 +88,7 @@ public class BridgeDomainCustomizer
     @Override
     public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<BridgeDomain> id,
                                        @Nonnull final BridgeDomain dataBefore,
-                                       @Nonnull final Context ctx) throws WriteFailedException.CreateFailedException {
+                                       @Nonnull final WriteContext ctx) throws WriteFailedException.CreateFailedException {
         LOG.debug("writeCurrentAttributes: id={}, current={}, ctx={}", id, dataBefore, ctx);
         final String bdName = dataBefore.getName();
 
@@ -116,7 +116,7 @@ public class BridgeDomainCustomizer
     @Override
     public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<BridgeDomain> id,
                                         @Nonnull final BridgeDomain dataBefore,
-                                        @Nonnull final Context ctx) throws WriteFailedException.DeleteFailedException {
+                                        @Nonnull final WriteContext ctx) throws WriteFailedException.DeleteFailedException {
         LOG.debug("deleteCurrentAttributes: id={}, dataBefore={}, ctx={}", id, dataBefore, ctx);
 
         final String bdName = id.firstKeyOf(BridgeDomain.class).getName();
@@ -138,7 +138,7 @@ public class BridgeDomainCustomizer
     @Override
     public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<BridgeDomain> id,
                                         @Nonnull final BridgeDomain dataBefore, @Nonnull final BridgeDomain dataAfter,
-                                        @Nonnull final Context ctx) throws WriteFailedException.UpdateFailedException {
+                                        @Nonnull final WriteContext ctx) throws WriteFailedException.UpdateFailedException {
         LOG.debug("updateCurrentAttributes: id={}, dataBefore={}, dataAfter={}, ctx={}", id, dataBefore, dataAfter,
                 ctx);
 
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/InterfaceTypeTestUtils.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/InterfaceTypeTestUtils.java
new file mode 100644 (file)
index 0000000..ff96131
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.v3po.translate.v3po.interfaces;
+
+import static org.mockito.Mockito.doReturn;
+
+import com.google.common.base.Optional;
+import io.fd.honeycomb.v3po.translate.Context;
+import io.fd.honeycomb.v3po.translate.write.WriteContext;
+import org.mockito.Matchers;
+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.InterfaceBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+final class InterfaceTypeTestUtils {
+
+    private InterfaceTypeTestUtils() {}
+
+    static void setupWriteContext(final WriteContext writeContext, final Class<? extends InterfaceType> ifcType) {
+        doReturn(new Context()).when(writeContext).getContext();
+        doReturn(Optional.of(new InterfaceBuilder()
+            .setType(ifcType)
+            .build())).when(writeContext).readAfter(Matchers.any(InstanceIdentifier.class));
+    }
+}
index 668eed4..8ae04f0 100644 (file)
@@ -24,8 +24,8 @@ import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
-import io.fd.honeycomb.v3po.translate.Context;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
+import io.fd.honeycomb.v3po.translate.write.WriteContext;
 import java.util.concurrent.CompletableFuture;
 import org.junit.Before;
 import org.junit.Test;
@@ -53,12 +53,17 @@ public class TapCustomizerTest {
 
     @Mock
     private FutureJVpp vppApi;
+    @Mock
+    private WriteContext writeContext;
+
     private NamingContext ctx;
     private TapCustomizer tapCustomizer;
 
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
+        InterfaceTypeTestUtils.setupWriteContext(writeContext,
+            org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.Tap.class);
         ctx = new NamingContext("ifcintest");
         tapCustomizer = new TapCustomizer(vppApi, ctx);
     }
@@ -80,8 +85,8 @@ public class TapCustomizerTest {
             }
         }).when(vppApi).tapConnect(any(TapConnect.class));
 
-        tapCustomizer.writeCurrentAttributes(getTapId("tap"), getTapData("tap", "ff:ff:ff:ff:ff:ff"), new Context());
-        tapCustomizer.writeCurrentAttributes(getTapId("tap2"), getTapData("tap2", "ff:ff:ff:ff:ff:ff"), new Context());
+        tapCustomizer.writeCurrentAttributes(getTapId("tap"), getTapData("tap", "ff:ff:ff:ff:ff:ff"), writeContext);
+        tapCustomizer.writeCurrentAttributes(getTapId("tap2"), getTapData("tap2", "ff:ff:ff:ff:ff:ff"), writeContext);
 
         verify(vppApi, times(2)).tapConnect(any(TapConnect.class));
         assertTrue(ctx.containsIndex("tap"));
@@ -103,8 +108,8 @@ public class TapCustomizerTest {
         replyModif.complete(tmodif);
         doReturn(replyModif).when(vppApi).tapModify(any(TapModify.class));
 
-        tapCustomizer.writeCurrentAttributes(getTapId("tap"), getTapData("tap", "ff:ff:ff:ff:ff:ff"), new Context());
-        tapCustomizer.updateCurrentAttributes(getTapId("tap"), getTapData("tap", "ff:ff:ff:ff:ff:ff"), getTapData("tap", "ff:ff:ff:ff:ff:f1"), new Context());
+        tapCustomizer.writeCurrentAttributes(getTapId("tap"), getTapData("tap", "ff:ff:ff:ff:ff:ff"), writeContext);
+        tapCustomizer.updateCurrentAttributes(getTapId("tap"), getTapData("tap", "ff:ff:ff:ff:ff:ff"), getTapData("tap", "ff:ff:ff:ff:ff:f1"), writeContext);
 
         verify(vppApi).tapConnect(any(TapConnect.class));
         verify(vppApi).tapModify(any(TapModify.class));
@@ -126,8 +131,8 @@ public class TapCustomizerTest {
         replyDelete.complete(tmodif);
         doReturn(replyDelete).when(vppApi).tapDelete(any(TapDelete.class));
 
-        tapCustomizer.writeCurrentAttributes(getTapId("tap"), getTapData("tap", "ff:ff:ff:ff:ff:ff"), new Context());
-        tapCustomizer.deleteCurrentAttributes(getTapId("tap"), getTapData("tap", "ff:ff:ff:ff:ff:ff"), new Context());
+        tapCustomizer.writeCurrentAttributes(getTapId("tap"), getTapData("tap", "ff:ff:ff:ff:ff:ff"), writeContext);
+        tapCustomizer.deleteCurrentAttributes(getTapId("tap"), getTapData("tap", "ff:ff:ff:ff:ff:ff"), writeContext);
 
         verify(vppApi).tapConnect(any(TapConnect.class));
         verify(vppApi).tapDelete(any(TapDelete.class));
index 076df67..15b2a75 100644 (file)
@@ -29,10 +29,10 @@ import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 import static org.mockito.MockitoAnnotations.initMocks;
 
-import io.fd.honeycomb.v3po.translate.Context;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException;
 import io.fd.honeycomb.v3po.translate.v3po.utils.V3poUtils;
+import io.fd.honeycomb.v3po.translate.write.WriteContext;
 import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.CompletionStage;
@@ -62,7 +62,7 @@ public class VhostUserCustomizerTest {
     @Mock
     private FutureJVpp api;
     @Mock
-    private Context ctx;
+    private WriteContext writeContext;
 
     private NamingContext namingContext;
     private VhostUserCustomizer customizer;
@@ -75,6 +75,8 @@ public class VhostUserCustomizerTest {
     @Before
     public void setUp() throws Exception {
         initMocks(this);
+        InterfaceTypeTestUtils.setupWriteContext(writeContext,
+            org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VhostUser.class);
         namingContext = new NamingContext("generatedInterfaceName");
         // TODO create base class for tests using vppApi
         customizer = new VhostUserCustomizer(api, namingContext);
@@ -182,7 +184,7 @@ public class VhostUserCustomizerTest {
 
         whenCreateVhostUserIfThenSuccess();
 
-        customizer.writeCurrentAttributes(ID, vhostUser, ctx);
+        customizer.writeCurrentAttributes(ID, vhostUser, writeContext);
         verifyCreateVhostUserIfWasInvoked(vhostUser);
         assertTrue(namingContext.containsIndex(IFACE_NAME));
     }
@@ -194,7 +196,7 @@ public class VhostUserCustomizerTest {
         whenVxlanAddDelTunnelThenFailure();
 
         try {
-            customizer.writeCurrentAttributes(ID, vhostUser, ctx);
+            customizer.writeCurrentAttributes(ID, vhostUser, writeContext);
         } catch (WriteFailedException.CreateFailedException e) {
             assertEquals(VppApiInvocationException.class, e.getCause().getClass());
             verifyCreateVhostUserIfWasInvoked(vhostUser);
@@ -212,7 +214,7 @@ public class VhostUserCustomizerTest {
 
         whenModifyVhostUserIfThenSuccess();
 
-        customizer.updateCurrentAttributes(ID, vhostUserBefore, vhostUserAfter, ctx);
+        customizer.updateCurrentAttributes(ID, vhostUserBefore, vhostUserAfter, writeContext);
         verifyModifyVhostUserIfWasInvoked(vhostUserAfter, IFACE_ID);
     }
 
@@ -220,7 +222,7 @@ public class VhostUserCustomizerTest {
     public void testUpdateCurrentAttributesNoUpdate() throws Exception {
         final VhostUser vhostUserBefore = generateVhostUser(VhostUserRole.Server, "socketName");
         final VhostUser vhostUserAfter = generateVhostUser(VhostUserRole.Server, "socketName");
-        customizer.updateCurrentAttributes(ID, vhostUserBefore, vhostUserAfter, ctx);
+        customizer.updateCurrentAttributes(ID, vhostUserBefore, vhostUserAfter, writeContext);
         verify(api, never()).modifyVhostUserIf(any(ModifyVhostUserIf.class));
     }
 
@@ -233,7 +235,7 @@ public class VhostUserCustomizerTest {
         whenModifyVhostUserIfThenFailure();
 
         try {
-            customizer.updateCurrentAttributes(ID, vhostUserBefore, vhostUserAfter, ctx);
+            customizer.updateCurrentAttributes(ID, vhostUserBefore, vhostUserAfter, writeContext);
         } catch (WriteFailedException.UpdateFailedException e) {
             assertEquals(VppApiInvocationException.class, e.getCause().getClass());
             verifyModifyVhostUserIfWasInvoked(vhostUserAfter, IFACE_ID);
@@ -249,7 +251,7 @@ public class VhostUserCustomizerTest {
 
         whenDeleteVhostUserIfThenSuccess();
 
-        customizer.deleteCurrentAttributes(ID, vhostUser, ctx);
+        customizer.deleteCurrentAttributes(ID, vhostUser, writeContext);
         verifyDeleteVhostUserIfWasInvoked(IFACE_ID);
         assertFalse(namingContext.containsIndex(IFACE_NAME));
     }
@@ -262,7 +264,7 @@ public class VhostUserCustomizerTest {
         whenDeleteVhostUserIfThenFailure();
 
         try {
-            customizer.deleteCurrentAttributes(ID, vhostUser, ctx);
+            customizer.deleteCurrentAttributes(ID, vhostUser, writeContext);
         } catch (WriteFailedException.DeleteFailedException e) {
             assertEquals(VppApiInvocationException.class, e.getCause().getClass());
             verifyDeleteVhostUserIfWasInvoked(IFACE_ID);
index a599d75..af7b4df 100644 (file)
@@ -29,9 +29,9 @@ import static org.mockito.Mockito.when;
 import static org.mockito.MockitoAnnotations.initMocks;
 
 import com.google.common.net.InetAddresses;
-import io.fd.honeycomb.v3po.translate.Context;
 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;
@@ -62,7 +62,7 @@ public class VxlanCustomizerTest {
     @Mock
     private FutureJVpp api;
     @Mock
-    private Context ctx;
+    private WriteContext writeContext;
 
     private VxlanCustomizer customizer;
     private NamingContext namingContext;
@@ -72,6 +72,8 @@ public class VxlanCustomizerTest {
     @Before
     public void setUp() throws Exception {
         initMocks(this);
+        InterfaceTypeTestUtils.setupWriteContext(writeContext,
+            org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanTunnel.class);
         // TODO create base class for tests using vppApi
         namingContext = new NamingContext("generateInterfaceNAme");
         customizer = new VxlanCustomizer(api, namingContext);
@@ -140,7 +142,7 @@ public class VxlanCustomizerTest {
 
         whenVxlanAddDelTunnelThenSuccess();
 
-        customizer.writeCurrentAttributes(id, vxlan, ctx);
+        customizer.writeCurrentAttributes(id, vxlan, writeContext);
         verifyVxlanAddWasInvoked(vxlan);
         assertTrue(namingContext.containsIndex(ifaceName));
     }
@@ -152,7 +154,7 @@ public class VxlanCustomizerTest {
         whenVxlanAddDelTunnelThenFailure();
 
         try {
-            customizer.writeCurrentAttributes(id, vxlan, ctx);
+            customizer.writeCurrentAttributes(id, vxlan, writeContext);
         } catch (WriteFailedException.CreateFailedException e) {
             assertEquals(VppApiInvocationException.class, e.getCause().getClass());
             verifyVxlanAddWasInvoked(vxlan);
@@ -165,7 +167,7 @@ public class VxlanCustomizerTest {
     @Test
     public void testUpdateCurrentAttributes() throws Exception {
         try {
-            customizer.updateCurrentAttributes(id, generateVxlan(10), generateVxlan(11), ctx);
+            customizer.updateCurrentAttributes(id, generateVxlan(10), generateVxlan(11), writeContext);
         } catch (WriteFailedException.UpdateFailedException e) {
             assertEquals(UnsupportedOperationException.class, e.getCause().getClass());
             return;
@@ -175,7 +177,7 @@ public class VxlanCustomizerTest {
 
     @Test
     public void testUpdateCurrentAttributesNoUpdate() throws Exception {
-        customizer.updateCurrentAttributes(id, generateVxlan(), generateVxlan(), ctx);
+        customizer.updateCurrentAttributes(id, generateVxlan(), generateVxlan(), writeContext);
         verify(api, never()).vxlanAddDelTunnel(any(VxlanAddDelTunnel.class));
     }
 
@@ -186,7 +188,7 @@ public class VxlanCustomizerTest {
         whenVxlanAddDelTunnelThenSuccess();
         namingContext.addName(1, ifaceName);
 
-        customizer.deleteCurrentAttributes(id, vxlan, ctx);
+        customizer.deleteCurrentAttributes(id, vxlan, writeContext);
         verifyVxlanDeleteWasInvoked(vxlan);
         assertFalse(namingContext.containsIndex(ifaceName));
     }
@@ -199,7 +201,7 @@ public class VxlanCustomizerTest {
         namingContext.addName(1, ifaceName);
 
         try {
-            customizer.deleteCurrentAttributes(id, vxlan, ctx);
+            customizer.deleteCurrentAttributes(id, vxlan, writeContext);
         } catch (WriteFailedException.DeleteFailedException e) {
             assertEquals(VppApiInvocationException.class, e.getCause().getClass());
             verifyVxlanDeleteWasInvoked(vxlan);
index 6e44907..f5b19a7 100644 (file)
@@ -24,9 +24,9 @@ import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 import static org.mockito.MockitoAnnotations.initMocks;
 
-import io.fd.honeycomb.v3po.translate.Context;
-import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
+import 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;
@@ -49,7 +49,7 @@ public class BridgeDomainCustomizerTest {
     private FutureJVpp api;
 
     @Mock
-    private Context ctx;
+    private WriteContext ctx;
 
     private BridgeDomainCustomizer customizer;
     private NamingContext namingContext;
index 51b4c02..e9717de 100644 (file)
             <artifactId>jvpp</artifactId>
             <version>1.0.0-SNAPSHOT</version>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.mdsal.model</groupId>
+            <artifactId>ietf-interfaces</artifactId>
+        </dependency>
 
         <!-- Testing Dependencies -->
         <dependency>
diff --git a/v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/AbstractInterfaceTypeCustomizer.java b/v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/AbstractInterfaceTypeCustomizer.java
new file mode 100644 (file)
index 0000000..45ac193
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * 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 static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkState;
+
+import com.google.common.base.Optional;
+import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer;
+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.InterfaceType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.openvpp.jvpp.future.FutureJVpp;
+
+/**
+ * Validation WriteCustomizers for Interface subnodes.
+ * Validates the type of interface.
+ *
+ * TODO this should be validated on model/DataTree level. However DataTree does not enforce When conditions
+ * Delete this class when DataTree handles when constraints properly
+ */
+public abstract class AbstractInterfaceTypeCustomizer<D extends DataObject>
+    extends FutureJVppCustomizer implements ChildWriterCustomizer<D> {
+
+    protected AbstractInterfaceTypeCustomizer(final FutureJVpp futureJvpp) {
+        super(futureJvpp);
+    }
+
+    private void checkProperInterfaceType(@Nonnull final WriteContext writeContext,
+                                  @Nonnull final InstanceIdentifier<D> id) {
+        final InstanceIdentifier<Interface> ifcTypeFromIid = id.firstIdentifierOf(Interface.class);
+        checkArgument(ifcTypeFromIid != null, "Instance identifier does not contain {} type", Interface.class);
+        checkArgument(id.firstKeyOf(Interface.class) != null, "Instance identifier does not contain keyed {} type",
+            Interface.class);
+        final Optional<DataObject> interfaceConfigOperational = writeContext.readAfter(ifcTypeFromIid);
+        checkState(interfaceConfigOperational.isPresent(),
+            "Unable to get Interface configuration for an interface being updated under ID");
+
+        IllegalInterfaceTypeException
+            .checkInterfaceType((Interface) interfaceConfigOperational.get(), getExpectedInterfaceType());
+    }
+
+    protected abstract Class<? extends InterfaceType> getExpectedInterfaceType();
+
+    /**
+     * Validate expected interface type
+     */
+    @Override
+    public final void writeCurrentAttributes(@Nonnull final InstanceIdentifier<D> id, @Nonnull final D dataAfter,
+                                       @Nonnull final WriteContext writeContext) throws WriteFailedException.CreateFailedException {
+        checkProperInterfaceType(writeContext, id);
+        writeInterface(id, dataAfter, writeContext);
+    }
+
+    protected abstract void writeInterface(final InstanceIdentifier<D> id, final D dataAfter,
+                                           final WriteContext writeContext)
+        throws WriteFailedException.CreateFailedException;
+
+    // Validation for update and delete is not necessary
+
+    /**
+     * Indicates unexpected interface type
+     */
+    protected static final class IllegalInterfaceTypeException extends IllegalArgumentException {
+
+        private IllegalInterfaceTypeException(final String msg) {
+            super(msg);
+        }
+
+        /**
+         * Check the type of interface equals expected type
+         *
+         * @throws IllegalInterfaceTypeException if type of interface is null or not expected
+         */
+        static void checkInterfaceType(@Nonnull final Interface ifc,
+                                       @Nonnull final Class<? extends InterfaceType> expectedType) {
+            if (ifc.getType() == null || !expectedType.equals(ifc.getType())) {
+                throw new IllegalInterfaceTypeException(String.format(
+                    "Unexpected interface type: %s for interface: %s. Expected interface is: %s", ifc.getType(),
+                    ifc.getName(), expectedType));
+            }
+        }
+
+    }
+}