HONEYCOMB-10: Porting v3po2vpp to the new Java API
authorMarek Gradzki <[email protected]>
Wed, 4 May 2016 08:17:39 +0000 (10:17 +0200)
committerMarek Gradzki <[email protected]>
Thu, 5 May 2016 06:41:23 +0000 (08:41 +0200)
Change-Id: Ic7166b0f578442165595aa44a587ebbc5db0e75c
Signed-off-by: Marek Gradzki <[email protected]>
Signed-off-by: Maros Marsalek <[email protected]>
56 files changed:
v3po/artifacts/pom.xml
v3po/features/pom.xml
v3po/features/src/main/features/features.xml
v3po/impl/pom.xml
v3po/impl/src/main/config/default-config.xml
v3po/impl/src/main/yang/v3po-impl.yang
v3po/pom.xml
v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/read/ListReaderCustomizer.java
v3po/v3po2vpp/pom.xml
v3po/v3po2vpp/src/main/config/default-config.xml
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/VxlanCustomizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Interface1Customizer.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/interfacesstate/InterfaceCustomizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceUtils.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VppInterfaceStateCustomizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/utils/V3poUtils.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainCustomizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/BridgeDomainCustomizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VersionCustomizer.java
v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/InterfacesHoneycombWriterModule.java
v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/InterfacesStateHoneycombReaderModule.java
v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/VppHoneycombWriterModule.java
v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/VppStateHoneycombReaderModule.java
v3po/v3po2vpp/src/main/yang/v3po2vpp.yang
v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizerTest.java
v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/ChildReaderCustomizerTest.java [new file with mode: 0644]
v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/ListReaderCustomizerTest.java [new file with mode: 0644]
v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/RootReaderCustomizerTest.java [new file with mode: 0644]
v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/utils/V3poUtilsTest.java
v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainCustomizerTest.java
v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/VppTest.java
v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/VppUtils.java
v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/BridgeDomainCustomizerTest.java [new file with mode: 0644]
v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VersionCustomizerTest.java [new file with mode: 0644]
v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VppStateTest.java
v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VppStateTestUtils.java [moved from v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VppStateUtils.java with 70% similarity]
v3po/vpp-cfg-init/src/main/java/io/fd/honeycomb/v3po/vpp/data/init/VppInitializer.java
v3po/vpp-japi-cfg/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/japi/cfg/rev160406/VppJapiImplModule.java [deleted file]
v3po/vpp-japi-cfg/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/japi/cfg/rev160406/VppJapiImplModuleFactory.java [deleted file]
v3po/vpp-jvpp-cfg/pom.xml [moved from v3po/vpp-japi-cfg/pom.xml with 94% similarity]
v3po/vpp-jvpp-cfg/src/main/config/default-config.xml [moved from v3po/vpp-japi-cfg/src/main/config/default-config.xml with 78% similarity]
v3po/vpp-jvpp-cfg/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/jvpp/cfg/rev160406/VppJvppImplModule.java [new file with mode: 0644]
v3po/vpp-jvpp-cfg/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/jvpp/cfg/rev160406/VppJvppImplModuleFactory.java [new file with mode: 0644]
v3po/vpp-jvpp-cfg/src/main/yang/vpp-jvpp-cfg.yang [moved from v3po/vpp-japi-cfg/src/main/yang/vpp-japi-cfg.yang with 67% similarity]
v3po/vpp-translate-utils/pom.xml
v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/FutureJVppCustomizer.java [moved from v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/VppApiCustomizer.java with 66% similarity]
v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/NamingContext.java [new file with mode: 0644]
v3po/vpp-translate-utils/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/util/rev160406/NamingContextImplModule.java [new file with mode: 0644]
v3po/vpp-translate-utils/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/util/rev160406/NamingContextImplModuleFactory.java [new file with mode: 0644]
v3po/vpp-translate-utils/src/main/yang/vpp-util.yang [new file with mode: 0644]

index a915cb3..e3ee2da 100644 (file)
@@ -71,7 +71,7 @@
       </dependency>
       <dependency>
         <groupId>${project.groupId}</groupId>
-        <artifactId>vpp-japi-cfg</artifactId>
+        <artifactId>vpp-jvpp-cfg</artifactId>
         <version>${project.version}</version>
       </dependency>
       <dependency>
index 53ab054..aa50c05 100644 (file)
     </dependency>
     <dependency>
       <groupId>${project.groupId}</groupId>
-      <artifactId>vpp-japi-cfg</artifactId>
+      <artifactId>vpp-jvpp-cfg</artifactId>
       <version>${project.version}</version>
     </dependency>
     <dependency>
       <groupId>${project.groupId}</groupId>
-      <artifactId>vpp-japi-cfg</artifactId>
+      <artifactId>vpp-jvpp-cfg</artifactId>
       <version>${project.version}</version>
       <type>xml</type>
       <classifier>config</classifier>
     </dependency>
     <dependency>
       <groupId>io.fd.vpp</groupId>
-      <artifactId>vppjapi</artifactId>
+      <artifactId>jvpp</artifactId>
       <version>1.0.0-SNAPSHOT</version>
     </dependency>
   </dependencies>
index b1cc718..9a8df9b 100644 (file)
     <bundle>mvn:io.fd.honeycomb.v3po/data-api/${project.version}</bundle>
     <bundle>mvn:io.fd.honeycomb.v3po/data-impl/${project.version}</bundle>
     <bundle>mvn:io.fd.honeycomb.v3po/translate-impl/${project.version}</bundle>
-    <bundle>wrap:mvn:io.fd.vpp/vppjapi/1.0.0-SNAPSHOT</bundle>
-    <bundle>mvn:io.fd.honeycomb.v3po/vpp-japi-cfg/${project.version}</bundle>
+    <bundle>wrap:mvn:io.fd.vpp/jvpp/1.0.0-SNAPSHOT</bundle>
+    <bundle>mvn:io.fd.honeycomb.v3po/vpp-jvpp-cfg/${project.version}</bundle>
     <bundle>mvn:io.fd.honeycomb.v3po/v3po2vpp/${project.version}</bundle>
     <bundle>mvn:io.fd.honeycomb.v3po/vpp-cfg-init/${project.version}</bundle>
-    <configfile finalname="${configfile.directory}/vpp-japi.xml">mvn:io.fd.honeycomb.v3po/vpp-japi-cfg/${project.version}/xml/config</configfile>
+    <configfile finalname="${configfile.directory}/vpp-jvpp.xml">mvn:io.fd.honeycomb.v3po/vpp-jvpp-cfg/${project.version}/xml/config</configfile>
     <configfile finalname="${configfile.directory}/v3po.xml">mvn:io.fd.honeycomb.v3po/v3po-impl/${project.version}/xml/config</configfile>
     <configfile finalname="${configfile.directory}/v3po-netconf.xml">mvn:io.fd.honeycomb.v3po/v3po-impl/${project.version}/xml/netconf</configfile>
     <configfile finalname="${configfile.directory}/v3po-restconf.xml">mvn:io.fd.honeycomb.v3po/v3po-impl/${project.version}/xml/restconf</configfile>
index 3678853..053e0ff 100644 (file)
       <version>1.0.0-Beryllium</version>
     </dependency>
 
-
-    <dependency>
-      <groupId>io.fd.vpp</groupId>
-      <artifactId>vppjapi</artifactId>
-      <version>1.0.0-SNAPSHOT</version>
-    </dependency>
-
     <dependency>
       <groupId>org.opendaylight.mdsal.model</groupId>
       <artifactId>ietf-topology</artifactId>
       <artifactId>mockito-all</artifactId>
       <scope>test</scope>
     </dependency>
-    <!--Needed due to final vppAPI, TODO remove once vppAPi refactored-->
-    <dependency>
-      <groupId>org.powermock</groupId>
-      <artifactId>powermock-api-mockito</artifactId>
-      <version>1.5.6</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.powermock</groupId>
-      <artifactId>powermock-module-junit4</artifactId>
-      <version>1.5.6</version>
-      <scope>test</scope>
-    </dependency>
   </dependencies>
 
 
index 40478b7..f679521 100644 (file)
@@ -18,7 +18,7 @@
   <required-capabilities>
       <capability>urn:opendaylight:params:xml:ns:yang:v3po:impl?module=v3po-impl&amp;revision=2014-12-10</capability>
       <capability>urn:honeycomb:params:xml:ns:yang:translate:utils?module=translate-utils&amp;revision=2016-04-06</capability>
-      <capability>urn:honeycomb:params:xml:ns:yang:vpp:japi:cfg?module=vpp-japi-cfg&amp;revision=2016-04-06</capability>
+      <capability>urn:honeycomb:params:xml:ns:yang:vpp:jvpp:cfg?module=vpp-jvpp-cfg&amp;revision=2016-04-06</capability>
       <capability>urn:honeycomb:params:xml:ns:yang:vpp:data:init?module=vpp-cfg-init&amp;revision=2016-04-07</capability>
       <capability>urn:honeycomb:params:xml:ns:yang:data:impl?module=data-impl&amp;revision=2016-04-11</capability>
       <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&amp;revision=2013-10-28</capability>
index b496857..30b70f3 100644 (file)
@@ -6,7 +6,7 @@ module v3po-impl {
     import config { prefix config; revision-date 2013-04-05; }
     import opendaylight-md-sal-binding { prefix md-sal-binding; revision-date 2013-10-28;}
     import opendaylight-md-sal-dom {prefix dom;}
-    import vpp-japi-cfg { prefix vjc; revision-date 2016-04-06; }
+    import vpp-jvpp-cfg { prefix vjvppc; revision-date 2016-04-06; }
     import translate-api { prefix tapi; revision-date 2016-04-06; }
     import data-api { prefix dapi; revision-date 2016-04-11; }
 
index 6389fb2..c79cb12 100644 (file)
@@ -40,7 +40,7 @@
     <module>translate-impl</module>
     <module>translate-utils</module>
     <module>vpp-translate-utils</module>
-    <module>vpp-japi-cfg</module>
+    <module>vpp-jvpp-cfg</module>
     <module>v3po2vpp</module>
     <module>vpp-cfg-init</module>
     <module>impl</module>
index 746b439..857743e 100644 (file)
@@ -18,6 +18,7 @@ package io.fd.honeycomb.v3po.translate.spi.read;
 
 import com.google.common.annotations.Beta;
 import io.fd.honeycomb.v3po.translate.Context;
+import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
 import java.util.List;
 import javax.annotation.Nonnull;
 import org.opendaylight.yangtools.concepts.Builder;
@@ -42,9 +43,11 @@ public interface ListReaderCustomizer<C extends DataObject & Identifiable<K>, K
      *
      * @param id Wildcarded ID pointing to list node managed by enclosing reader
      * @param context Read context
+     * @throws ReadFailedException if the list of IDs could not be read
      */
     @Nonnull
-    List<K> getAllIds(@Nonnull final InstanceIdentifier<C> id, @Nonnull final Context context);
+    List<K> getAllIds(@Nonnull final InstanceIdentifier<C> id, @Nonnull final Context context) throws
+            ReadFailedException;
     // TODO does it make sense with vpp APIs ? Should we replace it with a simple readAll ?
 
     /**
index 6b57ca2..9fbaf0b 100644 (file)
         </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
-            <artifactId>vpp-japi-cfg</artifactId>
+            <artifactId>vpp-jvpp-cfg</artifactId>
             <version>${project.version}</version>
         </dependency>
         <dependency>
             <groupId>io.fd.vpp</groupId>
-            <artifactId>vppjapi</artifactId>
+            <artifactId>jvpp</artifactId>
             <version>1.0.0-SNAPSHOT</version>
         </dependency>
 
             <artifactId>mockito-all</artifactId>
             <scope>test</scope>
         </dependency>
-        <!--Needed due to final vppAPI, TODO remove once vppAPi refactored-->
-        <dependency>
-            <groupId>org.powermock</groupId>
-            <artifactId>powermock-api-mockito</artifactId>
-            <version>1.5.6</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.powermock</groupId>
-            <artifactId>powermock-module-junit4</artifactId>
-            <version>1.5.6</version>
-            <scope>test</scope>
-        </dependency>
         <dependency>
             <groupId>org.skinny-framework</groupId>
             <artifactId>skinny-logback</artifactId>
index 89c3c47..cd736ed 100644 (file)
 
 <snapshot>
     <required-capabilities>
-        <capability>urn:honeycomb:params:xml:ns:yang:vpp:japi:cfg?module=vpp-japi-cfg&amp;revision=2016-04-06</capability>
+        <capability>urn:honeycomb:params:xml:ns:yang:vpp:jvpp:cfg?module=vpp-jvpp-cfg&amp;revision=2016-04-06</capability>
         <capability>urn:honeycomb:params:xml:ns:yang:v3po2vpp?module=v3po2vpp&amp;revision=2016-04-06</capability>
+        <capability>urn:honeycomb:params:xml:ns:yang:vpp:util?module=vpp-util&amp;revision=2016-04-06</capability>
     </required-capabilities>
     <configuration>
 
         <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
             <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+                <module>
+                    <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:util">prefix:naming-context-impl</type>
+                    <name>interface-context</name>
+                    <artificial-name-prefix>interface-</artificial-name-prefix>
+                </module>
+                <module>
+                    <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:util">prefix:naming-context-impl</type>
+                    <name>bridge-domain-context</name>
+                    <artificial-name-prefix>bridge-domain-</artificial-name-prefix>
+                </module>
+
                 <module>
                     <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:v3po2vpp">prefix:vpp-state-honeycomb-reader</type>
                     <name>vpp-state-honeycomb-reader</name>
-                    <vpp-japi>
-                        <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:japi:cfg">prefix:vpp-japi</type>
-                        <name>vpp-japi</name>
-                    </vpp-japi>
+                    <vpp-jvpp>
+                        <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:jvpp:cfg">prefix:vpp-jvpp</type>
+                        <name>vpp-jvpp</name>
+                    </vpp-jvpp>
+                    <interface-context-vpp-state>
+                        <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:util">prefix:naming-context</type>
+                        <name>interface-context</name>
+                    </interface-context-vpp-state>
+                    <bridge-domain-context-vpp-state>
+                        <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:util">prefix:naming-context</type>
+                        <name>bridge-domain-context</name>
+                    </bridge-domain-context-vpp-state>
                 </module>
                 <module>
                     <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:v3po2vpp">prefix:interfaces-state-honeycomb-reader</type>
                     <name>interfaces-state-honeycomb-reader</name>
-                    <vpp-japi>
-                        <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:japi:cfg">prefix:vpp-japi</type>
-                        <name>vpp-japi</name>
-                    </vpp-japi>
+                    <vpp-jvpp>
+                        <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:jvpp:cfg">prefix:vpp-jvpp</type>
+                        <name>vpp-jvpp</name>
+                    </vpp-jvpp>
+                    <interface-context-ifc-state>
+                        <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:util">prefix:naming-context</type>
+                        <name>interface-context</name>
+                    </interface-context-ifc-state>
+                    <bridge-domain-context-ifc-state>
+                        <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:util">prefix:naming-context</type>
+                        <name>bridge-domain-context</name>
+                    </bridge-domain-context-ifc-state>
                 </module>
 
                 <module>
                     <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:v3po2vpp">prefix:vpp-honeycomb-writer</type>
                     <name>vpp-honeycomb-writer</name>
-                    <vpp-japi-writer>
-                        <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:japi:cfg">prefix:vpp-japi</type>
-                        <name>vpp-japi</name>
-                    </vpp-japi-writer>
+                    <vpp-jvpp-writer>
+                        <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:jvpp:cfg">prefix:vpp-jvpp</type>
+                        <name>vpp-jvpp</name>
+                    </vpp-jvpp-writer>
+                    <interface-context-vpp>
+                        <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:util">prefix:naming-context</type>
+                        <name>interface-context</name>
+                    </interface-context-vpp>
+                    <bridge-domain-context-vpp>
+                        <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:util">prefix:naming-context</type>
+                        <name>bridge-domain-context</name>
+                    </bridge-domain-context-vpp>
                 </module>
 
                 <module>
                     <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:v3po2vpp">prefix:interfaces-honeycomb-writer</type>
                     <name>interfaces-honeycomb-writer</name>
-                    <vpp-japi-ifc>
-                        <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:japi:cfg">prefix:vpp-japi</type>
-                        <name>vpp-japi</name>
-                    </vpp-japi-ifc>
+                    <vpp-jvpp-ifc>
+                        <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:jvpp:cfg">prefix:vpp-jvpp</type>
+                        <name>vpp-jvpp</name>
+                    </vpp-jvpp-ifc>
+                    <interface-context>
+                        <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:util">prefix:naming-context</type>
+                        <name>interface-context</name>
+                    </interface-context>
+                    <bridge-domain-context>
+                        <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:util">prefix:naming-context</type>
+                        <name>bridge-domain-context</name>
+                    </bridge-domain-context>
                 </module>
 
                 <module>
                         <provider>/modules/module[type='interfaces-state-honeycomb-reader'][name='interfaces-state-honeycomb-reader']</provider>
                     </instance>
                 </service>
+                <service>
+                    <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:util">prefix:naming-context</type>
+                    <instance>
+                        <name>interface-context</name>
+                        <provider>/modules/module[type='naming-context-impl'][name='interface-context']</provider>
+                    </instance>
+                    <instance>
+                        <name>bridge-domain-context</name>
+                        <provider>/modules/module[type='naming-context-impl'][name='bridge-domain-context']</provider>
+                    </instance>
+                </service>
                 <service>
                     <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:api">prefix:honeycomb-writer</type>
                     <instance>
index 69ff631..cdcea45 100644 (file)
@@ -19,20 +19,21 @@ package io.fd.honeycomb.v3po.translate.v3po.interfaces;
 import com.google.common.base.Optional;
 import io.fd.honeycomb.v3po.translate.Context;
 import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer;
-import io.fd.honeycomb.v3po.translate.v3po.util.VppApiCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
 import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.Ethernet;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.openvpp.jvpp.future.FutureJVpp;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class EthernetCustomizer extends VppApiCustomizer implements ChildWriterCustomizer<Ethernet> {
+public class EthernetCustomizer extends FutureJVppCustomizer implements ChildWriterCustomizer<Ethernet> {
 
     private static final Logger LOG = LoggerFactory.getLogger(EthernetCustomizer.class);
 
-    public EthernetCustomizer(final org.openvpp.vppjapi.vppApi vppApi) {
+    public EthernetCustomizer(final FutureJVpp vppApi) {
         super(vppApi);
     }
 
index 30600d8..5d5a6c0 100644 (file)
@@ -18,30 +18,36 @@ package io.fd.honeycomb.v3po.translate.v3po.interfaces;
 
 import io.fd.honeycomb.v3po.translate.Context;
 import io.fd.honeycomb.v3po.translate.spi.write.ListWriterCustomizer;
-import io.fd.honeycomb.v3po.translate.v3po.util.VppApiCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
+import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException;
 import io.fd.honeycomb.v3po.translate.v3po.utils.V3poUtils;
 import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
 import java.util.List;
+import java.util.concurrent.CompletionStage;
 import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.openvpp.vppjapi.vppApi;
+import org.openvpp.jvpp.dto.SwInterfaceSetFlags;
+import org.openvpp.jvpp.dto.SwInterfaceSetFlagsReply;
+import org.openvpp.jvpp.future.FutureJVpp;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
  * Ietf interface write customizer that only caches interface objects for child writers
  */
-public class InterfaceCustomizer extends VppApiCustomizer implements ListWriterCustomizer<Interface, InterfaceKey> {
+public class InterfaceCustomizer extends FutureJVppCustomizer implements ListWriterCustomizer<Interface, InterfaceKey> {
 
     private static final Logger LOG = LoggerFactory.getLogger(InterfaceCustomizer.class);
+    private final NamingContext interfaceContext;
 
-    public InterfaceCustomizer(final vppApi vppApi) {
+    public InterfaceCustomizer(final FutureJVpp vppApi, final NamingContext interfaceContext) {
         super(vppApi);
+        this.interfaceContext = interfaceContext;
     }
 
     @Override
@@ -94,20 +100,15 @@ public class InterfaceCustomizer extends VppApiCustomizer implements ListWriterC
         LOG.info("Setting interface {}, type: {}", swIf.getName(), swIf.getType().getSimpleName());
         LOG.debug("Setting interface {}", swIf);
 
-        String swIfName = swIf.getName();
-        int swIfIndex = getVppApi().swIfIndexFromName(swIfName);
-
-        setInterfaceAttributes(swIf, swIfName);
+        setInterfaceAttributes(swIf, swIf.getName());
     }
 
     private void setInterfaceAttributes(final Interface swIf, final String swIfName)
         throws VppApiInvocationException {
         LOG.debug("Creating {} interface {}", swIf.getType().getSimpleName(), swIf.getName());
 
-        setInterfaceFlags(swIfName, getVppApi().swIfIndexFromName(swIfName),
+        setInterfaceFlags(swIfName, interfaceContext.getIndex(swIfName),
             swIf.isEnabled() ? (byte) 1 : (byte) 0);
-
-        setDescription(swIf);
     }
 
     private void updateInterface(final InstanceIdentifier<Interface> id,
@@ -116,35 +117,33 @@ public class InterfaceCustomizer extends VppApiCustomizer implements ListWriterC
         LOG.info("Updating interface {}, type: {}", dataAfter.getName(), dataAfter.getType().getSimpleName());
         LOG.debug("Updating interface {}", dataAfter);
 
-        String swIfName = dataAfter.getName();
-        int swIfIndex = getVppApi().swIfIndexFromName(swIfName);
-
-        setInterfaceAttributes(dataAfter, swIfName);
+        setInterfaceAttributes(dataAfter, dataAfter.getName());
     }
 
     private void setInterfaceFlags(final String swIfName, final int swIfIndex, final byte enabled)
         throws VppApiInvocationException {
-        int ctxId = getVppApi().swInterfaceSetFlags(swIfIndex, enabled, enabled, (byte) 0 /* deleted */);
+        final CompletionStage<SwInterfaceSetFlagsReply> swInterfaceSetFlagsReplyFuture = getFutureJVpp().swInterfaceSetFlags(
+            getSwInterfaceSetFlagsInput(swIfIndex, enabled, (byte) 0 /* deleted */));
 
-        LOG.debug("Updating interface flags for: {}, index: {}, enabled: {}, ctxId: {}", swIfName, swIfIndex,
-            enabled, ctxId);
+        LOG.debug("Updating interface flags for: {}, index: {}, enabled: {}", swIfName, swIfIndex, enabled);
 
-        final int rv = V3poUtils.waitForResponse(ctxId, getVppApi());
-        if (rv < 0) {
-            LOG.warn("Failed to update interface flags for: {}, index: {}, enabled: {}, ctxId: {}", swIfName, swIfIndex,
-                enabled, ctxId);
-            throw new VppApiInvocationException("swInterfaceSetFlags", ctxId, rv);
+        SwInterfaceSetFlagsReply reply = V3poUtils.getReply(swInterfaceSetFlagsReplyFuture.toCompletableFuture());
+        if (reply.retval < 0) {
+            LOG.warn("Failed to update interface flags for: {}, index: {}, enabled: {}", swIfName, swIfIndex,
+                enabled);
+            throw new VppApiInvocationException("swInterfaceSetFlags", reply.context, reply.retval);
         } else {
             LOG.debug("Interface flags updated successfully for: {}, index: {}, enabled: {}, ctxId: {}",
-                swIfName, swIfIndex, enabled, ctxId);
+                swIfName, swIfIndex, enabled, reply.context);
         }
     }
 
-    private void setDescription(final Interface swIf) {
-        if (swIf.getDescription() != null) {
-            getVppApi().setInterfaceDescription(swIf.getName(), swIf.getDescription());
-        } else {
-            getVppApi().setInterfaceDescription(swIf.getName(), "");
-        }
+    private SwInterfaceSetFlags getSwInterfaceSetFlagsInput(final int swIfIndex, final byte enabled, final byte deleted) {
+        final SwInterfaceSetFlags swInterfaceSetFlags = new SwInterfaceSetFlags();
+        swInterfaceSetFlags.swIfIndex = swIfIndex;
+        swInterfaceSetFlags.adminUpDown = enabled;
+        swInterfaceSetFlags.linkUpDown = enabled;
+        swInterfaceSetFlags.deleted = deleted;
+        return swInterfaceSetFlags;
     }
 }
index b9296b4..3bc04f8 100644 (file)
@@ -21,10 +21,12 @@ import static com.google.common.base.Preconditions.checkArgument;
 import com.google.common.base.Optional;
 import io.fd.honeycomb.v3po.translate.Context;
 import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer;
-import io.fd.honeycomb.v3po.translate.v3po.util.VppApiCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
+import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException;
 import io.fd.honeycomb.v3po.translate.v3po.utils.V3poUtils;
 import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
+import java.util.concurrent.CompletionStage;
 import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentation;
@@ -34,15 +36,25 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.l2.interconnection.XconnectBased;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.openvpp.jvpp.dto.SwInterfaceSetL2Bridge;
+import org.openvpp.jvpp.dto.SwInterfaceSetL2BridgeReply;
+import org.openvpp.jvpp.dto.SwInterfaceSetL2Xconnect;
+import org.openvpp.jvpp.dto.SwInterfaceSetL2XconnectReply;
+import org.openvpp.jvpp.future.FutureJVpp;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class L2Customizer extends VppApiCustomizer implements ChildWriterCustomizer<L2> {
+public class L2Customizer extends FutureJVppCustomizer implements ChildWriterCustomizer<L2> {
 
     private static final Logger LOG = LoggerFactory.getLogger(L2Customizer.class);
+    private final NamingContext interfaceContext;
+    private final NamingContext bridgeDomainContext;
 
-    public L2Customizer(final org.openvpp.vppjapi.vppApi vppApi) {
+    public L2Customizer(final FutureJVpp vppApi, final NamingContext interfaceContext,
+                        final NamingContext bridgeDomainContext) {
         super(vppApi);
+        this.interfaceContext = interfaceContext;
+        this.bridgeDomainContext = bridgeDomainContext;
     }
 
     @Nonnull
@@ -57,7 +69,7 @@ public class L2Customizer extends VppApiCustomizer implements ChildWriterCustomi
         throws WriteFailedException {
 
         final String ifcName = id.firstKeyOf(Interface.class).getName();
-        final int swIfc = getSwIfc(ifcName);
+        final int swIfc = interfaceContext.getIndex(ifcName);
         try {
             setL2(id, swIfc, ifcName, dataAfter);
         } catch (VppApiInvocationException e) {
@@ -72,7 +84,7 @@ public class L2Customizer extends VppApiCustomizer implements ChildWriterCustomi
         throws WriteFailedException {
 
         final String ifcName = id.firstKeyOf(Interface.class).getName();
-        final int swIfc = getSwIfc(ifcName);
+        final int swIfc = interfaceContext.getIndex(ifcName);
         // TODO handle update properly (if possible)
         try {
             setL2(id, swIfc, ifcName, dataAfter);
@@ -82,12 +94,6 @@ public class L2Customizer extends VppApiCustomizer implements ChildWriterCustomi
         }
     }
 
-    private int getSwIfc(final String ifcName) {
-        int swIfcIndex = getVppApi().swIfIndexFromName(ifcName);
-        checkArgument(swIfcIndex != -1, "Interface %s does not exist", ifcName);
-        return swIfcIndex;
-    }
-
     @Override
     public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<L2> id, @Nonnull final L2 dataBefore,
                                         @Nonnull final Context writeContext) {
@@ -126,7 +132,9 @@ public class L2Customizer extends VppApiCustomizer implements ChildWriterCustomi
             bb.getBridgeDomain(), ifcName);
 
         String bdName = bb.getBridgeDomain();
-        int bdId = getVppApi().bridgeDomainIdFromName(bdName);
+
+        // FIXME need BridgeDomainContext here
+        int bdId = bridgeDomainContext.getIndex(bdName);
         checkArgument(bdId > 0, "Unable to set Interconnection for Interface: %s, bridge domain: %s does not exist",
             ifcName, bdName);
 
@@ -135,19 +143,32 @@ public class L2Customizer extends VppApiCustomizer implements ChildWriterCustomi
             : (byte) 0;
         byte shg = bb.getSplitHorizonGroup().byteValue();
 
-        final int ctxId = getVppApi().swInterfaceSetL2Bridge(swIfIndex, bdId, shg, bvi, (byte) 1 /* enable */);
-        final int rv = V3poUtils.waitForResponse(ctxId, getVppApi());
+        final CompletionStage<SwInterfaceSetL2BridgeReply> swInterfaceSetL2BridgeReplyCompletionStage = getFutureJVpp()
+            .swInterfaceSetL2Bridge(getL2BridgeRequest(swIfIndex, bdId, shg, bvi, (byte) 1 /* enable */));
+        final SwInterfaceSetL2BridgeReply reply =
+            V3poUtils.getReply(swInterfaceSetL2BridgeReplyCompletionStage.toCompletableFuture());
 
-        if (rv < 0) {
+        if (reply.retval < 0) {
             LOG.warn("Failed to update bridge based interconnection flags for: {}, interconnection: {}", ifcName,
                 bb);
-            throw new VppApiInvocationException("swInterfaceSetL2Bridge", ctxId, rv);
+            throw new VppApiInvocationException("swInterfaceSetL2Bridge", reply.context, reply.retval);
         } else {
             LOG.debug("Bridge based interconnection updated successfully for: {}, interconnection: {}", ifcName,
                 bb);
         }
     }
 
+    private SwInterfaceSetL2Bridge getL2BridgeRequest(final int swIfIndex, final int bdId, final byte shg,
+                                                      final byte bvi, final byte enabled) {
+        final SwInterfaceSetL2Bridge swInterfaceSetL2Bridge = new SwInterfaceSetL2Bridge();
+        swInterfaceSetL2Bridge.rxSwIfIndex = swIfIndex;
+        swInterfaceSetL2Bridge.bdId = bdId;
+        swInterfaceSetL2Bridge.shg = shg;
+        swInterfaceSetL2Bridge.bvi = bvi;
+        swInterfaceSetL2Bridge.enable = enabled;
+        return swInterfaceSetL2Bridge;
+    }
+
     private void setXconnectBasedL2(final int swIfIndex, final String ifcName, final XconnectBased ic)
         throws VppApiInvocationException {
 
@@ -155,21 +176,34 @@ public class L2Customizer extends VppApiCustomizer implements ChildWriterCustomi
         LOG.debug("Setting xconnect based interconnection(outgoing ifc=%s) for interface: %s", outSwIfName,
             ifcName);
 
-        int outSwIfIndex = getVppApi().swIfIndexFromName(outSwIfName);
+        int outSwIfIndex = interfaceContext.getIndex(outSwIfName);
         checkArgument(outSwIfIndex > 0,
             "Unable to set Interconnection for Interface: %s, outgoing interface: %s does not exist",
             ifcName, outSwIfIndex);
 
-        int ctxId = getVppApi().swInterfaceSetL2Xconnect(swIfIndex, outSwIfIndex, (byte) 1 /* enable */);
-        final int rv = V3poUtils.waitForResponse(ctxId, getVppApi());
+        final CompletionStage<SwInterfaceSetL2XconnectReply> swInterfaceSetL2XconnectReplyCompletionStage =
+            getFutureJVpp()
+                .swInterfaceSetL2Xconnect(getL2XConnectRequest(swIfIndex, outSwIfIndex, (byte) 1 /* enable */));
+        final SwInterfaceSetL2XconnectReply reply =
+            V3poUtils.getReply(swInterfaceSetL2XconnectReplyCompletionStage.toCompletableFuture());
 
-        if (rv < 0) {
+        if (reply.retval < 0) {
             LOG.warn("Failed to update xconnect based interconnection flags for: {}, interconnection: {}",
                 ifcName, ic);
-            throw new VppApiInvocationException("swInterfaceSetL2Xconnect", ctxId, rv);
+            throw new VppApiInvocationException("swInterfaceSetL2Xconnect", reply.context, reply.retval);
         } else {
             LOG.debug("Xconnect based interconnection updated successfully for: {}, interconnection: {}", ifcName,
                 ic);
         }
     }
+
+    private SwInterfaceSetL2Xconnect getL2XConnectRequest(final int rxIfc, final int txIfc,
+                                                          final byte enabled) {
+
+        final SwInterfaceSetL2Xconnect swInterfaceSetL2Xconnect = new SwInterfaceSetL2Xconnect();
+        swInterfaceSetL2Xconnect.enable = enabled;
+        swInterfaceSetL2Xconnect.rxSwIfIndex = rxIfc;
+        swInterfaceSetL2Xconnect.txSwIfIndex = txIfc;
+        return swInterfaceSetL2Xconnect;
+    }
 }
index 718afc0..b15050c 100644 (file)
 
 package io.fd.honeycomb.v3po.translate.v3po.interfaces;
 
-import static com.google.common.base.Preconditions.checkArgument;
-
 import com.google.common.base.Optional;
 import io.fd.honeycomb.v3po.translate.Context;
 import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer;
-import io.fd.honeycomb.v3po.translate.v3po.util.VppApiCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException;
 import io.fd.honeycomb.v3po.translate.v3po.utils.V3poUtils;
 import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
+import java.util.concurrent.CompletionStage;
 import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.Routing;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.openvpp.jvpp.dto.SwInterfaceSetTable;
+import org.openvpp.jvpp.dto.SwInterfaceSetTableReply;
+import org.openvpp.jvpp.future.FutureJVpp;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class RoutingCustomizer extends VppApiCustomizer implements ChildWriterCustomizer<Routing> {
+public class RoutingCustomizer extends FutureJVppCustomizer implements ChildWriterCustomizer<Routing> {
 
     private static final Logger LOG = LoggerFactory.getLogger(RoutingCustomizer.class);
+    private final NamingContext interfaceContext;
 
-    public RoutingCustomizer(final org.openvpp.vppjapi.vppApi vppApi) {
+    public RoutingCustomizer(final FutureJVpp vppApi, final NamingContext interfaceContext) {
         super(vppApi);
+        this.interfaceContext = interfaceContext;
     }
 
     @Nonnull
@@ -84,7 +89,7 @@ public class RoutingCustomizer extends VppApiCustomizer implements ChildWriterCu
     }
 
     private void setRouting(final String name, final Routing rt) throws VppApiInvocationException {
-        final int swIfc = getSwIfc(name);
+        final int swIfc = interfaceContext.getIndex(name);
         LOG.debug("Setting routing for interface: {}, {}. Routing: {}", name, swIfc, rt);
 
         int vrfId = (rt != null)
@@ -92,21 +97,25 @@ public class RoutingCustomizer extends VppApiCustomizer implements ChildWriterCu
             : 0;
 
         if (vrfId != 0) {
-            final int ctxId = getVppApi().swInterfaceSetTable(swIfc, (byte) 0, /* isIpv6 */ vrfId);
-            final int rv = V3poUtils.waitForResponse(ctxId, getVppApi());
-            if (rv < 0) {
+            final CompletionStage<SwInterfaceSetTableReply> swInterfaceSetTableReplyCompletionStage =
+                getFutureJVpp().swInterfaceSetTable(getInterfaceSetTableRequest(swIfc, (byte) 0, /* isIpv6 */ vrfId));
+            final SwInterfaceSetTableReply reply =
+                V3poUtils.getReply(swInterfaceSetTableReplyCompletionStage.toCompletableFuture());
+            if (reply.retval < 0) {
                 LOG.debug("Failed to set routing for interface: {}, {}, vxlan: {}", name, swIfc, rt);
-                throw new VppApiInvocationException("swInterfaceSetTable", ctxId, rv);
+                throw new VppApiInvocationException("swInterfaceSetTable", reply.context, reply.retval);
             } else {
                 LOG.debug("Routing set successfully for interface: {}, {}, routing: {}", name, swIfc, rt);
             }
         }
     }
 
-    private int getSwIfc(final String name) {
-        int swIfcIndex = getVppApi().swIfIndexFromName(name);
-        checkArgument(swIfcIndex != -1, "Interface %s does not exist", name);
-        return swIfcIndex;
+    private SwInterfaceSetTable getInterfaceSetTableRequest(final int swIfc, final byte isIpv6, final int vrfId) {
+        final SwInterfaceSetTable swInterfaceSetTable = new SwInterfaceSetTable();
+        swInterfaceSetTable.isIpv6 = isIpv6;
+        swInterfaceSetTable.swIfIndex = swIfc;
+        swInterfaceSetTable.vrfId = vrfId;
+        return swInterfaceSetTable;
     }
 
 }
index 6e84c30..2e53266 100644 (file)
 package io.fd.honeycomb.v3po.translate.v3po.interfaces;
 
 import com.google.common.base.Optional;
+import com.google.common.net.InetAddresses;
 import io.fd.honeycomb.v3po.translate.Context;
 import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer;
-import io.fd.honeycomb.v3po.translate.v3po.util.VppApiCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException;
 import io.fd.honeycomb.v3po.translate.v3po.utils.V3poUtils;
 import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
+import java.net.InetAddress;
+import java.util.concurrent.CompletionStage;
 import javax.annotation.Nonnull;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentation;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanTunnel;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.Vxlan;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.openvpp.jvpp.dto.VxlanAddDelTunnel;
+import org.openvpp.jvpp.dto.VxlanAddDelTunnelReply;
+import org.openvpp.jvpp.future.FutureJVpp;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class VxlanCustomizer extends VppApiCustomizer implements ChildWriterCustomizer<Vxlan> {
+public class VxlanCustomizer extends FutureJVppCustomizer implements ChildWriterCustomizer<Vxlan> {
 
     private static final Logger LOG = LoggerFactory.getLogger(VxlanCustomizer.class);
+    private final NamingContext interfaceContext;
 
-
-    public VxlanCustomizer(final org.openvpp.vppjapi.vppApi vppApi) {
+    public VxlanCustomizer(final FutureJVpp vppApi, final NamingContext interfaceContext) {
         super(vppApi);
+        this.interfaceContext = interfaceContext;
     }
 
     @Nonnull
@@ -84,28 +90,39 @@ public class VxlanCustomizer extends VppApiCustomizer implements ChildWriterCust
     }
 
     private void createVxlanTunnel(final String swIfName, final Vxlan vxlan) throws VppApiInvocationException {
-        Ipv4AddressNoZone srcAddress = V3poUtils.removeIpv4AddressNoZone(vxlan.getSrc());
-        Ipv4AddressNoZone dstAddress = V3poUtils.removeIpv4AddressNoZone(vxlan.getDst());
-
-        byte[] srcAddr = V3poUtils.ipv4AddressNoZoneToArray(srcAddress);
-        byte[] dstAddr = V3poUtils.ipv4AddressNoZoneToArray(dstAddress);
+        final InetAddress srcAddress = InetAddresses.forString(vxlan.getSrc().getValue());
+        final InetAddress dstAddress = InetAddresses.forString(vxlan.getDst().getValue());
         int encapVrfId = vxlan.getEncapVrfId().intValue();
         int vni = vxlan.getVni().getValue().intValue();
 
         LOG.debug("Setting vxlan tunnel for interface: {}. Vxlan: {}", swIfName, vxlan);
-        int ctxId = 0; getVppApi().vxlanAddDelTunnel(
-                (byte) 1 /* is add */,
-                (byte) 0 /* is ipv6 */,
-                srcAddr, dstAddr, encapVrfId, -1, vni);
-        final int rv = V3poUtils.waitForResponse(ctxId, getVppApi());
-        if (rv < 0) {
+        final CompletionStage<VxlanAddDelTunnelReply> vxlanAddDelTunnelReplyCompletionStage =
+            getFutureJVpp().vxlanAddDelTunnel(getVxlanTunnelRequest((byte) 1 /* is add */, srcAddress.getAddress(),
+                dstAddress.getAddress(), encapVrfId, -1, vni, (byte) 0 /* is IPV6 */));
+
+        final VxlanAddDelTunnelReply reply =
+            V3poUtils.getReply(vxlanAddDelTunnelReplyCompletionStage.toCompletableFuture());
+        if (reply.retval < 0) {
             LOG.debug("Failed to set vxlan tunnel for interface: {}, vxlan: {}", swIfName, vxlan);
-            throw new VppApiInvocationException("vxlanAddDelTunnel", ctxId, rv);
+            throw new VppApiInvocationException("vxlanAddDelTunnel", reply.context, reply.retval);
         } else {
             LOG.debug("Vxlan tunnel set successfully for: {}, vxlan: {}", swIfName, vxlan);
-            // FIXME avoid this dump just to fill cache in vpp-japi
-            // refresh interfaces to be able to get ifIndex
-            getVppApi().swInterfaceDump((byte) 1, V3poUtils.IFC_TYPES.inverse().get(VxlanTunnel.class).getBytes());
+            // Add new interface to our interface context
+            interfaceContext.addName(reply.swIfIndex, swIfName);
         }
     }
+
+    private VxlanAddDelTunnel getVxlanTunnelRequest(final byte isAdd, final byte[] srcAddr, final byte[] dstAddr,
+                                                    final int encapVrfId,
+                                                    final int decapNextIndex, final int vni, final byte isIpv6) {
+        final VxlanAddDelTunnel vxlanAddDelTunnel = new VxlanAddDelTunnel();
+        vxlanAddDelTunnel.isAdd = isAdd;
+        vxlanAddDelTunnel.srcAddress = srcAddr;
+        vxlanAddDelTunnel.dstAddress = dstAddr;
+        vxlanAddDelTunnel.encapVrfId = encapVrfId;
+        vxlanAddDelTunnel.vni = vni;
+        vxlanAddDelTunnel.decapNextIndex = decapNextIndex;
+        vxlanAddDelTunnel.isIpv6 = isIpv6;
+        return vxlanAddDelTunnel;
+    }
 }
index 9f35849..e309294 100644 (file)
@@ -19,16 +19,17 @@ package io.fd.honeycomb.v3po.translate.v3po.interfaces.ip;
 import com.google.common.base.Optional;
 import io.fd.honeycomb.v3po.translate.Context;
 import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer;
-import io.fd.honeycomb.v3po.translate.v3po.util.VppApiCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
 import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface1;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.openvpp.jvpp.future.FutureJVpp;
 
-public class Interface1Customizer extends VppApiCustomizer implements ChildWriterCustomizer<Interface1> {
+public class Interface1Customizer extends FutureJVppCustomizer implements ChildWriterCustomizer<Interface1> {
 
-    public Interface1Customizer(final org.openvpp.vppjapi.vppApi vppApi) {
+    public Interface1Customizer(final FutureJVpp vppApi) {
         super(vppApi);
     }
 
index 8349ebb..de2015c 100644 (file)
@@ -22,10 +22,12 @@ import static com.google.common.base.Preconditions.checkNotNull;
 import com.google.common.base.Optional;
 import io.fd.honeycomb.v3po.translate.Context;
 import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer;
-import io.fd.honeycomb.v3po.translate.v3po.util.VppApiCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
+import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException;
 import io.fd.honeycomb.v3po.translate.v3po.utils.V3poUtils;
 import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
+import java.util.concurrent.CompletionStage;
 import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface1;
@@ -36,17 +38,23 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev14061
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.PrefixLength;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.openvpp.jvpp.dto.SwInterfaceAddDelAddress;
+import org.openvpp.jvpp.dto.SwInterfaceAddDelAddressReply;
+import org.openvpp.jvpp.future.FutureJVpp;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class Ipv4Customizer extends VppApiCustomizer implements ChildWriterCustomizer<Ipv4> {
+public class Ipv4Customizer extends FutureJVppCustomizer implements ChildWriterCustomizer<Ipv4> {
 
     private static final Logger LOG = LoggerFactory.getLogger(Ipv4Customizer.class);
+    private final NamingContext interfaceContext;
 
-    public Ipv4Customizer(final org.openvpp.vppjapi.vppApi vppApi) {
+    public Ipv4Customizer(final FutureJVpp vppApi, final NamingContext interfaceContext) {
         super(vppApi);
+        this.interfaceContext = interfaceContext;
     }
 
+    // TODO replace guava's Optionals with Java8
     @Nonnull
     @Override
     public Optional<Ipv4> extract(@Nonnull final InstanceIdentifier<Ipv4> currentId,
@@ -91,7 +99,7 @@ public class Ipv4Customizer extends VppApiCustomizer implements ChildWriterCusto
 
     private void setIpv4(final InstanceIdentifier<Ipv4> id, final String name, final Ipv4 ipv4)
         throws WriteFailedException, VppApiInvocationException {
-        final int swIfc = getSwIfc(name);
+        final int swIfc = interfaceContext.getIndex(name);
 
         for (Address ipv4Addr : ipv4.getAddress()) {
             Subnet subnet = ipv4Addr.getSubnet();
@@ -127,24 +135,34 @@ public class Ipv4Customizer extends VppApiCustomizer implements ChildWriterCusto
         checkArgument(plen > 0, "Invalid length");
         checkNotNull(addr, "Null address");
 
-        final int ctxId = getVppApi().swInterfaceAddDelAddress(swIfc, (byte) 1 /* isAdd */, (byte) 0 /* isIpv6 */,
-            (byte) 0 /* delAll */, plen.byteValue(), addr);
+        final CompletionStage<SwInterfaceAddDelAddressReply> swInterfaceAddDelAddressReplyCompletionStage =
+            getFutureJVpp().swInterfaceAddDelAddress(getSwInterfaceAddDelAddressRequest(
+                swIfc, (byte) 1 /* isAdd */, (byte) 0 /* isIpv6 */, (byte) 0 /* delAll */, plen.byteValue(), addr));
 
-        final int rv = V3poUtils.waitForResponse(ctxId, getVppApi());
-        if (rv < 0) {
+        final SwInterfaceAddDelAddressReply reply =
+            V3poUtils.getReply(swInterfaceAddDelAddressReplyCompletionStage.toCompletableFuture());
+
+        if (reply.retval < 0) {
             LOG.warn("Failed to set Subnet(prefix-length) for interface: {}, {},  Subnet: {}, Ipv4: {}", name, swIfc,
                 subnet, ipv4Addr);
-            throw new VppApiInvocationException("swInterfaceAddDelAddress", ctxId, rv);
+            throw new VppApiInvocationException("swInterfaceAddDelAddress", reply.context, reply.retval);
         } else {
             LOG.debug("Subnet(prefix-length) set successfully for interface: {}, {},  Subnet: {}, Ipv4: {}", name,
                 swIfc, subnet, ipv4Addr);
         }
     }
 
-
-    private int getSwIfc(final String name) {
-        int swIfcIndex = getVppApi().swIfIndexFromName(name);
-        checkArgument(swIfcIndex != -1, "Interface %s does not exist", name);
-        return swIfcIndex;
+    private SwInterfaceAddDelAddress getSwInterfaceAddDelAddressRequest(final int swIfc, final byte isAdd, final byte ipv6,
+                                                                        final byte deleteAll,
+                                                                        final byte length, final byte[] addr) {
+        final SwInterfaceAddDelAddress swInterfaceAddDelAddress = new SwInterfaceAddDelAddress();
+        swInterfaceAddDelAddress.swIfIndex = swIfc;
+        swInterfaceAddDelAddress.isAdd = isAdd;
+        swInterfaceAddDelAddress.isIpv6 = ipv6;
+        swInterfaceAddDelAddress.delAll = deleteAll;
+        swInterfaceAddDelAddress.address = addr;
+        swInterfaceAddDelAddress.addressLength = length;
+        return swInterfaceAddDelAddress;
     }
+
 }
index 3798f89..e3ad392 100644 (file)
@@ -19,20 +19,21 @@ package io.fd.honeycomb.v3po.translate.v3po.interfaces.ip;
 import com.google.common.base.Optional;
 import io.fd.honeycomb.v3po.translate.Context;
 import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer;
-import io.fd.honeycomb.v3po.translate.v3po.util.VppApiCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
 import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface1;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv6;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.openvpp.jvpp.future.FutureJVpp;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class Ipv6Customizer extends VppApiCustomizer implements ChildWriterCustomizer<Ipv6> {
+public class Ipv6Customizer extends FutureJVppCustomizer implements ChildWriterCustomizer<Ipv6> {
 
     private static final Logger LOG = LoggerFactory.getLogger(Ipv6Customizer.class);
 
-    public Ipv6Customizer(final org.openvpp.vppjapi.vppApi vppApi) {
+    public Ipv6Customizer(final FutureJVpp vppApi) {
         super(vppApi);
     }
 
index 718cef1..f7d473f 100644 (file)
@@ -19,6 +19,14 @@ package io.fd.honeycomb.v3po.translate.v3po.interfacesstate;
 import io.fd.honeycomb.v3po.translate.Context;
 import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
 import io.fd.honeycomb.v3po.translate.spi.read.ListReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
+import io.fd.honeycomb.v3po.translate.v3po.utils.V3poUtils;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Collectors;
+import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.EthernetCsmacd;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesStateBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
@@ -29,21 +37,23 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.openvpp.vppjapi.vppInterfaceDetails;
+import org.openvpp.jvpp.dto.SwInterfaceDetails;
+import org.openvpp.jvpp.dto.SwInterfaceDetailsReplyDump;
+import org.openvpp.jvpp.dto.SwInterfaceDump;
+import org.openvpp.jvpp.future.FutureJVpp;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.ArrayList;
-import java.util.List;
-
 
-public class InterfaceCustomizer extends io.fd.honeycomb.v3po.translate.v3po.util.VppApiCustomizer
+public class InterfaceCustomizer extends FutureJVppCustomizer
         implements ListReaderCustomizer<Interface, InterfaceKey, InterfaceBuilder> {
 
     private static final Logger LOG = LoggerFactory.getLogger(InterfaceCustomizer.class);
+    private final NamingContext interfaceContext;
 
-    public InterfaceCustomizer(org.openvpp.vppjapi.vppApi vppApi) {
-        super(vppApi);
+    public InterfaceCustomizer(@Nonnull final FutureJVpp jvpp, final NamingContext interfaceContext) {
+        super(jvpp);
+        this.interfaceContext = interfaceContext;
     }
 
     @Override
@@ -54,56 +64,67 @@ public class InterfaceCustomizer extends io.fd.honeycomb.v3po.translate.v3po.uti
     @Override
     public void readCurrentAttributes(InstanceIdentifier<Interface> id, InterfaceBuilder builder, Context ctx)
             throws ReadFailedException {
-        vppInterfaceDetails[] ifaces;
-
         final InterfaceKey key = id.firstKeyOf(id.getTargetType());
-        // Extract one interface detail from VPP
-        ifaces = getVppApi().swInterfaceDump((byte) 1, key.getName().getBytes());
-        if (null == ifaces) {
-            LOG.warn("VPP returned null instead of interface by key {}", key.getName().getBytes());
-            return;
-        }
 
-        if (1 != ifaces.length) {
-            LOG.error("Failed to extract interface {} details from VPP", key.getName());
-            return;
+        final SwInterfaceDetails iface;
+        try {
+            iface = InterfaceUtils.getVppInterfaceDetails(getFutureJVpp(), key);
+        } catch (Exception e) {
+            throw new ReadFailedException(id, e);
         }
 
-        final vppInterfaceDetails iface = ifaces[0];
 
-        builder.setName(iface.interfaceName);
+        builder.setName(key.getName());
         // FIXME: report interface type based on name
         //Tunnel.class l2vlan(802.1q) bridge (transparent bridge?)
         builder.setType(EthernetCsmacd.class);
-        builder.setIfIndex(InterfaceUtils.vppIfIndexToYang(iface.ifIndex));
-        builder.setAdminStatus(iface.adminUp == 1 ? AdminStatus.Up : AdminStatus.Down);
-        builder.setOperStatus(1 == iface.linkUp ? OperStatus.Up : OperStatus.Down);
+        builder.setIfIndex(InterfaceUtils.vppIfIndexToYang(iface.swIfIndex));
+        builder.setAdminStatus(iface.adminUpDown == 1
+                ? AdminStatus.Up
+                : AdminStatus.Down);
+        builder.setOperStatus(1 == iface.linkUpDown
+                ? OperStatus.Up
+                : OperStatus.Down);
         if (0 != iface.linkSpeed) {
             builder.setSpeed(InterfaceUtils.vppInterfaceSpeedToYang(iface.linkSpeed));
         }
-        if (iface.physAddr.length == 6) {
-            builder.setPhysAddress(new PhysAddress(InterfaceUtils.vppPhysAddrToYang(iface.physAddr)));
+        if (iface.l2AddressLength == 6) {
+            builder.setPhysAddress(new PhysAddress(InterfaceUtils.vppPhysAddrToYang(iface.l2Address)));
         }
     }
 
+    @Nonnull
     @Override
-    public List<InterfaceKey> getAllIds(InstanceIdentifier<Interface> id, Context context) {
-        vppInterfaceDetails[] ifaces;
-        final ArrayList<InterfaceKey> interfaceKeys = new ArrayList<>();
-
-        ifaces = getVppApi().swInterfaceDump((byte) 0, "".getBytes());
-        if (null != ifaces) {
-            for (vppInterfaceDetails ifc : ifaces) {
-                interfaceKeys.add(new InterfaceKey(ifc.interfaceName));
-            }
+    public List<InterfaceKey> getAllIds(@Nonnull final InstanceIdentifier<Interface> id,
+                                        @Nonnull final Context context) throws ReadFailedException {
+        final SwInterfaceDump request = new SwInterfaceDump();
+        request.nameFilter = "".getBytes();
+        request.nameFilterValid = 0;
+
+        final CompletableFuture<SwInterfaceDetailsReplyDump> swInterfaceDetailsReplyDumpCompletableFuture =
+                getFutureJVpp().swInterfaceDump(request).toCompletableFuture();
+        final SwInterfaceDetailsReplyDump ifaces = V3poUtils.getReply(swInterfaceDetailsReplyDumpCompletableFuture);
+
+        // TODO can we get null here?
+        if (null == ifaces || null == ifaces.swInterfaceDetails) {
+            return Collections.emptyList();
         }
 
-        return interfaceKeys;
+        return ifaces.swInterfaceDetails.stream()
+                .filter(elt -> elt != null)
+                .map((elt) -> {
+                    // Store interface name from VPP in context if not yet present
+                    if(!interfaceContext.containsName(elt.swIfIndex)){
+                        interfaceContext.addName(elt.swIfIndex, V3poUtils.toString(elt.interfaceName));
+                    }
+                    return new InterfaceKey(interfaceContext.getName(elt.swIfIndex));
+                })
+                .collect(Collectors.toList());
     }
 
     @Override
-    public void merge(org.opendaylight.yangtools.concepts.Builder<? extends DataObject> builder,
-                      List<Interface> readData) {
+    public void merge(@Nonnull final org.opendaylight.yangtools.concepts.Builder<? extends DataObject> builder,
+                      @Nonnull final  List<Interface> readData) {
         ((InterfacesStateBuilder) builder).setInterface(readData);
     }
 
index d589c25..979c9d6 100644 (file)
 
 package io.fd.honeycomb.v3po.translate.v3po.interfacesstate;
 
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Iterables;
 import java.math.BigInteger;
-
+import java.util.concurrent.ExecutionException;
 import javax.annotation.Nonnull;
-
+import javax.annotation.Nullable;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Gauge64;
-
-import com.google.common.base.Preconditions;
-import org.openvpp.vppjapi.vppApi;
-import org.openvpp.vppjapi.vppInterfaceDetails;
+import org.openvpp.jvpp.dto.SwInterfaceDetails;
+import org.openvpp.jvpp.dto.SwInterfaceDetailsReplyDump;
+import org.openvpp.jvpp.dto.SwInterfaceDump;
+import org.openvpp.jvpp.future.FutureJVpp;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -42,8 +45,7 @@ public class InterfaceUtils {
     private static final char[] HEX_CHARS = "0123456789abcdef".toCharArray();
 
     /**
-     * Convert VPP's link speed bitmask to Yang type. 1 = 10M, 2 = 100M, 4 = 1G,
-     * 8 = 10G, 16 = 40G, 32 = 100G
+     * Convert VPP's link speed bitmask to Yang type. 1 = 10M, 2 = 100M, 4 = 1G, 8 = 10G, 16 = 40G, 32 = 100G
      *
      * @param vppLinkSpeed Link speed in bitmask format from VPP.
      * @return Converted value from VPP link speed
@@ -74,16 +76,11 @@ public class InterfaceUtils {
     }
 
     /**
-     * Convert VPP's physical address stored byte array format to string as Yang
-     * dictates
-     * <p>
-     * Replace later with
-     * https://git.opendaylight.org/gerrit/#/c/34869/10/model/ietf/ietf-type-
-     * util/src/main/
+     * Convert VPP's physical address stored byte array format to string as Yang dictates <p> Replace later with
+     * https://git.opendaylight.org/gerrit/#/c/34869/10/model/ietf/ietf-type- util/src/main/
      * java/org/opendaylight/mdsal/model/ietf/util/AbstractIetfYangUtil.java
      *
-     * @param vppPhysAddress byte array of bytes constructing the network IF physical
-     *                       address.
+     * @param vppPhysAddress byte array of bytes constructing the network IF physical address.
      * @return String like "aa:bb:cc:dd:ee:ff"
      */
     public static String vppPhysAddrToYang(@Nonnull final byte[] vppPhysAddress) {
@@ -102,8 +99,8 @@ public class InterfaceUtils {
     }
 
     /**
-     * VPP's interface index is counted from 0, whereas ietf-interface's
-     * if-index is from 1. This function converts from VPP's interface index to YANG's interface index.
+     * VPP's interface index is counted from 0, whereas ietf-interface's if-index is from 1. This function converts from
+     * VPP's interface index to YANG's interface index.
      *
      * @param vppIfIndex the sw interface index VPP reported.
      * @return VPP's interface index incremented by one
@@ -115,7 +112,7 @@ public class InterfaceUtils {
     /**
      * This function does the opposite of what {@link #vppIfIndexToYang(int)} does.
      *
-     * @param yangIf if-index from ietf-interfaces.
+     * @param yangIfIndex if-index from ietf-interfaces.
      * @return VPP's representation of the if-index
      */
     public static int YangIfIndexToVpp(int yangIfIndex) {
@@ -124,25 +121,31 @@ public class InterfaceUtils {
     }
 
 
-    public static vppInterfaceDetails[] getVppInterfaceDetails(final vppApi api,
-                                                             final boolean specificInterface,
-                                                             String interfaceName) {
-        if (interfaceName == null) {
-            interfaceName = new String();
-        }
-        vppInterfaceDetails[] ifaces = api.swInterfaceDump(
-                (byte) (specificInterface ? 1 : 0),
-                interfaceName.getBytes());
-        if (null == ifaces) {
-            LOG.warn("VPP returned null instead of interface by key {}", interfaceName);
+    /**
+     * Queries VPP for interface description given interface key.
+     *
+     * @param futureJvpp VPP Java Future API
+     * @param key        interface key
+     * @return SwInterfaceDetails DTO or null if interface was not found
+     * @throws ExecutionException   if exception has been thrown while executing VPP query
+     * @throws InterruptedException if the current thread was interrupted
+     */
+    @Nullable
+    public static SwInterfaceDetails getVppInterfaceDetails(@Nonnull final FutureJVpp futureJvpp,
+                                                            @Nonnull InterfaceKey key)
+            throws ExecutionException, InterruptedException {
+        final SwInterfaceDump request = new SwInterfaceDump();
+        request.nameFilter = key.getName().getBytes();
+        request.nameFilterValid = 1;
+
+        // TODO should we use timeout?
+        SwInterfaceDetailsReplyDump ifaces = futureJvpp.swInterfaceDump(request).toCompletableFuture().get();
+        if (null == ifaces) { // TODO can we get null here?
+            LOG.warn("VPP returned null instead of interface by key {}", key.getName().getBytes());
             return null;
         }
 
-        if (1 != ifaces.length) {
-            LOG.error("Failed to extract interface {} details from VPP", interfaceName);
-        }
-
-        return ifaces;
+        return Iterables.getOnlyElement(ifaces.swInterfaceDetails);
     }
 
 
index 8e5cc89..2bc8bea 100644 (file)
 
 package io.fd.honeycomb.v3po.translate.v3po.interfacesstate;
 
-import static io.fd.honeycomb.v3po.translate.v3po.interfacesstate.InterfaceUtils.getVppInterfaceDetails;
-
 import io.fd.honeycomb.v3po.translate.Context;
 import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
 import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
 import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder;
@@ -32,28 +31,31 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev
 import org.opendaylight.yangtools.concepts.Builder;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.openvpp.vppjapi.vppInterfaceDetails;
+import org.openvpp.jvpp.dto.SwInterfaceDetails;
+import org.openvpp.jvpp.future.FutureJVpp;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 
-public class VppInterfaceStateCustomizer extends io.fd.honeycomb.v3po.translate.v3po.util.VppApiCustomizer
+public class VppInterfaceStateCustomizer extends FutureJVppCustomizer
         implements ChildReaderCustomizer<VppInterfaceStateAugmentation, VppInterfaceStateAugmentationBuilder> {
 
     private static final Logger LOG = LoggerFactory.getLogger(VppInterfaceStateCustomizer.class);
 
-    public VppInterfaceStateCustomizer(org.openvpp.vppjapi.vppApi vppApi) {
-        super(vppApi);
+    public VppInterfaceStateCustomizer(@Nonnull final FutureJVpp jvpp) {
+        super(jvpp);
     }
 
     @Override
-    public void merge(@Nonnull Builder<? extends DataObject> parentBuilder, @Nonnull VppInterfaceStateAugmentation readValue) {
+    public void merge(@Nonnull Builder<? extends DataObject> parentBuilder,
+                      @Nonnull VppInterfaceStateAugmentation readValue) {
         ((InterfaceBuilder) parentBuilder).addAugmentation(VppInterfaceStateAugmentation.class, readValue);
     }
 
     @Nonnull
     @Override
-    public VppInterfaceStateAugmentationBuilder getBuilder(@Nonnull InstanceIdentifier<VppInterfaceStateAugmentation> id) {
+    public VppInterfaceStateAugmentationBuilder getBuilder(
+            @Nonnull InstanceIdentifier<VppInterfaceStateAugmentation> id) {
         return new VppInterfaceStateAugmentationBuilder();
     }
 
@@ -63,15 +65,15 @@ public class VppInterfaceStateCustomizer extends io.fd.honeycomb.v3po.translate.
                                       @Nonnull final Context ctx) throws ReadFailedException {
 
         final InterfaceKey key = id.firstKeyOf(Interface.class);
-        vppInterfaceDetails[] ifaces = getVppInterfaceDetails(getVppApi(), true, key.getName());
-        if (null == ifaces || ifaces.length != 1) {
-            return;
+        final SwInterfaceDetails iface;
+        try {
+            iface = InterfaceUtils.getVppInterfaceDetails(getFutureJVpp(), key);
+        } catch (Exception e) {
+            throw new ReadFailedException(id, e);
         }
 
-        final vppInterfaceDetails iface = ifaces[0];
         final EthernetBuilder ethernet = new EthernetBuilder();
-
-        ethernet.setMtu(iface.linkMtu);
+        ethernet.setMtu((int) iface.linkMtu);
         switch (iface.linkDuplex) {
             case 1:
                 ethernet.setDuplex(Ethernet.Duplex.Half);
index 8862645..b4217df 100644 (file)
 
 package io.fd.honeycomb.v3po.translate.v3po.utils;
 
-import com.google.common.base.Preconditions;
 import com.google.common.base.Splitter;
 import com.google.common.collect.BiMap;
 import com.google.common.collect.HashBiMap;
-import javax.annotation.Nonnull;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.EthernetCsmacd;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.SoftwareLoopback;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanTunnel;
-import org.openvpp.vppjapi.vppApi;
+import org.openvpp.jvpp.dto.JVppReply;
 
 public final class V3poUtils {
 
@@ -48,25 +47,17 @@ public final class V3poUtils {
 
     private V3poUtils() {}
 
-    public static int waitForResponse(final int ctxId, final vppApi vppApi) {
-        int rv;
-        while ((rv = vppApi.getRetval(ctxId, RELEASE)) == RESPONSE_NOT_READY) {
-            // TODO limit attempts
+    public static <REP extends JVppReply<?>> REP getReply(Future<REP> future) {
+        try {
+            return future.get();
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            throw new IllegalStateException("Interrupted", e);
+        } catch (ExecutionException e) {
+            // Execution exception should not occur, since we are using return codes for errors
+            // TODO fix when using exceptions instead of return codes
+            throw new IllegalArgumentException("Future " + " should not fail with an exception", e);
         }
-        return rv;
-    }
-
-    public static int parseIp(final String address) {
-        int result = 0;
-
-        // iterate over each octet
-        for (String part : DOT_SPLITTER.split(address)) {
-            // shift the previously parsed bits over by 1 byte
-            result = result << 8;
-            // set the low order bits to the current octet
-            result |= Integer.parseInt(part);
-        }
-        return result;
     }
 
     public static byte[] ipv4AddressNoZoneToArray(final Ipv4AddressNoZone ipv4Addr) {
@@ -80,22 +71,10 @@ public final class V3poUtils {
     }
 
     /**
-     * Removes zone index from Ipv4Address.
-     * @param ipv4Addr ipv4 address which can contain zone index
-     * @return ipv4 address without zone index
+     * Return (interned) string from byte array while removing \u0000.
+     * Strings represented as fixed length byte[] from vpp contain \u0000.
      */
-    @Nonnull
-    public static Ipv4AddressNoZone removeIpv4AddressNoZone(@Nonnull final Ipv4Address ipv4Addr) {
-        Preconditions.checkNotNull(ipv4Addr, "ipv4Addr should not be null");
-        if (ipv4Addr instanceof Ipv4AddressNoZone) {
-            return (Ipv4AddressNoZone)ipv4Addr;
-        } else {
-            String value = ipv4Addr.getValue();
-            final int index = value.indexOf('%');
-            if (index != -1) {
-                value = value.substring(0, index);
-            }
-            return new Ipv4AddressNoZone(value);
-        }
+    public static String toString(final byte[] cString) {
+        return new String(cString).replaceAll("\\u0000", "").intern();
     }
 }
index c69f2ef..4b4d7b3 100644 (file)
@@ -18,12 +18,15 @@ package io.fd.honeycomb.v3po.translate.v3po.vpp;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
 
-import io.fd.honeycomb.v3po.translate.spi.write.ListWriterCustomizer;
-import io.fd.honeycomb.v3po.translate.v3po.util.VppApiCustomizer;
+import com.google.common.base.Preconditions;
 import io.fd.honeycomb.v3po.translate.Context;
+import io.fd.honeycomb.v3po.translate.spi.write.ListWriterCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
+import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException;
 import io.fd.honeycomb.v3po.translate.v3po.utils.V3poUtils;
+import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
 import java.util.List;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
@@ -32,19 +35,24 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomainKey;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.openvpp.jvpp.dto.BridgeDomainAddDel;
+import org.openvpp.jvpp.dto.BridgeDomainAddDelReply;
+import org.openvpp.jvpp.future.FutureJVpp;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public class BridgeDomainCustomizer
-    extends VppApiCustomizer
-    implements ListWriterCustomizer<BridgeDomain, BridgeDomainKey> {
+        extends FutureJVppCustomizer
+        implements ListWriterCustomizer<BridgeDomain, BridgeDomainKey> {
 
     private static final Logger LOG = LoggerFactory.getLogger(BridgeDomainCustomizer.class);
 
     private static final byte ADD_OR_UPDATE_BD = (byte) 1;
+    private final NamingContext bdContext;
 
-    public BridgeDomainCustomizer(final org.openvpp.vppjapi.vppApi api) {
-        super(api);
+    public BridgeDomainCustomizer(@Nonnull final FutureJVpp futureJvpp, @Nonnull final NamingContext bdContext) {
+        super(futureJvpp);
+        this.bdContext = Preconditions.checkNotNull(bdContext, "bdContext should not be null");
     }
 
     @Nonnull
@@ -54,76 +62,96 @@ public class BridgeDomainCustomizer
         return ((BridgeDomains) parentData).getBridgeDomain();
     }
 
-    private int addOrUpdateBridgeDomain(final int bdId, @Nonnull final BridgeDomain bd) {
-        byte flood = booleanToByte(bd.isFlood());
-        byte forward = booleanToByte(bd.isForward());
-        byte learn = booleanToByte(bd.isLearn());
-        byte uuf = booleanToByte(bd.isUnknownUnicastFlood());
-        byte arpTerm = booleanToByte(bd.isArpTermination());
-
-        int ctxId = getVppApi().bridgeDomainAddDel(bdId, flood, forward, learn, uuf, arpTerm, ADD_OR_UPDATE_BD);
-        return V3poUtils.waitForResponse(ctxId, getVppApi());
+    private BridgeDomainAddDelReply addOrUpdateBridgeDomain(final int bdId, @Nonnull final BridgeDomain bd)
+            throws VppApiInvocationException {
+        final BridgeDomainAddDel request = new BridgeDomainAddDel();
+        request.bdId = bdId;
+        request.flood = booleanToByte(bd.isFlood());
+        request.forward = booleanToByte(bd.isForward());
+        request.learn = booleanToByte(bd.isLearn());
+        request.uuFlood = booleanToByte(bd.isUnknownUnicastFlood());
+        request.arpTerm = booleanToByte(bd.isArpTermination());
+        request.isAdd = ADD_OR_UPDATE_BD;
+
+        final BridgeDomainAddDelReply reply =
+                V3poUtils.getReply(getFutureJVpp().bridgeDomainAddDel(request).toCompletableFuture());
+        if (reply.retval < 0) {
+            LOG.warn("Bridge domain {} (id={}) add/update failed", bd.getName(), bdId);
+            throw new VppApiInvocationException("bridgeDomainAddDel", reply.context, reply.retval);
+        } else {
+            LOG.debug("Bridge domain {} (id={}) add/update successful", bd.getName(), bdId);
+        }
+
+        return reply;
     }
 
     @Override
     public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<BridgeDomain> id,
-                                       @Nonnull final BridgeDomain current,
-                                       @Nonnull final Context ctx) {
-        LOG.debug("writeCurrentAttributes: id={}, current={}, ctx={}", id, current, ctx);
-        final String bdName = current.getName();
-        int bdId = getVppApi().findOrAddBridgeDomainId(bdName);
-        checkState(bdId > 0, "Unable to find or create bridge domain. Return code: %s", bdId);
-
-        int rv = addOrUpdateBridgeDomain(bdId, current);
-
-        checkState(rv >= 0, "Bridge domain %s(%s) write failed. Return code: %s", bdName, bdId, rv);
-        LOG.debug("Bridge domain {} written as {} successfully", bdName, bdId);
+                                       @Nonnull final BridgeDomain dataBefore,
+                                       @Nonnull final Context ctx) throws WriteFailedException.CreateFailedException {
+        LOG.debug("writeCurrentAttributes: id={}, current={}, ctx={}", id, dataBefore, ctx);
+        final String bdName = dataBefore.getName();
+
+        try {
+            // FIXME we need the bd index to be returned by VPP or we should have a counter field (maybe in context similar to artificial name)
+            // Here we assign the next available ID from bdContext's perspective
+            int index = 1;
+            while(bdContext.containsName(index)) {
+                index++;
+            }
+            addOrUpdateBridgeDomain(index, dataBefore);
+            bdContext.addName(index, bdName);
+        } catch (VppApiInvocationException e) {
+            LOG.warn("Failed to create bridge domain", e);
+            throw new WriteFailedException.CreateFailedException(id, dataBefore, e);
+        }
     }
 
     private byte booleanToByte(@Nullable final Boolean aBoolean) {
-        return aBoolean != null && aBoolean ? (byte) 1 : (byte) 0;
+        return aBoolean != null && aBoolean
+                ? (byte) 1
+                : (byte) 0;
     }
 
     @Override
     public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<BridgeDomain> id,
                                         @Nonnull final BridgeDomain dataBefore,
-                                        @Nonnull final Context ctx) {
+                                        @Nonnull final Context ctx) throws WriteFailedException.DeleteFailedException {
         LOG.debug("deleteCurrentAttributes: id={}, dataBefore={}, ctx={}", id, dataBefore, ctx);
-        String bdName = id.firstKeyOf(BridgeDomain.class).getName();
-
-        int bdId = getVppApi().bridgeDomainIdFromName(bdName);
-        checkState(bdId > 0, "Unable to delete bridge domain. Does not exist. Return code: %s", bdId);
 
-        int ctxId = getVppApi().bridgeDomainAddDel(bdId,
-            (byte) 0 /* flood */,
-            (byte) 0 /* forward */,
-            (byte) 0 /* learn */,
-            (byte) 0 /* uuf */,
-            (byte) 0 /* arpTerm */,
-            (byte) 0 /* isAdd */);
-
-        int rv = V3poUtils.waitForResponse(ctxId, getVppApi());
-
-        checkState(rv >= 0, "Bridge domain delete failed. Return code: %s", rv);
-        LOG.debug("Bridge domain {} deleted as {} successfully", bdName, bdId);
+        final String bdName = id.firstKeyOf(BridgeDomain.class).getName();
+        int bdId = bdContext.getIndex(bdName);
+        final BridgeDomainAddDel request = new BridgeDomainAddDel();
+        request.bdId = bdId;
+
+        final BridgeDomainAddDelReply reply =
+                V3poUtils.getReply(getFutureJVpp().bridgeDomainAddDel(request).toCompletableFuture());
+        if (reply.retval < 0) {
+            LOG.warn("Bridge domain {} (id={}) delete failed", bdName, bdId);
+            throw new WriteFailedException.DeleteFailedException(id,
+                    new VppApiInvocationException("bridgeDomainAddDel", reply.context, reply.retval));
+        } else {
+            LOG.debug("Bridge domain {} (id={}) deleted successfully", bdName, bdId);
+        }
     }
 
     @Override
     public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<BridgeDomain> id,
                                         @Nonnull final BridgeDomain dataBefore, @Nonnull final BridgeDomain dataAfter,
-                                        @Nonnull final Context ctx) {
-        LOG.debug("updateCurrentAttributes: id={}, dataBefore={}, dataAfter={}, ctx={}", id, dataBefore, dataAfter, ctx);
+                                        @Nonnull final Context ctx) throws WriteFailedException.UpdateFailedException {
+        LOG.debug("updateCurrentAttributes: id={}, dataBefore={}, dataAfter={}, ctx={}", id, dataBefore, dataAfter,
+                ctx);
 
         final String bdName = checkNotNull(dataAfter.getName());
-        checkArgument(bdName.equals(dataBefore.getName()), "BridgeDomain name changed. It should be deleted and then created.");
-
-        int bdId = getVppApi().bridgeDomainIdFromName(bdName);
-        checkState(bdId > 0, "Unable to find bridge domain. Return code: %s", bdId);
-
-        final int rv = addOrUpdateBridgeDomain(bdId, dataAfter);
-
-        checkState(rv >= 0, "Bridge domain %s(%s) update failed. Return code: %s", bdName, bdId, rv);
-        LOG.debug("Bridge domain {}({}) updated successfully", bdName, bdId);
+        checkArgument(bdName.equals(dataBefore.getName()),
+                "BridgeDomain name changed. It should be deleted and then created.");
+
+        try {
+            addOrUpdateBridgeDomain(bdContext.getIndex(bdName), dataAfter);
+        } catch (VppApiInvocationException e) {
+            LOG.warn("Failed to create bridge domain", e);
+            throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, e);
+        }
     }
 
 }
index 61c345b..addb425 100644 (file)
 
 package io.fd.honeycomb.v3po.translate.v3po.vppstate;
 
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
-import io.fd.honeycomb.v3po.translate.spi.read.ListReaderCustomizer;
-import io.fd.honeycomb.v3po.translate.v3po.util.VppApiCustomizer;
+import com.google.common.primitives.Longs;
 import io.fd.honeycomb.v3po.translate.Context;
+import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
+import io.fd.honeycomb.v3po.translate.spi.read.ListReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -34,104 +39,150 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.bridge.domain.InterfaceKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.bridge.domain.L2Fib;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.bridge.domain.L2FibBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.bridge.domain.L2FibKey;
 import org.opendaylight.yangtools.concepts.Builder;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.openvpp.vppjapi.vppBridgeDomainDetails;
-import org.openvpp.vppjapi.vppBridgeDomainInterfaceDetails;
-import org.openvpp.vppjapi.vppL2Fib;
+import org.openvpp.jvpp.dto.BridgeDomainDetails;
+import org.openvpp.jvpp.dto.BridgeDomainDetailsReplyDump;
+import org.openvpp.jvpp.dto.BridgeDomainDump;
+import org.openvpp.jvpp.dto.BridgeDomainSwIfDetails;
+import org.openvpp.jvpp.dto.L2FibTableDump;
+import org.openvpp.jvpp.dto.L2FibTableEntry;
+import org.openvpp.jvpp.dto.L2FibTableEntryReplyDump;
+import org.openvpp.jvpp.future.FutureJVpp;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public final class BridgeDomainCustomizer extends VppApiCustomizer
-    implements ListReaderCustomizer<BridgeDomain, BridgeDomainKey, BridgeDomainBuilder> {
+public final class BridgeDomainCustomizer extends FutureJVppCustomizer
+        implements ListReaderCustomizer<BridgeDomain, BridgeDomainKey, BridgeDomainBuilder> {
 
     private static final Logger LOG = LoggerFactory.getLogger(BridgeDomainCustomizer.class);
-
-    public BridgeDomainCustomizer(@Nonnull final org.openvpp.vppjapi.vppApi vppApi) {
-        super(vppApi);
+    private final NamingContext bdContext;
+    private final NamingContext interfaceContext;
+
+    public BridgeDomainCustomizer(@Nonnull final FutureJVpp futureJVpp, @Nonnull final NamingContext bdContext,
+                                  @Nonnull final NamingContext interfaceContext) {
+        super(futureJVpp);
+        this.bdContext = Preconditions.checkNotNull(bdContext, "bdContext should not be null");
+        this.interfaceContext = Preconditions.checkNotNull(interfaceContext, "interfaceContext should not be null");;
     }
 
     @Override
     public void readCurrentAttributes(@Nonnull final InstanceIdentifier<BridgeDomain> id,
-                                      @Nonnull final BridgeDomainBuilder builder, @Nonnull final Context context) {
+                                      @Nonnull final BridgeDomainBuilder builder, @Nonnull final Context context)
+            throws ReadFailedException {
         LOG.debug("vppstate.BridgeDomainCustomizer.readCurrentAttributes: id={}, builderbuilder={}, context={}",
                 id, builder, context);
 
         final BridgeDomainKey key = id.firstKeyOf(id.getTargetType());
         LOG.debug("vppstate.BridgeDomainCustomizer.readCurrentAttributes: key={}", key);
 
-        final int bdId = getVppApi().bridgeDomainIdFromName(key.getName());
+        final int bdId = bdContext.getIndex(key.getName());
         LOG.debug("vppstate.BridgeDomainCustomizer.readCurrentAttributes: bdId={}", bdId);
 
-        final vppBridgeDomainDetails bridgeDomainDetails = getVppApi().getBridgeDomainDetails(bdId);
-        if(bridgeDomainDetails == null) {
-            LOG.debug("Bridge domain name={} does not exist", key.getName());
+        BridgeDomainDetailsReplyDump reply;
+        BridgeDomainDetails bridgeDomainDetails;
+        final BridgeDomainDump request = new BridgeDomainDump();
+        request.bdId = bdContext.getIndex(key.getName());
+        try {
+            reply = getFutureJVpp().bridgeDomainDump(request).toCompletableFuture().get();
+            bridgeDomainDetails = Iterables.getOnlyElement(reply.bridgeDomainDetails);
+        } catch (Exception e) {
+            LOG.debug("Unable to read bridge domain: {}", key.getName(), e);
             return;
         }
+
         logBridgeDomainDetails(bridgeDomainDetails);
 
         builder.setName(key.getName());
-        // builder.setName(bridgeDomainDetails.name);
-        builder.setArpTermination(bridgeDomainDetails.arpTerm);
-        builder.setFlood(bridgeDomainDetails.flood);
-        builder.setForward(bridgeDomainDetails.forward);
-        builder.setLearn(bridgeDomainDetails.learn);
-        builder.setUnknownUnicastFlood(bridgeDomainDetails.uuFlood);
-
-        builder.setInterface(getIfcs(bridgeDomainDetails));
-
-        final vppL2Fib[] vppL2Fibs = getVppApi().l2FibTableDump(bdId);
-
-        final List<L2Fib> l2Fibs = Lists.newArrayListWithCapacity(vppL2Fibs.length);
-        for (vppL2Fib vppL2Fib : vppL2Fibs) {
-            l2Fibs.add(new L2FibBuilder()
-                .setAction((vppL2Fib.filter
-                    ? L2Fib.Action.Filter
-                    : L2Fib.Action.Forward))
-                .setBridgedVirtualInterface(vppL2Fib.bridgedVirtualInterface)
-                .setOutgoingInterface(vppL2Fib.outgoingInterface)
-                .setPhysAddress(new PhysAddress(getMacAddress(vppL2Fib.physAddress)))
-                .setStaticConfig(vppL2Fib.staticConfig)
-                .build());
+        builder.setArpTermination(byteToBoolean(bridgeDomainDetails.arpTerm));
+        builder.setFlood(byteToBoolean(bridgeDomainDetails.flood));
+        builder.setForward(byteToBoolean(bridgeDomainDetails.forward));
+        builder.setLearn(byteToBoolean(bridgeDomainDetails.learn));
+        builder.setUnknownUnicastFlood(byteToBoolean(bridgeDomainDetails.uuFlood));
+
+        builder.setInterface(getIfcs(bridgeDomainDetails, reply.bridgeDomainSwIfDetails));
+
+        final L2FibTableDump l2FibRequest = new L2FibTableDump();
+        l2FibRequest.bdId = bdId;
+        try {
+            final L2FibTableEntryReplyDump dump =
+                    getFutureJVpp().l2FibTableDump(l2FibRequest).toCompletableFuture().get();
+            final List<L2Fib> l2Fibs = Lists.newArrayListWithCapacity(dump.l2FibTableEntry.size());
+            for (L2FibTableEntry entry : dump.l2FibTableEntry) {
+                // entry.mac is a long value in the format 66:55:44:33:22:11:XX:XX
+                // where mac address is 11:22:33:44:55:66
+                final PhysAddress address = new PhysAddress(getMacAddress(Longs.toByteArray(entry.mac)));
+                l2Fibs.add(new L2FibBuilder()
+                        .setAction((byteToBoolean(entry.filterMac)
+                                ? L2Fib.Action.Filter
+                                : L2Fib.Action.Forward))
+                        .setBridgedVirtualInterface(byteToBoolean(entry.bviMac))
+                        .setOutgoingInterface(interfaceContext.getName(entry.swIfIndex))
+                        .setStaticConfig(byteToBoolean(entry.staticMac))
+                        .setPhysAddress(address)
+                        .setKey(new L2FibKey(address))
+                        .build());
+            }
+            builder.setL2Fib(l2Fibs);
+
+        } catch (Exception e) {
+            LOG.warn("Failed to acquire l2FibTableDump for domain id={}", bdId, e);
+        }
+    }
+
+    // TODO move to utils
+    private static Boolean byteToBoolean(final byte aByte) {
+        if (aByte == 0) {
+            return Boolean.FALSE;
+        } else if (aByte == 1) {
+            return Boolean.TRUE;
         }
-        builder.setL2Fib(l2Fibs);
+        throw new IllegalArgumentException(String.format("0 or 1 was expected but was %d", aByte));
     }
 
-    private void logBridgeDomainDetails(final vppBridgeDomainDetails bridgeDomainDetails) {
+    private void logBridgeDomainDetails(final BridgeDomainDetails bridgeDomainDetails) {
         LOG.debug("bridgeDomainDetails={}", bridgeDomainDetails);
         if (bridgeDomainDetails != null) {
             LOG.debug("bridgeDomainDetails.arpTerm={}", bridgeDomainDetails.arpTerm);
             LOG.debug("bridgeDomainDetails.bdId={}", bridgeDomainDetails.bdId);
-            LOG.debug("bridgeDomainDetails.bviInterfaceName={}", bridgeDomainDetails.bviInterfaceName);
+            LOG.debug("bridgeDomainDetails.bviSwIfIndex={}", bridgeDomainDetails.bviSwIfIndex);
             LOG.debug("bridgeDomainDetails.flood={}", bridgeDomainDetails.flood);
             LOG.debug("bridgeDomainDetails.forward={}", bridgeDomainDetails.forward);
             LOG.debug("bridgeDomainDetails.learn={}", bridgeDomainDetails.learn);
-            LOG.debug("bridgeDomainDetails.name={}", bridgeDomainDetails.name);
+            LOG.debug("bridgeDomainDetails.nSwIfs={}", bridgeDomainDetails.nSwIfs);
             LOG.debug("bridgeDomainDetails.uuFlood={}", bridgeDomainDetails.uuFlood);
         }
     }
 
-
+    // TODO move to some utility class
     private static String getMacAddress(byte[] mac) {
         StringBuilder sb = new StringBuilder(18);
-        for (byte b : mac) {
+        for (int i=5; i>=0; --i) {
             if (sb.length() > 0) {
                 sb.append(':');
             }
-            sb.append(String.format("%02x", b));
+            sb.append(String.format("%02x", mac[i]));
         }
         return sb.toString();
     }
 
-    private List<Interface> getIfcs(final vppBridgeDomainDetails bridgeDomainDetails) {
-        final List<Interface> ifcs = new ArrayList<>(bridgeDomainDetails.interfaces.length);
-        for (vppBridgeDomainInterfaceDetails anInterface : bridgeDomainDetails.interfaces) {
-            ifcs.add(new InterfaceBuilder()
-                .setBridgedVirtualInterface(bridgeDomainDetails.bviInterfaceName.equals(anInterface.interfaceName))
-                .setName(anInterface.interfaceName)
-                .setKey(new InterfaceKey(anInterface.interfaceName))
-                .build());
+    private List<Interface> getIfcs(final BridgeDomainDetails bridgeDomainDetails,
+                                    final List<BridgeDomainSwIfDetails> bridgeDomainSwIfDetails) {
+        final List<Interface> ifcs = new ArrayList<>(bridgeDomainSwIfDetails.size());
+        for (BridgeDomainSwIfDetails anInterface : bridgeDomainSwIfDetails) {
+            final String interfaceName = interfaceContext.getName(anInterface.swIfIndex);
+            if (anInterface.bdId == bridgeDomainDetails.bdId) {
+                ifcs.add(new InterfaceBuilder()
+                        .setBridgedVirtualInterface(bridgeDomainDetails.bviSwIfIndex == anInterface.swIfIndex)
+                        .setSplitHorizonGroup((short) anInterface.shg)
+                        .setName(interfaceName)
+                        .setKey(new InterfaceKey(interfaceName))
+                        .build());
+            }
+
+
         }
         return ifcs;
     }
@@ -144,25 +195,34 @@ public final class BridgeDomainCustomizer extends VppApiCustomizer
 
     @Nonnull
     @Override
-    public List<BridgeDomainKey> getAllIds(@Nonnull final InstanceIdentifier<BridgeDomain> id, @Nonnull final Context context) {
-        final int[] bIds = getVppApi().bridgeDomainDump(-1);
+    public List<BridgeDomainKey> getAllIds(@Nonnull final InstanceIdentifier<BridgeDomain> id,
+                                           @Nonnull final Context context) {
+        final BridgeDomainDump request = new BridgeDomainDump();
+        request.bdId = -1; // dump call
+
+        BridgeDomainDetailsReplyDump reply;
+        try {
+            reply = getFutureJVpp().bridgeDomainDump(request).toCompletableFuture().get();
+        } catch (Exception e) {
+            throw new IllegalStateException("Bridge domain dump failed", e); // TODO ReadFailedException?
+        }
 
-        if(bIds == null) {
+        if(reply == null || reply.bridgeDomainDetails == null) {
+            return Collections.emptyList();
+        }
+
+        final int bIdsLength = reply.bridgeDomainDetails.size();
+        LOG.debug("vppstate.BridgeDomainCustomizer.getAllIds: bIds.length={}", bIdsLength);
+        if (bIdsLength == 0) {
             // No bridge domains
             return Collections.emptyList();
         }
 
-        LOG.debug("vppstate.BridgeDomainCustomizer.getAllIds: bIds.length={}", bIds.length);
-        final List<BridgeDomainKey> allIds = new ArrayList<>(bIds.length);
-        for (int bId : bIds) {
-            LOG.debug("vppstate.BridgeDomainCustomizer.getAllIds: bId={}", bId);
-            // FIXME this is highly inefficient having to dump all of the bridge domain details
-            // Use context to store already read information
-            // TODO Or just remove the getAllIds method and replace with a simple readAll
-            final vppBridgeDomainDetails bridgeDomainDetails = getVppApi().getBridgeDomainDetails(bId);
-            logBridgeDomainDetails(bridgeDomainDetails);
-
-            final String bName = bridgeDomainDetails.name;
+        final List<BridgeDomainKey> allIds = new ArrayList<>(bIdsLength);
+        for (BridgeDomainDetails detail : reply.bridgeDomainDetails) {
+            logBridgeDomainDetails(detail);
+
+            final String bName = bdContext.getName(detail.bdId);
             LOG.debug("vppstate.BridgeDomainCustomizer.getAllIds: bName={}", bName);
             allIds.add(new BridgeDomainKey(bName));
         }
@@ -171,7 +231,8 @@ public final class BridgeDomainCustomizer extends VppApiCustomizer
     }
 
     @Override
-    public void merge(@Nonnull final Builder<? extends DataObject> builder, @Nonnull final List<BridgeDomain> readData) {
+    public void merge(@Nonnull final Builder<? extends DataObject> builder,
+                      @Nonnull final List<BridgeDomain> readData) {
         ((BridgeDomainsBuilder) builder).setBridgeDomain(readData);
     }
 }
index 31e3166..1db8217 100644 (file)
 package io.fd.honeycomb.v3po.translate.v3po.vppstate;
 
 import io.fd.honeycomb.v3po.translate.Context;
-import io.fd.honeycomb.v3po.translate.v3po.util.VppApiCustomizer;
+import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
 import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.utils.V3poUtils;
 import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppStateBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.Version;
@@ -26,14 +28,16 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev
 import org.opendaylight.yangtools.concepts.Builder;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.openvpp.vppjapi.vppVersion;
+import org.openvpp.jvpp.dto.ShowVersion;
+import org.openvpp.jvpp.dto.ShowVersionReply;
+import org.openvpp.jvpp.future.FutureJVpp;
 
 public final class VersionCustomizer
-    extends VppApiCustomizer
+    extends FutureJVppCustomizer
     implements ChildReaderCustomizer<Version, VersionBuilder> {
 
-    public VersionCustomizer(@Nonnull final org.openvpp.vppjapi.vppApi vppApi) {
-        super(vppApi);
+    public VersionCustomizer(@Nonnull final FutureJVpp futureJVpp) {
+        super(futureJVpp);
     }
 
     @Override
@@ -49,11 +53,18 @@ public final class VersionCustomizer
 
     @Override
     public void readCurrentAttributes(@Nonnull InstanceIdentifier<Version> id, @Nonnull final VersionBuilder builder,
-                                      @Nonnull final Context context) {
-        final vppVersion vppVersion = getVppApi().getVppVersion();
-        builder.setBranch(vppVersion.gitBranch);
-        builder.setName(vppVersion.programName);
-        builder.setBuildDate(vppVersion.buildDate);
-        builder.setBuildDirectory(vppVersion.buildDirectory);
+                                      @Nonnull final Context context) throws ReadFailedException {
+
+        ShowVersionReply reply;
+        try {
+            reply = getFutureJVpp().showVersion(new ShowVersion()).toCompletableFuture().get();
+        } catch (Exception e) {
+            throw new ReadFailedException(id, e);
+        }
+        builder.setBranch(V3poUtils.toString(reply.version));
+        builder.setName(V3poUtils.toString(reply.program));
+        builder.setBuildDate(V3poUtils.toString(reply.buildDate));
+        builder.setBuildDirectory(V3poUtils.toString(reply.buildDirectory));
     }
+
 }
index e906167..769589b 100644 (file)
@@ -54,9 +54,9 @@ public class InterfacesHoneycombWriterModule extends org.opendaylight.yang.gen.v
         ifcAugmentations.add(getInterface1AugmentationWriter());
 
         final ChildWriter<Interface> interfaceWriter = new CompositeListWriter<>(Interface.class,
-            RWUtils.<Interface>emptyChildWriterList(),
+            RWUtils.emptyChildWriterList(),
             ifcAugmentations,
-            new InterfaceCustomizer(getVppJapiIfcDependency()),
+            new InterfaceCustomizer(getVppJvppIfcDependency(), getInterfaceContextDependency()),
             // It's important that this customizer is handled in a postorder way, because you first have to handle child nodes
             // e.g. Vxlan before setting other interface or vppInterfaceAugmentation leaves
             TraversalType.POSTORDER);
@@ -68,36 +68,36 @@ public class InterfacesHoneycombWriterModule extends org.opendaylight.yang.gen.v
         // we loose the ordering information for root writers
         // Or can we rely to the order in which readers are configured ?
         return new CloseableWriter<>(new CompositeRootWriter<>(Interfaces.class,
-            childWriters, new NoopWriterCustomizer<Interfaces>()));
+            childWriters, new NoopWriterCustomizer<>()));
     }
 
     private ChildWriter<? extends Augmentation<Interface>> getInterface1AugmentationWriter() {
         final ChildWriter<Ipv4> ipv4Writer = new CompositeChildWriter<>(Ipv4.class,
-            new Ipv4Customizer(getVppJapiIfcDependency()));
+            new Ipv4Customizer(getVppJvppIfcDependency(), getInterfaceContextDependency()));
         final ChildWriter<Ipv6> ipv6Writer = new CompositeChildWriter<>(Ipv6.class,
-            new Ipv6Customizer(getVppJapiIfcDependency()));
+            new Ipv6Customizer(getVppJvppIfcDependency()));
 
         final List<ChildWriter<? extends ChildOf<Interface1>>> interface1ChildWriters = Lists.newArrayList();
         interface1ChildWriters.add(ipv4Writer);
         interface1ChildWriters.add(ipv6Writer);
 
         return new CompositeChildWriter<>(Interface1.class,
-            interface1ChildWriters, new ReflexiveAugmentWriterCustomizer<Interface1>());
+            interface1ChildWriters, new ReflexiveAugmentWriterCustomizer<>());
     }
 
     private ChildWriter<VppInterfaceAugmentation> getVppIfcAugmentationWriter() {
 
         final ChildWriter<Ethernet> ethernetWriter = new CompositeChildWriter<>(Ethernet.class,
-            new EthernetCustomizer(getVppJapiIfcDependency()));
+            new EthernetCustomizer(getVppJvppIfcDependency()));
 
         final ChildWriter<Routing> routingWriter = new CompositeChildWriter<>(Routing.class,
-            new RoutingCustomizer(getVppJapiIfcDependency()));
+            new RoutingCustomizer(getVppJvppIfcDependency(), getInterfaceContextDependency()));
 
         final ChildWriter<Vxlan> vxlanWriter = new CompositeChildWriter<>(Vxlan.class,
-            new VxlanCustomizer(getVppJapiIfcDependency()));
+            new VxlanCustomizer(getVppJvppIfcDependency(), getInterfaceContextDependency()));
 
         final ChildWriter<L2> l2Writer = new CompositeChildWriter<>(L2.class,
-            new L2Customizer(getVppJapiIfcDependency()));
+            new L2Customizer(getVppJvppIfcDependency(), getInterfaceContextDependency(), getBridgeDomainContextDependency()));
 
         final List<ChildWriter<? extends ChildOf<VppInterfaceAugmentation>>> vppIfcChildWriters = Lists.newArrayList();
         // TODO what's the order here ?
@@ -108,7 +108,7 @@ public class InterfacesHoneycombWriterModule extends org.opendaylight.yang.gen.v
 
         return new CompositeChildWriter<>(VppInterfaceAugmentation.class,
             vppIfcChildWriters,
-            RWUtils.<VppInterfaceAugmentation>emptyAugWriterList(),
-            new ReflexiveAugmentWriterCustomizer<VppInterfaceAugmentation>());
+            RWUtils.emptyAugWriterList(),
+            new ReflexiveAugmentWriterCustomizer<>());
     }
 }
index aa72a29..e753cf5 100644 (file)
@@ -1,10 +1,15 @@
 package org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.v3po2vpp.rev160406;
 
+
+import static io.fd.honeycomb.v3po.translate.util.RWUtils.emptyAugReaderList;
+import static io.fd.honeycomb.v3po.translate.util.RWUtils.emptyChildReaderList;
+import static io.fd.honeycomb.v3po.translate.util.RWUtils.singletonAugReaderList;
+import static io.fd.honeycomb.v3po.translate.util.RWUtils.singletonChildReaderList;
+
 import io.fd.honeycomb.v3po.translate.impl.read.CompositeChildReader;
 import io.fd.honeycomb.v3po.translate.impl.read.CompositeListReader;
 import io.fd.honeycomb.v3po.translate.impl.read.CompositeRootReader;
 import io.fd.honeycomb.v3po.translate.read.ChildReader;
-import io.fd.honeycomb.v3po.translate.util.RWUtils;
 import io.fd.honeycomb.v3po.translate.util.read.CloseableReader;
 import io.fd.honeycomb.v3po.translate.util.read.ReflexiveRootReaderCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.interfacesstate.InterfaceCustomizer;
@@ -15,14 +20,18 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceStateAugmentation;
-import org.openvpp.vppjapi.vppApi;
 
-public class InterfacesStateHoneycombReaderModule extends org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.v3po2vpp.rev160406.AbstractInterfacesStateHoneycombReaderModule {
-    public InterfacesStateHoneycombReaderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+public class InterfacesStateHoneycombReaderModule extends
+    org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.v3po2vpp.rev160406.AbstractInterfacesStateHoneycombReaderModule {
+    public InterfacesStateHoneycombReaderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+                                                org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
         super(identifier, dependencyResolver);
     }
 
-    public InterfacesStateHoneycombReaderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.v3po2vpp.rev160406.InterfacesStateHoneycombReaderModule oldModule, java.lang.AutoCloseable oldInstance) {
+    public InterfacesStateHoneycombReaderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+                                                org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,
+                                                org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.v3po2vpp.rev160406.InterfacesStateHoneycombReaderModule oldModule,
+                                                java.lang.AutoCloseable oldInstance) {
         super(identifier, dependencyResolver, oldModule, oldInstance);
     }
 
@@ -33,22 +42,22 @@ public class InterfacesStateHoneycombReaderModule extends org.opendaylight.yang.
 
     @Override
     public java.lang.AutoCloseable createInstance() {
-        final vppApi vppApi = getVppJapiDependency();
 
         final ChildReader<VppInterfaceStateAugmentation> vppInterfaceStateAugmentationChildReader =
-                new CompositeChildReader<>(VppInterfaceStateAugmentation.class,
-                        new VppInterfaceStateCustomizer(vppApi));
+            new CompositeChildReader<>(VppInterfaceStateAugmentation.class,
+                new VppInterfaceStateCustomizer(getVppJvppDependency()));
+
 
         final CompositeListReader<Interface, InterfaceKey, InterfaceBuilder> interfaceReader =
-                new CompositeListReader<>(Interface.class,
-                        RWUtils.<Interface>emptyChildReaderList(),
-                        RWUtils.<Interface>singletonAugReaderList(vppInterfaceStateAugmentationChildReader),
-                        new InterfaceCustomizer(vppApi));
+            new CompositeListReader<>(Interface.class,
+                emptyChildReaderList(),
+                singletonAugReaderList(vppInterfaceStateAugmentationChildReader),
+                new InterfaceCustomizer(getVppJvppDependency(), getInterfaceContextIfcStateDependency()));
 
         return new CloseableReader<>(new CompositeRootReader<>(
-                InterfacesState.class,
-                RWUtils.singletonChildReaderList(interfaceReader),
-                RWUtils.<InterfacesState>emptyAugReaderList(),
-                new ReflexiveRootReaderCustomizer<>(InterfacesStateBuilder.class)));
+            InterfacesState.class,
+            singletonChildReaderList(interfaceReader),
+            emptyAugReaderList(),
+            new ReflexiveRootReaderCustomizer<>(InterfacesStateBuilder.class)));
     }
 }
index a9eff59..69c1bfc 100644 (file)
@@ -35,20 +35,20 @@ public class VppHoneycombWriterModule extends org.opendaylight.yang.gen.v1.urn.h
     public java.lang.AutoCloseable createInstance() {
         final CompositeListWriter<BridgeDomain, BridgeDomainKey> bridgeDomainWriter = new CompositeListWriter<>(
             BridgeDomain.class,
-            new BridgeDomainCustomizer(getVppJapiWriterDependency()));
+            new BridgeDomainCustomizer(getVppJvppWriterDependency(), getBridgeDomainContextVppDependency()));
 
-        final ChildWriter<BridgeDomains> bridgeDomainsReader = new CompositeChildWriter<>(
+        final ChildWriter<BridgeDomains> bridgeDomainsWriter = new CompositeChildWriter<>(
             BridgeDomains.class,
             RWUtils.singletonChildWriterList(bridgeDomainWriter),
-            new ReflexiveChildWriterCustomizer<BridgeDomains>());
+            new ReflexiveChildWriterCustomizer<>());
 
         final List<ChildWriter<? extends ChildOf<Vpp>>> childWriters = new ArrayList<>();
-        childWriters.add(bridgeDomainsReader);
+        childWriters.add(bridgeDomainsWriter);
 
         return new CloseableWriter<>(new CompositeRootWriter<>(
             Vpp.class,
             childWriters,
-            new NoopWriterCustomizer<Vpp>()));
+            new NoopWriterCustomizer<>()));
     }
 
 }
index 0e1d480..9a01655 100644 (file)
@@ -21,7 +21,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomainBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomainKey;
 import org.opendaylight.yangtools.yang.binding.ChildOf;
-import org.openvpp.vppjapi.vppApi;
+import org.openvpp.jvpp.future.FutureJVpp;
 
 public class VppStateHoneycombReaderModule extends org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.v3po2vpp.rev160406.AbstractVppStateHoneycombReaderModule {
     public VppStateHoneycombReaderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
@@ -39,12 +39,13 @@ public class VppStateHoneycombReaderModule extends org.opendaylight.yang.gen.v1.
 
     @Override
     public java.lang.AutoCloseable createInstance() {
-        final vppApi vppApi = getVppJapiDependency();
+        final FutureJVpp vppApi = getVppJvppDependency();
 
         final ChildReader<Version> versionReader = new CompositeChildReader<>(Version.class, new VersionCustomizer(vppApi));
 
         final CompositeListReader<BridgeDomain, BridgeDomainKey, BridgeDomainBuilder> bridgeDomainReader =
-            new CompositeListReader<>(BridgeDomain.class, new BridgeDomainCustomizer(vppApi));
+            new CompositeListReader<>(BridgeDomain.class, new BridgeDomainCustomizer(vppApi,
+                getBridgeDomainContextVppStateDependency(), getInterfaceContextVppStateDependency()));
 
         final ChildReader<BridgeDomains> bridgeDomainsReader = new CompositeChildReader<>(
             BridgeDomains.class,
@@ -58,8 +59,7 @@ public class VppStateHoneycombReaderModule extends org.opendaylight.yang.gen.v1.
         return new CloseableReader<>(new CompositeRootReader<>(
             VppState.class,
             childVppReaders,
-            RWUtils.<VppState>emptyAugReaderList(),
+            RWUtils.emptyAugReaderList(),
             new ReflexiveRootReaderCustomizer<>(VppStateBuilder.class)));
     }
-
 }
index 286feb9..2687394 100644 (file)
@@ -5,7 +5,8 @@ module v3po2vpp {
 
     import config { prefix config; revision-date 2013-04-05; }
     import translate-api { prefix tapi; revision-date 2016-04-06; }
-    import vpp-japi-cfg { prefix vjc; revision-date 2016-04-06; }
+    import vpp-jvpp-cfg { prefix vjvppc; revision-date 2016-04-06; }
+    import vpp-util { prefix vpp-u; revision-date 2016-04-06; }
 
     description
         "This module contains reads and writers for v3po yang model";
@@ -24,15 +25,32 @@ module v3po2vpp {
         case vpp-state-honeycomb-reader {
             when "/config:modules/config:module/config:type = 'vpp-state-honeycomb-reader'";
 
-            container vpp-japi {
+            container vpp-jvpp {
                 uses config:service-ref {
                     refine type {
                         mandatory true;
-                        config:required-identity vjc:vpp-japi;
+                        config:required-identity vjvppc:vpp-jvpp;
                     }
                 }
             }
 
+            container interface-context-vpp-state {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity vpp-u:naming-context;
+                    }
+                }
+            }
+
+            container bridge-domain-context-vpp-state {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity vpp-u:naming-context;
+                    }
+                }
+            }
         }
     }
 
@@ -45,11 +63,29 @@ module v3po2vpp {
         case interfaces-state-honeycomb-reader {
             when "/config:modules/config:module/config:type = 'interfaces-state-honeycomb-reader'";
 
-            container vpp-japi {
+            container vpp-jvpp {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity vjvppc:vpp-jvpp;
+                    }
+                }
+            }
+
+            container interface-context-ifc-state {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity vpp-u:naming-context;
+                    }
+                }
+            }
+
+            container bridge-domain-context-ifc-state {
                 uses config:service-ref {
                     refine type {
                         mandatory true;
-                        config:required-identity vjc:vpp-japi;
+                        config:required-identity vpp-u:naming-context;
                     }
                 }
             }
@@ -67,15 +103,32 @@ module v3po2vpp {
         case vpp-honeycomb-writer {
             when "/config:modules/config:module/config:type = 'vpp-honeycomb-writer'";
 
-            container vpp-japi-writer {
+            container vpp-jvpp-writer {
                 uses config:service-ref {
                     refine type {
                         mandatory true;
-                        config:required-identity vjc:vpp-japi;
+                        config:required-identity vjvppc:vpp-jvpp;
                     }
                 }
             }
 
+            container interface-context-vpp {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity vpp-u:naming-context;
+                    }
+                }
+            }
+
+            container bridge-domain-context-vpp {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity vpp-u:naming-context;
+                    }
+                }
+            }
         }
     }
 
@@ -88,11 +141,29 @@ module v3po2vpp {
         case interfaces-honeycomb-writer {
             when "/config:modules/config:module/config:type = 'interfaces-honeycomb-writer'";
 
-            container vpp-japi-ifc {
+            container vpp-jvpp-ifc {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity vjvppc:vpp-jvpp;
+                    }
+                }
+            }
+
+            container interface-context {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity vpp-u:naming-context;
+                    }
+                }
+            }
+
+            container bridge-domain-context {
                 uses config:service-ref {
                     refine type {
                         mandatory true;
-                        config:required-identity vjc:vpp-japi;
+                        config:required-identity vpp-u:naming-context;
                     }
                 }
             }
index 111d813..7c88c31 100644 (file)
 
 package io.fd.honeycomb.v3po.translate.v3po.interfacesstate;
 
-import com.google.common.base.Optional;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Multimap;
-import io.fd.honeycomb.v3po.translate.impl.read.CompositeListReader;
-import io.fd.honeycomb.v3po.translate.impl.read.CompositeRootReader;
-import io.fd.honeycomb.v3po.translate.read.ChildReader;
-import io.fd.honeycomb.v3po.translate.read.ReadContext;
+import static io.fd.honeycomb.v3po.translate.v3po.interfacesstate.InterfaceUtils.YangIfIndexToVpp;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
-import io.fd.honeycomb.v3po.translate.read.Reader;
-import io.fd.honeycomb.v3po.translate.util.RWUtils;
-import io.fd.honeycomb.v3po.translate.util.read.DelegatingReaderRegistry;
-import io.fd.honeycomb.v3po.translate.util.read.ReflexiveRootReaderCustomizer;
-import io.fd.honeycomb.v3po.translate.v3po.interfacesstate.InterfaceCustomizer;
-import org.junit.Before;
+import io.fd.honeycomb.v3po.translate.spi.read.RootReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.test.ListReaderCustomizerTest;
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.ExecutionException;
 import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesStateBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey;
-import org.opendaylight.yangtools.yang.binding.ChildOf;
-import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.openvpp.vppjapi.vppApi;
-import org.openvpp.vppjapi.vppInterfaceDetails;
-import org.openvpp.vppjapi.vppVersion;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor;
-import org.powermock.modules.junit4.PowerMockRunner;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
+import org.openvpp.jvpp.dto.SwInterfaceDetails;
+import org.openvpp.jvpp.dto.SwInterfaceDetailsReplyDump;
+import org.openvpp.jvpp.dto.SwInterfaceDump;
 
-import static org.junit.Assert.assertTrue;
-import static org.powermock.api.mockito.PowerMockito.mock;
+public class InterfaceCustomizerTest extends
+        ListReaderCustomizerTest<Interface, InterfaceKey, InterfaceBuilder> {
 
-@RunWith(PowerMockRunner.class)
-@SuppressStaticInitializationFor("org.openvpp.vppjapi.vppConn")
-@PrepareForTest(vppApi.class)
-public class InterfaceCustomizerTest {
+    private NamingContext interfacesContext;
 
-    public static final vppVersion VERSION = new vppVersion("test", "1", "2", "33");
+    public InterfaceCustomizerTest() {
+        super(Interface.class);
+    }
 
-    private vppApi api;
-    private CompositeRootReader<InterfacesState, InterfacesStateBuilder> interfacesStateReader;
-    private DelegatingReaderRegistry readerRegistry;
-    private ReadContext ctx;
+    @Override
+    public void setUpBefore() {
+        interfacesContext = new NamingContext("generatedIfaceName");
+    }
 
-    private CompositeRootReader<InterfacesState, InterfacesStateBuilder> getInterfacesStateReader(
-            final vppApi vppApi) {
+    @Override
+    protected RootReaderCustomizer<Interface, InterfaceBuilder> initCustomizer() {
+        return new InterfaceCustomizer(api, interfacesContext);
+    }
 
-        final CompositeListReader<Interface, InterfaceKey, InterfaceBuilder> interfacesReader =
-                new CompositeListReader<>(Interface.class, new InterfaceCustomizer(vppApi));
+    // TODO use reflexion and move to ListReaderCustomizerTest
+    @Test
+    public void testMerge() throws Exception {
+        final InterfacesStateBuilder builder = mock(InterfacesStateBuilder.class);
+        final List<Interface> value = Collections.emptyList();
+        getCustomizer().merge(builder, value);
+        verify(builder).setInterface(value);
+    }
 
-        final List<ChildReader<? extends ChildOf<InterfacesState>>> childReaders = new ArrayList<>();
-        childReaders.add(interfacesReader);
+    private void verifyBridgeDomainDumpUpdateWasInvoked(final int nameFilterValid, final String ifaceName) {
+        // TODO adding equals methods for jvpp DTOs would make ArgumentCaptor usage obsolete
+        ArgumentCaptor<SwInterfaceDump> argumentCaptor = ArgumentCaptor.forClass(SwInterfaceDump.class);
+        verify(api).swInterfaceDump(argumentCaptor.capture());
+        final SwInterfaceDump actual = argumentCaptor.getValue();
+        assertEquals(nameFilterValid, actual.nameFilterValid);
+        assertArrayEquals(ifaceName.getBytes(), actual.nameFilter);
+    }
 
-        return new CompositeRootReader<>(InterfacesState.class, childReaders,
-                RWUtils.<InterfacesState>emptyAugReaderList(),
-                new ReflexiveRootReaderCustomizer<>(InterfacesStateBuilder.class));
+    private static void assertIfacesAreEqual(final Interface iface, final SwInterfaceDetails details) {
+        assertEquals(iface.getName(), new String(details.interfaceName));
+        assertEquals(YangIfIndexToVpp(iface.getIfIndex().intValue()), details.swIfIndex);
+        assertEquals(iface.getPhysAddress().getValue(), InterfaceUtils.vppPhysAddrToYang(details.l2Address));
     }
 
-    public static vppInterfaceDetails createVppInterfaceDetails(int ifIndex, String name) {
-        return new vppInterfaceDetails(
-                ifIndex, name, 0,
-                new byte[]{ (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00},
-                (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, 0, 0,
-                (byte) 0, (byte) 0, (byte) 0, (byte) 0, 0, 0, 0, 0, 0);
+    private void whenSwInterfaceDumpThenReturn(final List<SwInterfaceDetails> interfaceList)
+            throws ExecutionException, InterruptedException {
+        final CompletionStage<SwInterfaceDetailsReplyDump> replyCS = mock(CompletionStage.class);
+        final CompletableFuture<SwInterfaceDetailsReplyDump> replyFuture = mock(CompletableFuture.class);
+        when(replyCS.toCompletableFuture()).thenReturn(replyFuture);
+        final SwInterfaceDetailsReplyDump reply = new SwInterfaceDetailsReplyDump();
+        reply.swInterfaceDetails = interfaceList;
+        when(replyFuture.get()).thenReturn(reply);
+        when(api.swInterfaceDump(any(SwInterfaceDump.class))).thenReturn(replyCS);
     }
 
-    @Before
-    public void setUp() throws Exception {
-        api = mock(vppApi.class);
-        // PowerMockito.doReturn(VERSION).when(api).getVppVersion();
-        ctx = mock(ReadContext.class);
-        List<vppInterfaceDetails> ifaces = new ArrayList<>();
-        ifaces.add(createVppInterfaceDetails(0, "loop0"));
-        vppInterfaceDetails[] ifArr = ifaces.toArray(new vppInterfaceDetails[ifaces.size()]);
-
-        PowerMockito.when(api.swInterfaceDump((byte) 0, new byte[]{})).
-                thenReturn(ifArr);
-        PowerMockito.when(api.swInterfaceDump((byte) 1, ifArr[0].interfaceName.getBytes())).thenReturn(ifArr);
-
-        interfacesStateReader = getInterfacesStateReader(api);
-        readerRegistry = new DelegatingReaderRegistry(
-                Collections.<Reader<? extends DataObject>>singletonList(interfacesStateReader));
+    @Test
+    public void testReadCurrentAttributes() throws Exception {
+        final String ifaceName = "eth0";
+        final InstanceIdentifier<Interface> id = InstanceIdentifier.create(InterfacesState.class)
+                .child(Interface.class, new InterfaceKey(ifaceName));
+        final InterfaceBuilder builder = getCustomizer().getBuilder(id);
+
+        final SwInterfaceDetails iface = new SwInterfaceDetails();
+        iface.interfaceName = ifaceName.getBytes();
+        iface.swIfIndex = 0;
+        iface.linkSpeed = 1;
+        iface.l2AddressLength = 6;
+        iface.l2Address = new byte[iface.l2AddressLength];
+        final List<SwInterfaceDetails> interfaceList = Collections.singletonList(iface);
+        whenSwInterfaceDumpThenReturn(interfaceList);
+
+        getCustomizer().readCurrentAttributes(id, builder, ctx);
+
+        verifyBridgeDomainDumpUpdateWasInvoked(1, ifaceName);
+        assertIfacesAreEqual(builder.build(), iface);
     }
 
     @Test
-    public void testReadAll() throws ReadFailedException {
-        final Multimap<InstanceIdentifier<? extends DataObject>, ? extends DataObject> dataObjects =
-                readerRegistry.readAll(ctx);
-
-        System.out.println(dataObjects.keys());
-        final DataObject obj = Iterables.getOnlyElement(
-                dataObjects.get(Iterables.getOnlyElement(dataObjects.keySet())));
-        assertTrue(obj instanceof InterfacesState);
+    public void testReadCurrentAttributesFailed() throws Exception {
+        final String ifaceName = "eth0";
+        final InstanceIdentifier<Interface> id = InstanceIdentifier.create(InterfacesState.class)
+                .child(Interface.class, new InterfaceKey(ifaceName));
+        final InterfaceBuilder builder = getCustomizer().getBuilder(id);
+
+        whenSwInterfaceDumpThenReturn(Collections.emptyList());
+
+        try {
+            getCustomizer().readCurrentAttributes(id, builder, ctx);
+        } catch (ReadFailedException e) {
+            verifyBridgeDomainDumpUpdateWasInvoked(1, ifaceName);
+            return;
+        }
+
+        fail("ReadFailedException was expected");
     }
 
     @Test
-    public void testReadId() throws ReadFailedException {
-        Optional<? extends DataObject> read =
-                readerRegistry.read(InstanceIdentifier.create(InterfacesState.class).child(Interface.class, new InterfaceKey("Loofdsafdsap0")), ctx);
-        System.err.println(read);
+    public void testGetAllIds() throws Exception {
+        final InstanceIdentifier<Interface> id = InstanceIdentifier.create(InterfacesState.class)
+                .child(Interface.class);
+
+        final String swIf0Name = "eth0";
+        final SwInterfaceDetails swIf0 = new SwInterfaceDetails();
+        swIf0.interfaceName = swIf0Name.getBytes();
+        final String swIf1Name = "eth0";
+        final SwInterfaceDetails swIf1 = new SwInterfaceDetails();
+        swIf1.interfaceName = swIf1Name.getBytes();
+        whenSwInterfaceDumpThenReturn(Arrays.asList(swIf0, swIf1));
+
+        final List<InterfaceKey> expectedIds = Arrays.asList(new InterfaceKey(swIf0Name), new InterfaceKey(swIf1Name));
+        final List<InterfaceKey> actualIds = getCustomizer().getAllIds(id, ctx);
+
+        verifyBridgeDomainDumpUpdateWasInvoked(0, "");
+
+        assertEquals(expectedIds, actualIds);
     }
 }
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/ChildReaderCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/ChildReaderCustomizerTest.java
new file mode 100644 (file)
index 0000000..57369d6
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.v3po.translate.v3po.test;
+
+import static org.junit.Assert.assertNotNull;
+
+import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
+import org.junit.Test;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * Generic test for classes implementing {@link ChildReaderCustomizer} interface.
+ *
+ * @param <D> Specific DataObject derived type (Identifiable), that is handled by this customizer
+ * @param <B> Specific Builder for handled type (D)
+ */
+public abstract class ChildReaderCustomizerTest<D extends DataObject, B extends Builder<D>> extends RootReaderCustomizerTest<D, B>{
+
+
+    protected ChildReaderCustomizerTest(Class<D> dataObjectClass) {
+        super(dataObjectClass);
+    }
+
+    @Override
+    protected ChildReaderCustomizer<D, B> getCustomizer() {
+        return ChildReaderCustomizer.class.cast(super.getCustomizer());
+    }
+
+    @Test
+    public void testGetBuilder() throws Exception {
+        assertNotNull(getCustomizer().getBuilder(InstanceIdentifier.create(dataObjectClass)));
+    }
+}
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/ListReaderCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/ListReaderCustomizerTest.java
new file mode 100644 (file)
index 0000000..00cac2d
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.v3po.translate.v3po.test;
+
+import static org.junit.Assert.assertNotNull;
+
+import io.fd.honeycomb.v3po.translate.spi.read.ListReaderCustomizer;
+import org.junit.Test;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.Identifiable;
+import org.opendaylight.yangtools.yang.binding.Identifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * Generic test for classes implementing {@link ListReaderCustomizer} interface.
+ *
+ * @param <D> Specific DataObject derived type (Identifiable), that is handled by this customizer
+ * @param <K> Specific Identifier for handled type (D)
+ * @param <B> Specific Builder for handled type (D)
+ */
+public abstract class ListReaderCustomizerTest<D extends DataObject & Identifiable<K>, K extends Identifier<D>, B extends Builder<D>> extends RootReaderCustomizerTest<D, B>{
+
+
+    protected ListReaderCustomizerTest(Class<D> dataObjectClass) {
+        super(dataObjectClass);
+    }
+
+    @Override
+    protected ListReaderCustomizer<D, K, B> getCustomizer() {
+        return ListReaderCustomizer.class.cast(super.getCustomizer());
+    }
+
+    @Test
+    public void testGetBuilder() throws Exception {
+        assertNotNull(getCustomizer().getBuilder(InstanceIdentifier.create(dataObjectClass)));
+    }
+}
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/RootReaderCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/RootReaderCustomizerTest.java
new file mode 100644 (file)
index 0000000..76eb0fb
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.v3po.translate.v3po.test;
+
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.MockitoAnnotations.initMocks;
+
+import io.fd.honeycomb.v3po.translate.Context;
+import io.fd.honeycomb.v3po.translate.spi.read.RootReaderCustomizer;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.openvpp.jvpp.future.FutureJVpp;
+
+/**
+ * Generic test for classes implementing {@link RootReaderCustomizer} interface.
+ *
+ * @param <D> Specific DataObject derived type (Identifiable), that is handled by this customizer
+ * @param <B> Specific Builder for handled type (D)
+ */
+public abstract class RootReaderCustomizerTest<D extends DataObject, B extends Builder<D>> {
+
+    @Mock
+    protected FutureJVpp api;
+    @Mock
+    protected Context ctx;
+
+    protected final Class<D> dataObjectClass;
+    private RootReaderCustomizer<D, B> customizer;
+
+    protected RootReaderCustomizerTest(Class<D> dataObjectClass) {
+        this.dataObjectClass = dataObjectClass;
+    }
+
+    @Before
+    public void setUpParent() throws Exception {
+        initMocks(this);
+        setUpBefore();
+        customizer = initCustomizer();
+        setUpAfter();
+    }
+
+    /**
+     * Optional setup for subclasses. Invoked before customizer is initialized.
+     */
+    protected void setUpBefore() {
+
+    }
+
+    /**
+     * Optional setup for subclasses. Invoked after customizer is initialized.
+     */
+    protected void setUpAfter() {
+
+    }
+
+    protected abstract RootReaderCustomizer<D, B> initCustomizer();
+
+    protected RootReaderCustomizer<D, B> getCustomizer() {
+        return customizer;
+    }
+
+    @Test
+    public void testGetBuilder() throws Exception {
+        assertNotNull(customizer.getBuilder(InstanceIdentifier.create(dataObjectClass)));
+    }
+}
index 3cb054a..115eb2b 100644 (file)
@@ -1,35 +1,17 @@
 package io.fd.honeycomb.v3po.translate.v3po.utils;
 
-import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertArrayEquals;
 
 import org.junit.Test;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone;
 
 public class V3poUtilsTest {
 
     @Test
-    public void testRemoveIpv4AddressNoZoneFromIpv4WithZone() throws Exception {
-        String ipWithZone = "1.2.3.4%20";
-        String ipNoZone = "1.2.3.4";
-        final Ipv4Address expectedIp = new Ipv4Address(ipNoZone);
-        final Ipv4AddressNoZone actualIp = V3poUtils.removeIpv4AddressNoZone(new Ipv4Address(ipWithZone));
-        assertEquals(expectedIp.getValue(), actualIp.getValue());
-    }
-
-    @Test
-    public void testRemoveIpv4AddressNoZoneFromIpv4WithoutZone() throws Exception {
-        String ipNoZone = "1.2.3.4";
-        final Ipv4Address expectedIp = new Ipv4Address(ipNoZone);
-        final Ipv4AddressNoZone actualIp = V3poUtils.removeIpv4AddressNoZone(expectedIp);
-        assertEquals(expectedIp.getValue(), actualIp.getValue());
-    }
-
-    @Test
-    public void testRemoveIpv4AddressNoZoneNop() throws Exception {
-        String ipNoZone = "1.2.3.4";
-        final Ipv4Address expectedIp = new Ipv4AddressNoZone(ipNoZone);
-        final Ipv4AddressNoZone actualIp = V3poUtils.removeIpv4AddressNoZone(expectedIp);
-        assertEquals(expectedIp, actualIp);
+    public void testToString() {
+        final byte[] expected = "test".getBytes();
+        final byte[] cString = new byte[expected.length+10];
+        System.arraycopy(expected, 0, cString, 0, expected.length);
+        final String jString = V3poUtils.toString(cString);
+        assertArrayEquals(expected, jString.getBytes());
     }
 }
\ No newline at end of file
index f504918..5d5781a 100644 (file)
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package io.fd.honeycomb.v3po.translate.v3po.vpp;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.fail;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 import static org.mockito.MockitoAnnotations.initMocks;
 
 import io.fd.honeycomb.v3po.translate.Context;
+import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.ExecutionException;
 import org.junit.Before;
 import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomain;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomainBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomainKey;
-import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
-import org.openvpp.vppjapi.vppApi;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor;
-import org.powermock.modules.junit4.PowerMockRunner;
-
-@RunWith(PowerMockRunner.class)
-@SuppressStaticInitializationFor("org.openvpp.vppjapi.vppConn")
-@PrepareForTest(vppApi.class)
+import org.openvpp.jvpp.dto.BridgeDomainAddDel;
+import org.openvpp.jvpp.dto.BridgeDomainAddDelReply;
+import org.openvpp.jvpp.future.FutureJVpp;
+
 public class BridgeDomainCustomizerTest {
 
-    private static final int RESPONSE_NOT_READY = -77;
     private static final byte ADD_OR_UPDATE_BD = (byte) 1;
     private static final byte ZERO = 0;
-    private vppApi api;
+
+    @Mock
+    private FutureJVpp api;
 
     @Mock
     private Context ctx;
 
     private BridgeDomainCustomizer customizer;
+    private NamingContext namingContext;
 
     @Before
     public void setUp() throws Exception {
-        // TODO create base class for tests using vppApi
-        api = PowerMockito.mock(vppApi.class);
         initMocks(this);
-        customizer = new BridgeDomainCustomizer(api);
-
-        PowerMockito.doAnswer(BridgeDomainTestUtils.BD_NAME_TO_ID_ANSWER).when(api).findOrAddBridgeDomainId(anyString());
-        PowerMockito.doAnswer(BridgeDomainTestUtils.BD_NAME_TO_ID_ANSWER).when(api).bridgeDomainIdFromName(anyString());
-        PowerMockito.when(api.getRetval(anyInt(), anyInt())).thenReturn(RESPONSE_NOT_READY).thenReturn(0);
-        PowerMockito.doReturn(0).when(api).getRetval(anyInt(), anyInt());
+        // TODO create base class for tests using vppApi
+        namingContext = new NamingContext("generatedBDName");
+        customizer = new BridgeDomainCustomizer(api, namingContext);
     }
 
     private BridgeDomain generateBridgeDomain(final String bdName) {
@@ -87,127 +83,140 @@ public class BridgeDomainCustomizerTest {
                 .build();
     }
 
-    private final int verifyBridgeDomainAddOrUpdateWasInvoked(final BridgeDomain bd) {
-        final int bdn1Id = BridgeDomainTestUtils.bdNameToID(bd.getName());
+    private void verifyBridgeDomainAddOrUpdateWasInvoked(final BridgeDomain bd, final int bdId) {
         final byte arpTerm = BridgeDomainTestUtils.booleanToByte(bd.isArpTermination());
         final byte flood = BridgeDomainTestUtils.booleanToByte(bd.isFlood());
         final byte forward = BridgeDomainTestUtils.booleanToByte(bd.isForward());
         final byte learn = BridgeDomainTestUtils.booleanToByte(bd.isLearn());
         final byte uuf = BridgeDomainTestUtils.booleanToByte(bd.isUnknownUnicastFlood());
-        return verify(api).bridgeDomainAddDel(bdn1Id, flood, forward, learn, uuf, arpTerm, ADD_OR_UPDATE_BD);
+
+        // TODO adding equals methods for jvpp DTOs would make ArgumentCaptor usage obsolete
+        ArgumentCaptor<BridgeDomainAddDel> argumentCaptor = ArgumentCaptor.forClass(BridgeDomainAddDel.class);
+        verify(api).bridgeDomainAddDel(argumentCaptor.capture());
+        final BridgeDomainAddDel actual = argumentCaptor.getValue();
+        assertEquals(arpTerm, actual.arpTerm);
+        assertEquals(flood, actual.flood);
+        assertEquals(forward, actual.forward);
+        assertEquals(learn, actual.learn);
+        assertEquals(uuf, actual.uuFlood);
+        assertEquals(ADD_OR_UPDATE_BD, actual.isAdd);
+        assertEquals(bdId, actual.bdId);
     }
 
-    private int verifyBridgeDomainAddOrUpdateWasNotInvoked(final BridgeDomain bd) {
-        final int bdn1Id = BridgeDomainTestUtils.bdNameToID(bd.getName());
-        final byte arpTerm = BridgeDomainTestUtils.booleanToByte(bd.isArpTermination());
-        final byte flood = BridgeDomainTestUtils.booleanToByte(bd.isFlood());
-        final byte forward = BridgeDomainTestUtils.booleanToByte(bd.isForward());
-        final byte learn = BridgeDomainTestUtils.booleanToByte(bd.isLearn());
-        final byte uuf = BridgeDomainTestUtils.booleanToByte(bd.isUnknownUnicastFlood());
-        return verify(api, never()).bridgeDomainAddDel(bdn1Id, flood, forward, learn, uuf, arpTerm, ADD_OR_UPDATE_BD);
+    private void verifyBridgeDomainDeleteWasInvoked(final int bdId) {
+        ArgumentCaptor<BridgeDomainAddDel> argumentCaptor = ArgumentCaptor.forClass(BridgeDomainAddDel.class);
+        verify(api).bridgeDomainAddDel(argumentCaptor.capture());
+        final BridgeDomainAddDel actual = argumentCaptor.getValue();
+        assertEquals(bdId, actual.bdId);
+        assertEquals(ZERO, actual.arpTerm);
+        assertEquals(ZERO, actual.flood);
+        assertEquals(ZERO, actual.forward);
+        assertEquals(ZERO, actual.learn);
+        assertEquals(ZERO, actual.uuFlood);
+        assertEquals(ZERO, actual.isAdd);
+    }
+
+    private void whenBridgeDomainAddDelThen(final int retval) throws ExecutionException, InterruptedException {
+        final CompletionStage<BridgeDomainAddDelReply> replyCS = mock(CompletionStage.class);
+        final CompletableFuture<BridgeDomainAddDelReply> replyFuture = mock(CompletableFuture.class);
+        when(replyCS.toCompletableFuture()).thenReturn(replyFuture);
+        final BridgeDomainAddDelReply reply = new BridgeDomainAddDelReply();
+        reply.retval = retval;
+        when(replyFuture.get()).thenReturn(reply);
+        when(api.bridgeDomainAddDel(any(BridgeDomainAddDel.class))).thenReturn(replyCS);
     }
 
-    private int verifyBridgeDomainDeletedWasInvoked(final BridgeDomain bd) {
-        final int bdn1Id = BridgeDomainTestUtils.bdNameToID(bd.getName());
-        return verify(api).bridgeDomainAddDel(bdn1Id, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO);
+    private void whenBridgeDomainAddDelThenSuccess() throws ExecutionException, InterruptedException {
+        whenBridgeDomainAddDelThen(0);
     }
 
-    private int verifyBridgeDomainDeletedWasNotInvoked(final BridgeDomain bd) {
-        final int bdn1Id = BridgeDomainTestUtils.bdNameToID(bd.getName());
-        return verify(api, never()).bridgeDomainAddDel(bdn1Id, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO);
+    private void whenBridgeDomainAddDelThenFailure() throws ExecutionException, InterruptedException {
+        whenBridgeDomainAddDelThen(-1);
     }
 
     @Test
-    public void testAddBridgeDomain() {
+    public void testAddBridgeDomain() throws Exception {
+        final int bdId = 1;
         final String bdName = "bd1";
-        final BridgeDomain bd = generateBridgeDomain("bd1");
+        final BridgeDomain bd = generateBridgeDomain(bdName);
+
+        whenBridgeDomainAddDelThenSuccess();
 
         customizer.writeCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), bd, ctx);
 
-        verifyBridgeDomainAddOrUpdateWasInvoked(bd);
+        verifyBridgeDomainAddOrUpdateWasInvoked(bd, bdId);
     }
 
     @Test
-    public void testBridgeDomainNameCreateFailed() {
+    public void testAddBridgeDomainFailed() throws Exception {
+        final int bdId = 1;
         final String bdName = "bd1";
-        final BridgeDomain bd = generateBridgeDomain("bd1");
+        final BridgeDomain bd = generateBridgeDomain(bdName);
 
-        // make vpp api fail to create id for our bd name
-        PowerMockito.doReturn(-1).when(api).findOrAddBridgeDomainId(bdName);
+        whenBridgeDomainAddDelThenFailure();
 
         try {
             customizer.writeCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), bd, ctx);
-        } catch (IllegalStateException e) {
-            verifyBridgeDomainAddOrUpdateWasNotInvoked(bd);
+        } catch (WriteFailedException.CreateFailedException e) {
+            verifyBridgeDomainAddOrUpdateWasInvoked(bd, bdId);
             return;
         }
-        fail("IllegalStateException was expected");
+        fail("WriteFailedException.CreateFailedException  was expected");
     }
 
     @Test
-    public void testAddBridgeDomainFailed() {
-        // make any call to vpp fail
-        PowerMockito.doReturn(-1).when(api).getRetval(anyInt(), anyInt());
-
+    public void testDeleteBridgeDomain() throws Exception {
+        final int bdId = 1;
         final String bdName = "bd1";
         final BridgeDomain bd = generateBridgeDomain(bdName);
+        namingContext.addName(bdId, bdName);
 
-        try {
-            customizer.writeCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), bd, ctx);
-        } catch (IllegalStateException e) {
-            verifyBridgeDomainAddOrUpdateWasInvoked(bd);
-            return;
-        }
-        fail("IllegalStateException was expected");
-    }
-
-    @Test
-    public void testDeleteBridgeDomain() {
-        final String bdName = "bd1";
-        final BridgeDomain bd = generateBridgeDomain("bd1");
+        whenBridgeDomainAddDelThenSuccess();
 
         customizer.deleteCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), bd, ctx);
 
-        verifyBridgeDomainDeletedWasInvoked(bd);
+        verifyBridgeDomainDeleteWasInvoked(bdId);
     }
 
     @Test
-    public void testDeleteUnknownBridgeDomain() {
+    public void testDeleteUnknownBridgeDomain() throws Exception {
         final String bdName = "bd1";
         final BridgeDomain bd = generateBridgeDomain("bd1");
 
-        // make vpp api not find our bd
-        PowerMockito.doReturn(-1).when(api).bridgeDomainIdFromName(bdName);
-
         try {
             customizer.deleteCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), bd, ctx);
-        } catch (IllegalStateException e) {
-            verifyBridgeDomainDeletedWasNotInvoked(bd);
+        } catch (IllegalArgumentException e) {
+            verify(api, never()).bridgeDomainAddDel(any(BridgeDomainAddDel.class));
             return;
         }
-        fail("IllegalStateException was expected");
+        fail("IllegalArgumentException was expected");
     }
 
     @Test
-    public void testDeleteBridgeDomainFailed() {
-        // make any call to vpp fail
-        PowerMockito.doReturn(-1).when(api).getRetval(anyInt(), anyInt());
-
+    public void testDeleteBridgeDomainFailed() throws Exception {
+        final int bdId = 1;
         final String bdName = "bd1";
         final BridgeDomain bd = generateBridgeDomain(bdName);
+        namingContext.addName(bdId, bdName);
+
+        whenBridgeDomainAddDelThenFailure();
 
         try {
             customizer.deleteCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), bd, ctx);
-        } catch (IllegalStateException e) {
-            verifyBridgeDomainDeletedWasInvoked(bd);
+        } catch (WriteFailedException.DeleteFailedException e) {
+            verifyBridgeDomainDeleteWasInvoked(bdId);
             return;
         }
-        fail("IllegalStateException was expected");
+
+        fail("WriteFailedException.DeleteFailedException was expected");
     }
 
     @Test
     public void testUpdateBridgeDomain() throws Exception {
+        final int bdId = 1;
         final String bdName = "bd1";
+        namingContext.addName(bdId, bdName);
+
         final byte arpTermBefore = 1;
         final byte floodBefore = 1;
         final byte forwardBefore = 0;
@@ -220,11 +229,11 @@ public class BridgeDomainCustomizerTest {
                 generateBridgeDomain(bdName, arpTermBefore ^ 1, floodBefore ^ 1, forwardBefore ^ 1, learnBefore ^ 1,
                         uufBefore ^ 1);
 
-        final KeyedInstanceIdentifier<BridgeDomain, BridgeDomainKey> id = BridgeDomainTestUtils.bdIdentifierForName(bdName);
+        whenBridgeDomainAddDelThenSuccess();
 
-        customizer.updateCurrentAttributes(id, dataBefore, dataAfter, ctx);
+        customizer.updateCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), dataBefore, dataAfter, ctx);
 
-        verifyBridgeDomainAddOrUpdateWasInvoked(dataAfter);
+        verifyBridgeDomainAddOrUpdateWasInvoked(dataAfter, bdId);
     }
 
     @Test
@@ -232,30 +241,28 @@ public class BridgeDomainCustomizerTest {
         final String bdName = "bd1";
         final BridgeDomain bd = generateBridgeDomain("bd1");
 
-        // make vpp api not find our bd
-        PowerMockito.doReturn(-1).when(api).bridgeDomainIdFromName(bdName);
-
         try {
             customizer.updateCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), bd, bd, ctx);
-        } catch (IllegalStateException e) {
-            verifyBridgeDomainAddOrUpdateWasNotInvoked(bd);
+        } catch (IllegalArgumentException e) {
+            verify(api, never()).bridgeDomainAddDel(any(BridgeDomainAddDel.class));
             return;
         }
-        fail("IllegalStateException was expected");
+        fail("IllegalArgumentException was expected");
     }
 
     @Test
-    public void testUpdateBridgeDomainFailed() {
-        // make any call to vpp fail
-        PowerMockito.doReturn(-1).when(api).getRetval(anyInt(), anyInt());
-
+    public void testUpdateBridgeDomainFailed() throws Exception {
+        final int bdId = 1;
         final String bdName = "bd1";
         final BridgeDomain bd = generateBridgeDomain(bdName);
+        namingContext.addName(bdId, bdName);
+
+        whenBridgeDomainAddDelThenFailure();
 
         try {
             customizer.updateCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), bd, bd, ctx);
-        } catch (IllegalStateException e) {
-            verifyBridgeDomainAddOrUpdateWasInvoked(bd);
+        } catch (WriteFailedException.UpdateFailedException  e) {
+            verifyBridgeDomainAddOrUpdateWasInvoked(bd, bdId);
             return;
         }
         fail("IllegalStateException was expected");
index 0ff3ba1..820cf05 100644 (file)
 
 package io.fd.honeycomb.v3po.translate.v3po.vpp;
 
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyString;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
 
+import com.google.common.collect.Iterators;
 import com.google.common.collect.Lists;
 import io.fd.honeycomb.v3po.translate.impl.write.CompositeRootWriter;
-import io.fd.honeycomb.v3po.translate.write.WriteContext;
 import io.fd.honeycomb.v3po.translate.util.write.DelegatingWriterRegistry;
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
+import io.fd.honeycomb.v3po.translate.write.WriteContext;
 import io.fd.honeycomb.v3po.translate.write.Writer;
 import java.util.Collections;
 import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.ExecutionException;
 import org.junit.Before;
 import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.Vpp;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.BridgeDomains;
@@ -41,98 +46,147 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomainBuilder;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.openvpp.vppjapi.vppApi;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor;
-import org.powermock.modules.junit4.PowerMockRunner;
-
-@RunWith(PowerMockRunner.class)
-@SuppressStaticInitializationFor("org.openvpp.vppjapi.vppConn")
-@PrepareForTest(vppApi.class)
+import org.openvpp.jvpp.dto.BridgeDomainAddDel;
+import org.openvpp.jvpp.dto.BridgeDomainAddDelReply;
+import org.openvpp.jvpp.future.FutureJVpp;
+
 public class VppTest {
 
-    private vppApi api;
+    private static final byte ADD_OR_UPDATE_BD = 1;
+    private static final byte ZERO = 0;
+    private FutureJVpp api;
     private DelegatingWriterRegistry rootRegistry;
     private CompositeRootWriter<Vpp> vppWriter;
     private WriteContext ctx;
-
-    final byte zero = (byte) 0;
-    final byte flood = (byte) 1;
-    final byte forward = (byte) 0;
-    final byte learn = (byte) 1;
-    final byte uuf = (byte) 0;
-    final byte arpTerm = (byte) 0;
-    final byte add = (byte) 1;
+    private NamingContext bdContext;
 
     @Before
     public void setUp() throws Exception {
-        api = PowerMockito.mock(vppApi.class);
+        api = mock(FutureJVpp.class);
         ctx = mock(WriteContext.class);
-        PowerMockito.doAnswer(BridgeDomainTestUtils.BD_NAME_TO_ID_ANSWER).when(api).findOrAddBridgeDomainId(anyString());
-        PowerMockito.doAnswer(BridgeDomainTestUtils.BD_NAME_TO_ID_ANSWER).when(api).bridgeDomainIdFromName(anyString());
-        PowerMockito.doReturn(1).when(api).getRetval(anyInt(), anyInt());
-        vppWriter = VppUtils.getVppWriter(api);
+        bdContext = new NamingContext("generatedBdName");
+        vppWriter = VppUtils.getVppWriter(api, bdContext);
         rootRegistry = new DelegatingWriterRegistry(
             Collections.<Writer<? extends DataObject>>singletonList(vppWriter));
     }
 
+    private BridgeDomains getBridgeDomains(String... name) {
+        final List<BridgeDomain> bdmns = Lists.newArrayList();
+        for (String s : name) {
+            bdmns.add(new BridgeDomainBuilder()
+                    .setName(s)
+                    .setArpTermination(false)
+                    .setFlood(true)
+                    .setForward(false)
+                    .setLearn(true)
+                    .build());
+        }
+        return new BridgeDomainsBuilder()
+                .setBridgeDomain(bdmns)
+                .build();
+    }
+
+    private void whenBridgeDomainAddDelThen(final int retval) throws ExecutionException, InterruptedException {
+        final CompletionStage<BridgeDomainAddDelReply> replyCS = mock(CompletionStage.class);
+        final CompletableFuture<BridgeDomainAddDelReply> replyFuture = mock(CompletableFuture.class);
+        when(replyCS.toCompletableFuture()).thenReturn(replyFuture);
+        final BridgeDomainAddDelReply reply = new BridgeDomainAddDelReply();
+        reply.retval = retval;
+        when(replyFuture.get()).thenReturn(reply);
+        when(api.bridgeDomainAddDel(any(BridgeDomainAddDel.class))).thenReturn(replyCS);
+    }
+
+    private void verifyBridgeDomainAddDel(final BridgeDomain bd, final int bdId) {
+        final byte arpTerm = BridgeDomainTestUtils.booleanToByte(bd.isArpTermination());
+        final byte flood = BridgeDomainTestUtils.booleanToByte(bd.isFlood());
+        final byte forward = BridgeDomainTestUtils.booleanToByte(bd.isForward());
+        final byte learn = BridgeDomainTestUtils.booleanToByte(bd.isLearn());
+        final byte uuf = BridgeDomainTestUtils.booleanToByte(bd.isUnknownUnicastFlood());
+
+        // TODO adding equals methods for jvpp DTOs would make ArgumentCaptor usage obsolete
+        ArgumentCaptor<BridgeDomainAddDel> argumentCaptor = ArgumentCaptor.forClass(BridgeDomainAddDel.class);
+        verify(api).bridgeDomainAddDel(argumentCaptor.capture());
+        final BridgeDomainAddDel actual = argumentCaptor.getValue();
+        assertEquals(arpTerm, actual.arpTerm);
+        assertEquals(flood, actual.flood);
+        assertEquals(forward, actual.forward);
+        assertEquals(learn, actual.learn);
+        assertEquals(uuf, actual.uuFlood);
+        assertEquals(ADD_OR_UPDATE_BD, actual.isAdd);
+        assertEquals(bdId, actual.bdId);
+    }
+
+    private void verifyBridgeDomainDeleteWasInvoked(final int bdId) {
+        ArgumentCaptor<BridgeDomainAddDel> argumentCaptor = ArgumentCaptor.forClass(BridgeDomainAddDel.class);
+        verify(api).bridgeDomainAddDel(argumentCaptor.capture());
+        final BridgeDomainAddDel actual = argumentCaptor.getValue();
+        assertEquals(bdId, actual.bdId);
+        assertEquals(ZERO, actual.arpTerm);
+        assertEquals(ZERO, actual.flood);
+        assertEquals(ZERO, actual.forward);
+        assertEquals(ZERO, actual.learn);
+        assertEquals(ZERO, actual.uuFlood);
+        assertEquals(ZERO, actual.isAdd);
+    }
+
     @Test
-    public void writeVpp() throws Exception {
+    public void writeVppUsingRootRegistry() throws Exception {
+        final int bdId = 1;
+        final BridgeDomains bdn1 = getBridgeDomains("bdn1");
+        whenBridgeDomainAddDelThen(0);
+
         rootRegistry.update(
-            InstanceIdentifier.create(Vpp.class),
-            null,
-            new VppBuilder().setBridgeDomains(getBridgeDomains("bdn1")).build(),
-            ctx);
+                InstanceIdentifier.create(Vpp.class),
+                null,
+                new VppBuilder().setBridgeDomains(bdn1).build(),
+                ctx);
+
+        verifyBridgeDomainAddDel(Iterators.getOnlyElement(bdn1.getBridgeDomain().iterator()), bdId);
+    }
 
-        verify(api).bridgeDomainAddDel(1, flood, forward, learn, uuf, arpTerm, add);
+    @Test
+    public void writeVppUsingVppWriter() throws Exception {
+        final int bdId = 1;
+        final BridgeDomains bdn1 = getBridgeDomains("bdn1");
+        whenBridgeDomainAddDelThen(0);
 
         vppWriter.update(InstanceIdentifier.create(Vpp.class),
-            null,
-            new VppBuilder().setBridgeDomains(getBridgeDomains("bdn1")).build(),
-            ctx);
+                null,
+                new VppBuilder().setBridgeDomains(bdn1).build(),
+                ctx);
 
-        verify(api, times(2)).bridgeDomainAddDel(1, flood, forward, learn, uuf, arpTerm, add);
+        verifyBridgeDomainAddDel(Iterators.getOnlyElement(bdn1.getBridgeDomain().iterator()), bdId);
     }
 
     @Test
     public void writeVppFromRoot() throws Exception {
-        final Vpp vpp = new VppBuilder().setBridgeDomains(getBridgeDomains("bdn1")).build();
+        final BridgeDomains bdn1 = getBridgeDomains("bdn1");
+        final int bdId = 1;
+        final Vpp vpp = new VppBuilder().setBridgeDomains(bdn1).build();
+        whenBridgeDomainAddDelThen(0);
 
         rootRegistry.update(Collections.<InstanceIdentifier<?>, DataObject>emptyMap(),
             Collections.<InstanceIdentifier<?>, DataObject>singletonMap(InstanceIdentifier.create(Vpp.class),
                 vpp), ctx);
 
-        verify(api).bridgeDomainAddDel(1, flood, forward, learn, uuf, arpTerm, add);
-    }
-
-    private BridgeDomains getBridgeDomains(String... name) {
-        final List<BridgeDomain> bdmns = Lists.newArrayList();
-        for (String s : name) {
-            bdmns.add(new BridgeDomainBuilder()
-                .setName(s)
-                .setArpTermination(false)
-                .setFlood(true)
-                .setForward(false)
-                .setLearn(true)
-                .build());
-        }
-        return new BridgeDomainsBuilder()
-                .setBridgeDomain(bdmns)
-                .build();
+        verifyBridgeDomainAddDel(Iterators.getOnlyElement(bdn1.getBridgeDomain().iterator()), bdId);
     }
 
     @Test
     public void deleteVpp() throws Exception {
+        final String bdName = "bdn1";
+        final BridgeDomains bdn1 = getBridgeDomains(bdName);
+        final int bdId = 1;
+        whenBridgeDomainAddDelThen(0);
+        bdContext.addName(bdId, bdName);
+
         rootRegistry.update(
             InstanceIdentifier.create(Vpp.class),
-            new VppBuilder().setBridgeDomains(getBridgeDomains("bdn1")).build(),
+            new VppBuilder().setBridgeDomains(bdn1).build(),
             null,
             ctx);
 
-        final byte zero = (byte) 0;
-
-        verify(api).bridgeDomainAddDel(1, zero, zero, zero, zero, zero, zero);
+        verifyBridgeDomainDeleteWasInvoked(bdId);
     }
 
     @Test
@@ -148,7 +202,10 @@ public class VppTest {
 
     @Test
     public void writeUpdate() throws Exception {
-        final BridgeDomains domainsBefore = getBridgeDomains("bdn1");
+        final String bdName = "bdn1";
+        final int bdn1Id = 1;
+        bdContext.addName(bdn1Id, bdName);
+        final BridgeDomains domainsBefore = getBridgeDomains(bdName);
         final BridgeDomain bdn1Before = domainsBefore.getBridgeDomain().get(0);
 
         final BridgeDomain bdn1After = new BridgeDomainBuilder(bdn1Before).setFlood(!bdn1Before.isFlood()).build();
@@ -156,16 +213,16 @@ public class VppTest {
             .setBridgeDomain(Collections.singletonList(bdn1After))
             .build();
 
+        whenBridgeDomainAddDelThen(0);
+
         rootRegistry.update(
             InstanceIdentifier.create(Vpp.class),
             new VppBuilder().setBridgeDomains(domainsBefore).build(),
             new VppBuilder().setBridgeDomains(domainsAfter).build(),
             ctx);
 
-        final int bdn1Id = 1;
-
         // bdn1 is created with negated flood value
-        verify(api).bridgeDomainAddDel(bdn1Id, (byte) (flood ^ 1), forward, learn, uuf, arpTerm, add);
+        verifyBridgeDomainAddDel(bdn1After, bdn1Id);
     }
 
     // TODO test unkeyed list
index cb74314..4b3eb5a 100644 (file)
@@ -19,10 +19,11 @@ package io.fd.honeycomb.v3po.translate.v3po.vpp;
 import io.fd.honeycomb.v3po.translate.impl.write.CompositeChildWriter;
 import io.fd.honeycomb.v3po.translate.impl.write.CompositeListWriter;
 import io.fd.honeycomb.v3po.translate.impl.write.CompositeRootWriter;
+import io.fd.honeycomb.v3po.translate.util.RWUtils;
 import io.fd.honeycomb.v3po.translate.util.write.NoopWriterCustomizer;
 import io.fd.honeycomb.v3po.translate.util.write.ReflexiveChildWriterCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import io.fd.honeycomb.v3po.translate.write.ChildWriter;
-import io.fd.honeycomb.v3po.translate.util.RWUtils;
 import java.util.ArrayList;
 import java.util.List;
 import javax.annotation.Nonnull;
@@ -31,7 +32,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomain;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomainKey;
 import org.opendaylight.yangtools.yang.binding.ChildOf;
-import org.openvpp.vppjapi.vppApi;
+import org.openvpp.jvpp.future.FutureJVpp;
 
 final class VppUtils {
 
@@ -40,11 +41,11 @@ final class VppUtils {
     /**
      * Create root Vpp writer with all its children wired
      */
-    static CompositeRootWriter<Vpp> getVppWriter(@Nonnull final vppApi vppApi) {
+    static CompositeRootWriter<Vpp> getVppWriter(@Nonnull final FutureJVpp vppApi, final NamingContext bdContext) {
 
         final CompositeListWriter<BridgeDomain, BridgeDomainKey> bridgeDomainWriter = new CompositeListWriter<>(
             BridgeDomain.class,
-            new BridgeDomainCustomizer(vppApi));
+            new BridgeDomainCustomizer(vppApi, bdContext));
 
         final ChildWriter<BridgeDomains> bridgeDomainsReader = new CompositeChildWriter<>(
             BridgeDomains.class,
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/BridgeDomainCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/BridgeDomainCustomizerTest.java
new file mode 100644 (file)
index 0000000..c482c44
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.fd.honeycomb.v3po.translate.v3po.vppstate;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import io.fd.honeycomb.v3po.translate.spi.read.RootReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.test.ListReaderCustomizerTest;
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
+import java.util.Collections;
+import java.util.List;
+import org.junit.Test;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.BridgeDomainsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomain;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomainBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomainKey;
+
+public class BridgeDomainCustomizerTest extends ListReaderCustomizerTest<BridgeDomain, BridgeDomainKey, BridgeDomainBuilder> {
+
+    private NamingContext bdContext;
+    private NamingContext interfacesContext;
+
+    public BridgeDomainCustomizerTest() {
+        super(BridgeDomain.class);
+    }
+
+    @Override
+    public void setUpBefore() {
+        bdContext = new NamingContext("generatedBdName");
+        interfacesContext = new NamingContext("generatedIfaceName");
+    }
+
+    @Test
+    public void testMerge() throws Exception {
+        final BridgeDomainsBuilder builder = mock(BridgeDomainsBuilder.class);
+        final List<BridgeDomain> value = Collections.emptyList();
+        getCustomizer().merge(builder, value);
+        verify(builder).setBridgeDomain(value);
+    }
+
+    @Override
+    protected RootReaderCustomizer<BridgeDomain, BridgeDomainBuilder> initCustomizer() {
+        return new BridgeDomainCustomizer(api, bdContext, interfacesContext);
+    }
+}
\ No newline at end of file
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VersionCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VersionCustomizerTest.java
new file mode 100644 (file)
index 0000000..03b9231
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.v3po.translate.v3po.vppstate;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.test.ChildReaderCustomizerTest;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
+import org.junit.Test;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppStateBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.Version;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.VersionBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.openvpp.jvpp.dto.ShowVersion;
+import org.openvpp.jvpp.dto.ShowVersionReply;
+
+public class VersionCustomizerTest extends ChildReaderCustomizerTest<Version, VersionBuilder> {
+
+    public VersionCustomizerTest() {
+        super(Version.class);
+    }
+
+    @Override
+    protected ChildReaderCustomizer<Version, VersionBuilder> initCustomizer() {
+        return new VersionCustomizer(api);
+    }
+
+    @Test
+    public void testMerge() {
+        final VppStateBuilder builder = mock(VppStateBuilder.class);
+        final Version value = mock(Version.class);
+        getCustomizer().merge(builder, value);
+        verify(builder).setVersion(value);
+    }
+
+    @Test
+    public void testReadCurrentAttributes() throws Exception {
+        final CompletionStage<ShowVersionReply> replyCS = mock(CompletionStage.class);
+        final CompletableFuture<ShowVersionReply> replyFuture = mock(CompletableFuture.class);
+        when(replyCS.toCompletableFuture()).thenReturn(replyFuture);
+        final ShowVersionReply reply = new ShowVersionReply();
+        reply.retval = 0;
+        reply.version = new byte[]{};
+        reply.program = new byte[]{};
+        reply.buildDate = new byte[]{};
+        reply.buildDirectory = new byte[]{};
+        when(replyFuture.get()).thenReturn(reply);
+        when(api.showVersion(any(ShowVersion.class))).thenReturn(replyCS);
+
+        getCustomizer().readCurrentAttributes(InstanceIdentifier.create(Version.class), new VersionBuilder(), ctx);
+
+        verify(api).showVersion(any(ShowVersion.class));
+    }
+}
\ No newline at end of file
index 6f53f65..bf1d121 100644 (file)
@@ -19,27 +19,30 @@ package io.fd.honeycomb.v3po.translate.v3po.vppstate;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.mockito.MockitoAnnotations.initMocks;
 
 import com.google.common.base.Optional;
-import com.google.common.base.Predicate;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Multimap;
 import io.fd.honeycomb.v3po.translate.impl.read.CompositeListReader;
 import io.fd.honeycomb.v3po.translate.impl.read.CompositeRootReader;
-import io.fd.honeycomb.v3po.translate.util.read.DelegatingReaderRegistry;
 import io.fd.honeycomb.v3po.translate.read.ReadContext;
 import io.fd.honeycomb.v3po.translate.read.Reader;
+import io.fd.honeycomb.v3po.translate.util.read.DelegatingReaderRegistry;
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.ExecutionException;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Matchers;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
+import org.mockito.Mock;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppState;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppStateBuilder;
@@ -53,131 +56,123 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.bridge.domain.L2FibKey;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.openvpp.vppjapi.vppApi;
-import org.openvpp.vppjapi.vppBridgeDomainDetails;
-import org.openvpp.vppjapi.vppBridgeDomainInterfaceDetails;
-import org.openvpp.vppjapi.vppL2Fib;
-import org.openvpp.vppjapi.vppVersion;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor;
-import org.powermock.modules.junit4.PowerMockRunner;
-
-@RunWith(PowerMockRunner.class)
-@SuppressStaticInitializationFor("org.openvpp.vppjapi.vppConn")
-@PrepareForTest(vppApi.class)
+import org.openvpp.jvpp.dto.BridgeDomainDetails;
+import org.openvpp.jvpp.dto.BridgeDomainDetailsReplyDump;
+import org.openvpp.jvpp.dto.BridgeDomainDump;
+import org.openvpp.jvpp.dto.L2FibTableDump;
+import org.openvpp.jvpp.dto.L2FibTableEntry;
+import org.openvpp.jvpp.dto.L2FibTableEntryReplyDump;
+import org.openvpp.jvpp.dto.ShowVersion;
+import org.openvpp.jvpp.dto.ShowVersionReply;
+import org.openvpp.jvpp.future.FutureJVpp;
+
 public class VppStateTest {
 
-    public static final vppVersion VERSION = new vppVersion("test", "1", "2", "33");
+    @Mock
+    private FutureJVpp api;
+    @Mock
+    private ReadContext ctx;
+
+    private NamingContext bdContext;
+    private NamingContext interfaceContext;
 
-    private vppApi api;
     private CompositeRootReader<VppState, VppStateBuilder> vppStateReader;
     private DelegatingReaderRegistry readerRegistry;
-    private vppBridgeDomainDetails bdDetails;
-    private vppBridgeDomainDetails bdDetails2;
-    private ReadContext ctx;
 
     @Before
     public void setUp() throws Exception {
-        api = PowerMockito.mock(vppApi.class);
-
-        ctx = mock(ReadContext.class);
-
-        bdDetails = new vppBridgeDomainDetails();
-        setIfcs(bdDetails);
-        setBaseAttrs(bdDetails, "bdn1", 1);
-
-        bdDetails2 = new vppBridgeDomainDetails();
-        setIfcs(bdDetails2);
-        setBaseAttrs(bdDetails2, "bdn2", 2);
-
-        final vppL2Fib[] l2Fibs = getL2Fibs();
-        PowerMockito.doReturn(l2Fibs).when(api).l2FibTableDump(Matchers.anyInt());
-        PowerMockito.doAnswer(new Answer<vppBridgeDomainDetails>() {
-
-            @Override
-            public vppBridgeDomainDetails answer(final InvocationOnMock invocationOnMock) throws Throwable {
-                final Integer idx = (Integer) invocationOnMock.getArguments()[0];
-                switch (idx) {
-                    case 1 : return bdDetails;
-                    case 2 : return bdDetails2;
-                    default: return null;
-                }
-            }
-        }).when(api).getBridgeDomainDetails(Matchers.anyInt());
-
-        PowerMockito.doAnswer(new Answer<Object>() {
-            @Override
-            public Object answer(final InvocationOnMock invocationOnMock) throws Throwable {
-                final String name = (String) invocationOnMock.getArguments()[0];
-                switch (name) {
-                    case "bdn1" : return 1;
-                    case "bdn2" : return 2;
-                    default: return null;
-                }
-            }
-        }).when(api).bridgeDomainIdFromName(anyString());
-        PowerMockito.doReturn(new int[] {1, 2}).when(api).bridgeDomainDump(Matchers.anyInt());
-        PowerMockito.doReturn(VERSION).when(api).getVppVersion();
-        vppStateReader = VppStateUtils.getVppStateReader(api);
+        initMocks(this);
+
+        bdContext = new NamingContext("generatedBdName");
+        interfaceContext = new NamingContext("generatedInterfaceName");
+        vppStateReader = VppStateTestUtils.getVppStateReader(api, bdContext, interfaceContext);
         readerRegistry = new DelegatingReaderRegistry(Collections.<Reader<? extends DataObject>>singletonList(vppStateReader));
     }
 
-    private vppL2Fib[] getL2Fibs() {
-        return new vppL2Fib[] {
-            new vppL2Fib(new byte[]{1,2,3,4,5,6}, true, "ifc1", true, true),
-            new vppL2Fib(new byte[]{2,2,3,4,5,6}, true, "ifc2", true, true),
-        };
+    private static Version getVersion() {
+        return new VersionBuilder()
+                .setName("test")
+                .setBuildDirectory("1")
+                .setBranch("2")
+                .setBuildDate("3")
+                .build();
     }
 
-    private void setIfcs(final vppBridgeDomainDetails bdDetails) {
-        final vppBridgeDomainInterfaceDetails ifcDetails = new vppBridgeDomainInterfaceDetails();
-        ifcDetails.interfaceName = "ifc";
-        ifcDetails.splitHorizonGroup = 2;
-        bdDetails.interfaces = new vppBridgeDomainInterfaceDetails[] {ifcDetails};
+    private void whenShowVersionThenReturn(int retval, Version version) throws ExecutionException, InterruptedException {
+        final CompletionStage<ShowVersionReply> replyCS = mock(CompletionStage.class);
+        final CompletableFuture<ShowVersionReply> replyFuture = mock(CompletableFuture.class);
+        when(replyCS.toCompletableFuture()).thenReturn(replyFuture);
+        final ShowVersionReply reply = new ShowVersionReply();
+        reply.retval = 0; // success
+        reply.buildDate = version.getBuildDate().getBytes();
+        reply.program = version.getName().getBytes();
+        reply.version = version.getBranch().getBytes();
+        reply.buildDirectory = version.getBuildDirectory().getBytes();
+        when(replyFuture.get()).thenReturn(reply);
+        when(api.showVersion(any(ShowVersion.class))).thenReturn(replyCS);
     }
 
-    private void setBaseAttrs(final vppBridgeDomainDetails bdDetails, final String bdn, final int i) {
-        bdDetails.name = bdn;
-        bdDetails.arpTerm = true;
-        bdDetails.bdId = i;
-        bdDetails.bviInterfaceName = "ifc";
-        bdDetails.flood = true;
-        bdDetails.forward = true;
-        bdDetails.learn = true;
-        bdDetails.uuFlood = true;
+    private void whenL2FibTableDumpThenReturn(final List<L2FibTableEntry> entryList) throws ExecutionException, InterruptedException {
+        final CompletionStage<L2FibTableEntryReplyDump> replyCS = mock(CompletionStage.class);
+        final CompletableFuture<L2FibTableEntryReplyDump> replyFuture = mock(CompletableFuture.class);
+        when(replyCS.toCompletableFuture()).thenReturn(replyFuture);
+        final L2FibTableEntryReplyDump reply = new L2FibTableEntryReplyDump();
+        reply.l2FibTableEntry = entryList;
+        when(replyFuture.get()).thenReturn(reply);
+        when(api.l2FibTableDump(any(L2FibTableDump.class))).thenReturn(replyCS);
+    }
+
+    private void whenBridgeDomainDumpThenReturn(final List<BridgeDomainDetails> bdList) throws ExecutionException, InterruptedException {
+        final CompletionStage<BridgeDomainDetailsReplyDump> replyCS = mock(CompletionStage.class);
+        final CompletableFuture<BridgeDomainDetailsReplyDump> replyFuture = mock(CompletableFuture.class);
+        when(replyCS.toCompletableFuture()).thenReturn(replyFuture);
+        final BridgeDomainDetailsReplyDump reply = new BridgeDomainDetailsReplyDump();
+        reply.bridgeDomainDetails = bdList;
+        when(replyFuture.get()).thenReturn(reply);
+
+        doAnswer(invocation -> {
+            BridgeDomainDump request = (BridgeDomainDump)invocation.getArguments()[0];
+            if (request.bdId == -1) {
+                reply.bridgeDomainDetails = bdList;
+            } else {
+                reply.bridgeDomainDetails = Collections.singletonList(bdList.get(request.bdId));
+            }
+            return replyCS;
+        }).when(api).bridgeDomainDump(any(BridgeDomainDump.class));
     }
 
     @Test
     public void testReadAll() throws Exception {
+        final Version version = getVersion();
+        whenShowVersionThenReturn(0, version);
+
+        final List<BridgeDomainDetails> bdList = Arrays.asList(new BridgeDomainDetails(), new BridgeDomainDetails());
+        whenBridgeDomainDumpThenReturn(bdList);
+
         final Multimap<InstanceIdentifier<? extends DataObject>, ? extends DataObject> dataObjects = readerRegistry.readAll(ctx);
         assertEquals(dataObjects.size(), 1);
-        final DataObject dataObject = Iterables.getOnlyElement(dataObjects.get(Iterables.getOnlyElement(dataObjects.keySet())));
-        assertTrue(dataObject instanceof VppState);
-        assertVersion((VppState) dataObject);
-        assertEquals(2, ((VppState) dataObject).getBridgeDomains().getBridgeDomain().size());
-    }
-
-    private void assertVersion(final VppState dataObject) {
-        assertEquals(
-            new VersionBuilder()
-                .setName("test")
-                .setBuildDirectory("1")
-                .setBranch("2")
-                .setBuildDate("33")
-                .build(),
-            dataObject.getVersion());
+        final VppState dataObject = (VppState)Iterables.getOnlyElement(dataObjects.get(Iterables.getOnlyElement(dataObjects.keySet())));
+        assertEquals(version, dataObject.getVersion());
+        assertEquals(2, dataObject.getBridgeDomains().getBridgeDomain().size());
     }
 
     @Test
     public void testReadSpecific() throws Exception {
+        final Version version = getVersion();
+        whenShowVersionThenReturn(0, version);
+        whenBridgeDomainDumpThenReturn(Collections.emptyList());
+
         final Optional<? extends DataObject> read = readerRegistry.read(InstanceIdentifier.create(VppState.class), ctx);
         assertTrue(read.isPresent());
-        assertVersion((VppState) read.get());
+        assertEquals(version, ((VppState) read.get()).getVersion());
     }
 
     @Test
     public void testReadBridgeDomains() throws Exception {
+        final Version version = getVersion();
+        whenShowVersionThenReturn(0, version);
+        whenBridgeDomainDumpThenReturn(Collections.singletonList(new BridgeDomainDetails()));
+
         VppState readRoot = (VppState) readerRegistry.read(InstanceIdentifier.create(VppState.class), ctx).get();
 
         Optional<? extends DataObject> read =
@@ -191,6 +186,16 @@ public class VppStateTest {
      */
     @Test
     public void testReadL2Fib() throws Exception {
+        final BridgeDomainDetails bd = new BridgeDomainDetails();
+        bd.bdId = 0;
+        final String bdName = "bdn1";
+        bdContext.addName(bd.bdId, bdName);
+        whenBridgeDomainDumpThenReturn(Collections.singletonList(bd));
+        final L2FibTableEntry l2FibEntry = new L2FibTableEntry();
+        l2FibEntry.bdId = 0;
+        l2FibEntry.mac = 0x0605040302010000L;
+        whenL2FibTableDumpThenReturn(Collections.singletonList(l2FibEntry));
+
         // Deep child without a dedicated reader with specific l2fib key
         Optional<? extends DataObject> read =
             readerRegistry.read(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child(
@@ -208,10 +213,14 @@ public class VppStateTest {
 
     @Test
     public void testReadBridgeDomainAll() throws Exception {
+        final Version version = getVersion();
+        whenShowVersionThenReturn(0, version);
+        whenBridgeDomainDumpThenReturn(Collections.singletonList(new BridgeDomainDetails()));
+
         VppState readRoot = (VppState) readerRegistry.read(InstanceIdentifier.create(VppState.class), ctx).get();
 
         final CompositeListReader<BridgeDomain, BridgeDomainKey, BridgeDomainBuilder> bridgeDomainReader =
-            VppStateUtils.getBridgeDomainReader(api);
+            VppStateTestUtils.getBridgeDomainReader(api, bdContext, interfaceContext);
 
         final List<BridgeDomain> read =
             bridgeDomainReader.readList(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child(
@@ -222,24 +231,25 @@ public class VppStateTest {
 
     @Test
     public void testReadBridgeDomain() throws Exception {
+        final BridgeDomainDetails bd = new BridgeDomainDetails();
+        bd.bdId = 0;
+        final String bdName = "bdn1";
+        bdContext.addName(bd.bdId, bdName);
+        whenBridgeDomainDumpThenReturn(Collections.singletonList(bd));
+        whenShowVersionThenReturn(0, getVersion());
+
         VppState readRoot = (VppState) readerRegistry.read(InstanceIdentifier.create(VppState.class), ctx).get();
 
         final Optional<? extends DataObject> read =
             readerRegistry.read(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child(
-                BridgeDomain.class, new BridgeDomainKey("bdn1")), ctx);
+                BridgeDomain.class, new BridgeDomainKey(bdName)), ctx);
 
         assertTrue(read.isPresent());
-        assertEquals(Iterables.find(readRoot.getBridgeDomains().getBridgeDomain(), new Predicate<BridgeDomain>() {
-            @Override
-            public boolean apply(final BridgeDomain input) {
-                return input.getKey().getName().equals("bdn1");
-            }
-        }), read.get());
+        assertEquals(Iterables.find(readRoot.getBridgeDomains().getBridgeDomain(),
+                input -> input.getKey().getName().equals(bdName)), read.get());
     }
 
-    // FIXME
-    @Ignore("Bridge domain customizer does not check whether the bd exists or not and fails with NPE, add it there")
-    @Test
+    @Test(expected = IllegalArgumentException.class)
     public void testReadBridgeDomainNotExisting() throws Exception {
         final Optional<? extends DataObject> read =
             readerRegistry.read(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child(
@@ -249,6 +259,8 @@ public class VppStateTest {
 
     @Test
     public void testReadVersion() throws Exception {
+        whenShowVersionThenReturn(0, getVersion());
+        whenBridgeDomainDumpThenReturn(Collections.emptyList());
         VppState readRoot = (VppState) readerRegistry.read(InstanceIdentifier.create(VppState.class), ctx).get();
 
         Optional<? extends DataObject> read =
@@ -19,10 +19,11 @@ package io.fd.honeycomb.v3po.translate.v3po.vppstate;
 import io.fd.honeycomb.v3po.translate.impl.read.CompositeChildReader;
 import io.fd.honeycomb.v3po.translate.impl.read.CompositeListReader;
 import io.fd.honeycomb.v3po.translate.impl.read.CompositeRootReader;
+import io.fd.honeycomb.v3po.translate.read.ChildReader;
+import io.fd.honeycomb.v3po.translate.util.RWUtils;
 import io.fd.honeycomb.v3po.translate.util.read.ReflexiveChildReaderCustomizer;
 import io.fd.honeycomb.v3po.translate.util.read.ReflexiveRootReaderCustomizer;
-import io.fd.honeycomb.v3po.translate.util.RWUtils;
-import io.fd.honeycomb.v3po.translate.read.ChildReader;
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import java.util.ArrayList;
 import java.util.List;
 import javax.annotation.Nonnull;
@@ -35,43 +36,47 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomainBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomainKey;
 import org.opendaylight.yangtools.yang.binding.ChildOf;
-import org.openvpp.vppjapi.vppApi;
+import org.openvpp.jvpp.future.FutureJVpp;
 
-final class VppStateUtils {
+final class VppStateTestUtils {
 
-    public VppStateUtils() {}
+    public VppStateTestUtils() {
+    }
 
     /**
      * Create root VppState reader with all its children wired
      */
-    static CompositeRootReader<VppState, VppStateBuilder> getVppStateReader(@Nonnull final vppApi vppApi) {
+    static CompositeRootReader<VppState, VppStateBuilder> getVppStateReader(@Nonnull final FutureJVpp futureJVpp,
+                                                                            @Nonnull final NamingContext bdContext,
+                                                                            @Nonnull final NamingContext interfaceContext) {
 
         final ChildReader<Version> versionReader = new CompositeChildReader<>(
-            Version.class, new VersionCustomizer(vppApi));
+                Version.class, new VersionCustomizer(futureJVpp));
 
         final CompositeListReader<BridgeDomain, BridgeDomainKey, BridgeDomainBuilder> bridgeDomainReader =
-            getBridgeDomainReader(vppApi);
+                getBridgeDomainReader(futureJVpp, bdContext, interfaceContext);
 
         final ChildReader<BridgeDomains> bridgeDomainsReader = new CompositeChildReader<>(
-            BridgeDomains.class,
-            RWUtils.singletonChildReaderList(bridgeDomainReader),
-            new ReflexiveChildReaderCustomizer<>(BridgeDomainsBuilder.class));
+                BridgeDomains.class,
+                RWUtils.singletonChildReaderList(bridgeDomainReader),
+                new ReflexiveChildReaderCustomizer<>(BridgeDomainsBuilder.class));
 
         final List<ChildReader<? extends ChildOf<VppState>>> childVppReaders = new ArrayList<>();
         childVppReaders.add(versionReader);
         childVppReaders.add(bridgeDomainsReader);
 
         return new CompositeRootReader<>(
-            VppState.class,
-            childVppReaders,
-            RWUtils.<VppState>emptyAugReaderList(),
-            new ReflexiveRootReaderCustomizer<>(VppStateBuilder.class));
+                VppState.class,
+                childVppReaders,
+                RWUtils.<VppState>emptyAugReaderList(),
+                new ReflexiveRootReaderCustomizer<>(VppStateBuilder.class));
     }
 
     static CompositeListReader<BridgeDomain, BridgeDomainKey, BridgeDomainBuilder> getBridgeDomainReader(
-        final @Nonnull vppApi vppApi) {
+            final @Nonnull FutureJVpp futureJVpp, @Nonnull final NamingContext bdContext,
+            @Nonnull final NamingContext interfaceContext) {
         return new CompositeListReader<>(
-        BridgeDomain.class,
-        new BridgeDomainCustomizer(vppApi));
+                BridgeDomain.class,
+                new BridgeDomainCustomizer(futureJVpp, bdContext, interfaceContext));
     }
 }
index 9e6d742..77bb3a5 100644 (file)
@@ -68,7 +68,7 @@ public class VppInitializer extends AbstractDataTreeConverter<VppState, Vpp> {
                     builder.setFlood(input.isFlood());
                     builder.setForward(input.isForward());
                     builder.setKey(new BridgeDomainKey(input.getKey().getName()));
-                    // TODO bdBuilder.setL2Fib(bd.getL2Fib());
+                    // bdBuilder.setL2Fib(bd.getL2Fib()); // TODO we need state=>oper converter for L2Fib
                     builder.setName(input.getName());
                     return builder.build();
                 }
diff --git a/v3po/vpp-japi-cfg/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/japi/cfg/rev160406/VppJapiImplModule.java b/v3po/vpp-japi-cfg/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/japi/cfg/rev160406/VppJapiImplModule.java
deleted file mode 100644 (file)
index 3f092e9..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-package org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.japi.cfg.rev160406;
-
-import java.io.IOException;
-import org.openvpp.vppjapi.vppApi;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class VppJapiImplModule extends org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.japi.cfg.rev160406.AbstractVppJapiImplModule {
-
-    private static final Logger LOG = LoggerFactory.getLogger(VppJapiImplModule.class);
-
-    public VppJapiImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
-        super(identifier, dependencyResolver);
-    }
-
-    public VppJapiImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.japi.cfg.rev160406.VppJapiImplModule oldModule, java.lang.AutoCloseable oldInstance) {
-        super(identifier, dependencyResolver, oldModule, oldInstance);
-    }
-
-    @Override
-    public void customValidation() {
-        // add custom validation form module attributes here.
-    }
-
-    @Override
-    public java.lang.AutoCloseable createInstance() {
-        try {
-            final vppApi vppApi = new vppApi(getName());
-            LOG.info("VPP-INFO: VPP api client connection established");
-            return vppApi;
-        } catch (IOException e) {
-            LOG.error("VPP-ERROR: VPP api client connection failed", e);
-            throw new IllegalStateException("Unable to open vpp API", e);
-        }
-    }
-
-}
diff --git a/v3po/vpp-japi-cfg/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/japi/cfg/rev160406/VppJapiImplModuleFactory.java b/v3po/vpp-japi-cfg/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/japi/cfg/rev160406/VppJapiImplModuleFactory.java
deleted file mode 100644 (file)
index 6b3724c..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
-* Generated file
-*
-* Generated from: yang module name: vpp-japi-cfg yang module local name: vpp-japi-impl
-* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
-* Generated at: Wed Apr 06 11:06:28 CEST 2016
-*
-* Do not modify this file unless it is present under src/main directory
-*/
-package org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.japi.cfg.rev160406;
-public class VppJapiImplModuleFactory extends org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.japi.cfg.rev160406.AbstractVppJapiImplModuleFactory {
-
-}
similarity index 94%
rename from v3po/vpp-japi-cfg/pom.xml
rename to v3po/vpp-jvpp-cfg/pom.xml
index 3e3424a..9a864c8 100644 (file)
 
     <modelVersion>4.0.0</modelVersion>
     <groupId>io.fd.honeycomb.v3po</groupId>
-    <artifactId>vpp-japi-cfg</artifactId>
+    <artifactId>vpp-jvpp-cfg</artifactId>
     <version>1.0.0-SNAPSHOT</version>
     <packaging>bundle</packaging>
 
     <dependencies>
         <dependency>
             <groupId>io.fd.vpp</groupId>
-            <artifactId>vppjapi</artifactId>
+            <artifactId>jvpp</artifactId>
             <version>1.0.0-SNAPSHOT</version>
         </dependency>
     </dependencies>
 
 <snapshot>
     <required-capabilities>
-        <capability>urn:honeycomb:params:xml:ns:yang:vpp:japi:cfg?module=vpp-japi-cfg&amp;revision=2016-04-06</capability>
+        <capability>urn:honeycomb:params:xml:ns:yang:vpp:jvpp:cfg?module=vpp-jvpp-cfg&amp;revision=2016-04-06</capability>
     </required-capabilities>
     <configuration>
 
         <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
             <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
                 <module>
-                    <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:japi:cfg">prefix:vpp-japi-impl</type>
-                    <name>vpp-japi</name>
+                    <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:jvpp:cfg">prefix:vpp-jvpp-impl</type>
+                    <name>vpp-jvpp</name>
                 </module>
             </modules>
 
             <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
                 <service>
-                    <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:japi:cfg">prefix:vpp-japi</type>
+                    <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:jvpp:cfg">prefix:vpp-jvpp</type>
                     <instance>
-                        <name>vpp-japi</name>
-                        <provider>/modules/module[type='vpp-japi-impl'][name='vpp-japi']
+                        <name>vpp-jvpp</name>
+                        <provider>/modules/module[type='vpp-jvpp-impl'][name='vpp-jvpp']
                         </provider>
                     </instance>
                 </service>
diff --git a/v3po/vpp-jvpp-cfg/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/jvpp/cfg/rev160406/VppJvppImplModule.java b/v3po/vpp-jvpp-cfg/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/jvpp/cfg/rev160406/VppJvppImplModule.java
new file mode 100644 (file)
index 0000000..4c70f0b
--- /dev/null
@@ -0,0 +1,45 @@
+package org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.jvpp.cfg.rev160406;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import org.openvpp.jvpp.JVppImpl;
+import org.openvpp.jvpp.VppJNIConnection;
+import org.openvpp.jvpp.dto.JVppReply;
+import org.openvpp.jvpp.future.FutureJVppFacade;
+import org.openvpp.jvpp.future.FutureJVppFacadeCallback;
+
+public class VppJvppImplModule extends org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.jvpp.cfg.rev160406.AbstractVppJvppImplModule {
+    public VppJvppImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+        super(identifier, dependencyResolver);
+    }
+
+    public VppJvppImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.jvpp.cfg.rev160406.VppJvppImplModule oldModule, java.lang.AutoCloseable oldInstance) {
+        super(identifier, dependencyResolver, oldModule, oldInstance);
+    }
+
+    @Override
+    public void customValidation() {
+        // add custom validation form module attributes here.
+    }
+
+    @Override
+    public java.lang.AutoCloseable createInstance() {
+        try {
+            final Map<Integer, CompletableFuture<? extends JVppReply<?>>> map = new HashMap<>();
+            final JVppImpl jVpp =
+                new JVppImpl(VppJNIConnection.create(getName(), new FutureJVppFacadeCallback(map)));
+            return new FutureJVppFacade(jVpp, map) {
+                @Override
+                public void close() throws Exception {
+                    super.close();
+                    jVpp.close();
+                }
+            };
+        } catch (IOException e) {
+            throw new IllegalStateException("Unable to open VPP management connection", e);
+        }
+    }
+
+}
diff --git a/v3po/vpp-jvpp-cfg/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/jvpp/cfg/rev160406/VppJvppImplModuleFactory.java b/v3po/vpp-jvpp-cfg/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/jvpp/cfg/rev160406/VppJvppImplModuleFactory.java
new file mode 100644 (file)
index 0000000..7115109
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+* Generated file
+*
+* Generated from: yang module name: vpp-jvpp-cfg yang module local name: vpp-jvpp-impl
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Fri Apr 29 11:20:56 CEST 2016
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.jvpp.cfg.rev160406;
+public class VppJvppImplModuleFactory extends org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.jvpp.cfg.rev160406.AbstractVppJvppImplModuleFactory {
+
+}
@@ -1,7 +1,7 @@
-module vpp-japi-cfg {
+module vpp-jvpp-cfg {
     yang-version 1;
-    namespace "urn:honeycomb:params:xml:ns:yang:vpp:japi:cfg";
-    prefix "vjc";
+    namespace "urn:honeycomb:params:xml:ns:yang:vpp:jvpp:cfg";
+    prefix "vjvppc";
 
     import config { prefix config; revision-date 2013-04-05; }
 
@@ -14,19 +14,19 @@ module vpp-japi-cfg {
             "Initial revision.";
     }
 
-    identity vpp-japi {
+    identity vpp-jvpp {
         base "config:service-type";
-        config:java-class org.openvpp.vppjapi.vppApi;
+        config:java-class org.openvpp.jvpp.future.FutureJVpp;
     }
 
-    identity vpp-japi-impl {
+    identity vpp-jvpp-impl {
         base config:module-type;
-        config:provided-service vpp-japi;
+        config:provided-service vpp-jvpp;
     }
 
     augment "/config:modules/config:module/config:configuration" {
-        case vpp-japi-impl {
-            when "/config:modules/config:module/config:type = 'vpp-japi-impl'";
+        case vpp-jvpp-impl {
+            when "/config:modules/config:module/config:type = 'vpp-jvpp-impl'";
 
             leaf name {
                 type string;
index b63b6d4..51b4c02 100644 (file)
@@ -17,9 +17,9 @@
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <parent>
         <groupId>io.fd.honeycomb.common</groupId>
-        <artifactId>api-parent</artifactId>
+        <artifactId>impl-parent</artifactId>
         <version>1.0.0-SNAPSHOT</version>
-        <relativePath>../../common/api-parent</relativePath>
+        <relativePath>../../common/impl-parent</relativePath>
     </parent>
 
     <modelVersion>4.0.0</modelVersion>
@@ -36,7 +36,7 @@
         </dependency>
         <dependency>
             <groupId>io.fd.vpp</groupId>
-            <artifactId>vppjapi</artifactId>
+            <artifactId>jvpp</artifactId>
             <version>1.0.0-SNAPSHOT</version>
         </dependency>
 
 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;
 
 /**
  * Abstract utility to hold the vppApi reference.
  */
 @Beta
-public abstract class VppApiCustomizer {
+public abstract class FutureJVppCustomizer {
 
-    private final org.openvpp.vppjapi.vppApi vppApi;
+    private final FutureJVpp futureJvpp;
 
-    public VppApiCustomizer(final org.openvpp.vppjapi.vppApi vppApi) {
-        this.vppApi = vppApi;
+    public FutureJVppCustomizer(@Nonnull final FutureJVpp futureJvpp) {
+        this.futureJvpp = Preconditions.checkNotNull(futureJvpp, "futureJvpp should not be null");
     }
 
     /**
@@ -35,7 +38,7 @@ public abstract class VppApiCustomizer {
      *
      * @return vppApi reference
      */
-    public org.openvpp.vppjapi.vppApi getVppApi() {
-        return vppApi;
+    public FutureJVpp getFutureJVpp() {
+        return futureJvpp;
     }
 }
diff --git a/v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/NamingContext.java b/v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/NamingContext.java
new file mode 100644 (file)
index 0000000..96d908e
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * 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 com.google.common.collect.BiMap;
+import com.google.common.collect.HashBiMap;
+import javax.annotation.Nonnull;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Naming context keeping a mapping between int index and string name.
+ * Provides artificial names to unknown indices.
+ */
+public final class NamingContext implements AutoCloseable {
+
+    private static final Logger LOG = LoggerFactory.getLogger(NamingContext.class);
+
+    private final BiMap<String, Integer> nameMapping = HashBiMap.create();
+    private final String artificialNamePrefix;
+
+    public NamingContext(final String artificialNamePrefix) {
+        this.artificialNamePrefix = artificialNamePrefix;
+    }
+
+    @Nonnull
+    public synchronized String getName(final int index) {
+        if(!nameMapping.inverse().containsKey(index)) {
+            final String artificialName = getArtificialName(index);
+            LOG.info("Assigning artificial name: {} for index: {}", artificialName, index);
+            addName(index, artificialName);
+        }
+        return nameMapping.inverse().get(index);
+    }
+
+    @Nonnull
+    public synchronized boolean containsName(final int index) {
+        return nameMapping.inverse().containsKey(index);
+    }
+
+    @Nonnull
+    public synchronized void addName(final int index, final String name) {
+        nameMapping.put(name, index);
+    }
+
+    @Nonnull
+    public synchronized int removeName(final String name) {
+        return nameMapping.remove(name);
+    }
+
+    /**
+     * Returns index value associated with the given name.
+     *
+     * @param name the name whose associated index value is to be returned
+     * @return integer index value matching supplied name
+     * @throws IllegalArgumentException if name was not found
+     */
+    @Nonnull
+    public synchronized int getIndex(String name) {
+        checkArgument(nameMapping.containsKey(name), "Name %s not found. Known names: %s",
+                name, nameMapping);
+        return nameMapping.get(name);
+    }
+
+    @Nonnull
+    public synchronized boolean containsIndex(String interfaceName) {
+        return nameMapping.containsKey(interfaceName);
+    }
+
+    public String getArtificialName(final int index) {
+        return artificialNamePrefix + index;
+    }
+
+    @Override
+    public void close() throws Exception {
+        nameMapping.clear();
+    }
+}
diff --git a/v3po/vpp-translate-utils/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/util/rev160406/NamingContextImplModule.java b/v3po/vpp-translate-utils/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/util/rev160406/NamingContextImplModule.java
new file mode 100644 (file)
index 0000000..81cecb1
--- /dev/null
@@ -0,0 +1,24 @@
+package org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.util.rev160406;
+
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
+
+public class NamingContextImplModule extends org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.util.rev160406.AbstractNamingContextImplModule {
+    public NamingContextImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+        super(identifier, dependencyResolver);
+    }
+
+    public NamingContextImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.util.rev160406.NamingContextImplModule oldModule, java.lang.AutoCloseable oldInstance) {
+        super(identifier, dependencyResolver, oldModule, oldInstance);
+    }
+
+    @Override
+    public void customValidation() {
+        // add custom validation form module attributes here.
+    }
+
+    @Override
+    public java.lang.AutoCloseable createInstance() {
+        return new NamingContext(getArtificialNamePrefix());
+    }
+
+}
diff --git a/v3po/vpp-translate-utils/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/util/rev160406/NamingContextImplModuleFactory.java b/v3po/vpp-translate-utils/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/util/rev160406/NamingContextImplModuleFactory.java
new file mode 100644 (file)
index 0000000..c777daf
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+* Generated file
+*
+* Generated from: yang module name: vpp-util yang module local name: naming-context-impl
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Mon May 02 10:57:32 CEST 2016
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.util.rev160406;
+public class NamingContextImplModuleFactory extends org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.util.rev160406.AbstractNamingContextImplModuleFactory {
+
+}
diff --git a/v3po/vpp-translate-utils/src/main/yang/vpp-util.yang b/v3po/vpp-translate-utils/src/main/yang/vpp-util.yang
new file mode 100644 (file)
index 0000000..01e759d
--- /dev/null
@@ -0,0 +1,37 @@
+module vpp-util {
+    yang-version 1;
+    namespace "urn:honeycomb:params:xml:ns:yang:vpp:util";
+    prefix "vpp-u";
+
+    import config { prefix config; revision-date 2013-04-05; }
+
+    description
+        "This module contains utilities for vpp readers/writers";
+
+    revision "2016-04-06" {
+        description
+            "Initial revision.";
+    }
+
+    identity naming-context {
+        base "config:service-type";
+        config:java-class io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
+    }
+
+    identity naming-context-impl {
+        base config:module-type;
+        config:provided-service naming-context;
+    }
+
+    augment "/config:modules/config:module/config:configuration" {
+        case naming-context-impl {
+            when "/config:modules/config:module/config:type = 'naming-context-impl'";
+
+            leaf artificial-name-prefix {
+                type string;
+            }
+
+        }
+    }
+
+}
\ No newline at end of file