HONEYCOMB-34: Config tree initialization using ModifiableDataTree dependency
authorMarek Gradzki <[email protected]>
Mon, 11 Apr 2016 06:56:06 +0000 (08:56 +0200)
committerMarek Gradzki <[email protected]>
Tue, 12 Apr 2016 09:04:11 +0000 (11:04 +0200)
Change-Id: I9fa6119a92cc1979ed6f3364bb74e856a7a712c5
Signed-off-by: Marek Gradzki <[email protected]>
20 files changed:
v3po/data-api/src/main/java/io/fd/honeycomb/v3po/data/ModifiableDataTree.java
v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ConfigDataTree.java
v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/DataBroker.java
v3po/data-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/data/impl/rev160411/ConfigDataTreeModule.java
v3po/data-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/data/impl/rev160411/OperationalDataTreeModule.java
v3po/impl/src/main/config/default-config.xml
v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/VppDataBrokerInitializationProvider.java
v3po/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/v3po/impl/rev141210/DataBrokerModule.java [new file with mode: 0644]
v3po/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/v3po/impl/rev141210/DataBrokerModuleFactory.java [new file with mode: 0644]
v3po/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/v3po/impl/rev141210/V3poModule.java
v3po/impl/src/main/yang/v3po-impl.yang
v3po/vpp-cfg-init/pom.xml
v3po/vpp-cfg-init/src/main/java/io/fd/honeycomb/v3po/vpp/data/init/AbstractDataTreeConverter.java [new file with mode: 0644]
v3po/vpp-cfg-init/src/main/java/io/fd/honeycomb/v3po/vpp/data/init/DataTreeInitializer.java [new file with mode: 0644]
v3po/vpp-cfg-init/src/main/java/io/fd/honeycomb/v3po/vpp/data/init/InitializerRegistry.java
v3po/vpp-cfg-init/src/main/java/io/fd/honeycomb/v3po/vpp/data/init/InitializerRegistryImpl.java
v3po/vpp-cfg-init/src/main/java/io/fd/honeycomb/v3po/vpp/data/init/VppInitializer.java [new file with mode: 0644]
v3po/vpp-cfg-init/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/data/init/rev160407/VppConfigurationInitializerModule.java
v3po/vpp-cfg-init/src/main/yang/vpp-cfg-init.yang
v3po/vpp-cfg-init/src/test/java/io/fd/honeycomb/v3po/vpp/data/init/InitializerRegistryImplTest.java [new file with mode: 0644]

index 8b21ddf..a3b5c9c 100644 (file)
@@ -35,6 +35,14 @@ public interface ModifiableDataTree {
      */
     void modify(final DataTreeModification modification) throws DataValidationFailedException, TranslationException;
 
+    /**
+     * Initializes data tree using supplied modification.
+     *
+     * @param modification data tree modification
+     * @throws DataValidationFailedException if modification data is not valid
+     */
+    void initialize(final DataTreeModification modification) throws DataValidationFailedException;
+
     /**
      * Creates read-only snapshot of a ModifiableDataTree.
      *
index 59a555f..b90a57a 100644 (file)
@@ -90,6 +90,8 @@ public final class ConfigDataTree implements ModifiableDataTree {
     @Override
     public void modify(final DataTreeModification modification)
             throws DataValidationFailedException, TranslationException {
+        LOG.debug("ConfigDataTree.modify");
+
         dataTree.validate(modification);
 
         final DataTreeCandidate candidate = dataTree.prepare(modification);
@@ -135,6 +137,14 @@ public final class ConfigDataTree implements ModifiableDataTree {
         dataTree.commit(candidate);
     }
 
+    @Override
+    public void initialize(final DataTreeModification modification) throws DataValidationFailedException {
+        LOG.debug("ConfigDataTree.initialize");
+        dataTree.validate(modification);
+        final DataTreeCandidate candidate = dataTree.prepare(modification);
+        dataTree.commit(candidate);
+    }
+
     private Map<InstanceIdentifier<?>, DataObject> extractNetconfData(
             final Optional<NormalizedNode<?, ?>> parentOptional) {
         if (parentOptional.isPresent()) {
index 47b27f7..a0b5851 100644 (file)
@@ -35,6 +35,8 @@ import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Data Broker which provides data transaction functionality for YANG capable data provider using {@link NormalizedNode}
@@ -42,6 +44,7 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
  */
 public class DataBroker implements DOMDataBroker {
 
+    private static final Logger LOG = LoggerFactory.getLogger(DataBroker.class);
     private final ReadableDataTree operationalDataTree;
     private final ModifiableDataTree configDataTree;
 
@@ -56,16 +59,18 @@ public class DataBroker implements DOMDataBroker {
         this.operationalDataTree =
                 Preconditions.checkNotNull(operationalDataTree, "operationalDataTree should not be null");
         this.configDataTree = Preconditions.checkNotNull(configDataTree, "configDataTree should not be null");
+        LOG.trace("DataBroker({}).init() operationalDataTree={}, configDataTree={}", this, operationalDataTree, configDataTree);
     }
 
     @Override
     public DOMDataReadOnlyTransaction newReadOnlyTransaction() {
+        LOG.trace("DataBroker({}).newReadOnlyTransaction()", this);
         return new ReadOnlyTransaction(operationalDataTree, configDataTree.takeSnapshot());
     }
 
     @Override
     public DOMDataReadWriteTransaction newReadWriteTransaction() {
-        // todo use the same snapshot
+        LOG.trace("DataBroker({}).newReadWriteTransaction()", this);
         final DataTreeSnapshot configSnapshot = configDataTree.takeSnapshot();
         final DOMDataReadOnlyTransaction readOnlyTx = new ReadOnlyTransaction(operationalDataTree, configSnapshot);
         final DOMDataWriteTransaction writeOnlyTx = new WriteTransaction(configDataTree, configSnapshot);
@@ -74,6 +79,7 @@ public class DataBroker implements DOMDataBroker {
 
     @Override
     public DOMDataWriteTransaction newWriteOnlyTransaction() {
+        LOG.trace("DataBroker({}).newWriteOnlyTransaction()", this);
         return new WriteTransaction(configDataTree);
     }
 
index 115eb06..19267b1 100644 (file)
@@ -9,9 +9,14 @@ import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.TreeType;
 import org.opendaylight.yangtools.yang.data.impl.schema.tree.InMemoryDataTreeFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class ConfigDataTreeModule extends
         org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.data.impl.rev160411.AbstractConfigDataTreeModule {
+
+    private static final Logger LOG = LoggerFactory.getLogger(ConfigDataTreeModule.class);
+
     public ConfigDataTreeModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
                                 org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
         super(identifier, dependencyResolver);
@@ -31,6 +36,7 @@ public class ConfigDataTreeModule extends
 
     @Override
     public java.lang.AutoCloseable createInstance() {
+        LOG.info("ConfigDataTreeModule.createInstance()");
         final DataTree dataTree = InMemoryDataTreeFactory.getInstance().create(TreeType.CONFIGURATION);
         dataTree.setSchemaContext(getSchemaServiceDependency().getGlobalContext());
         return new CloseableConfigDataTree(
@@ -47,17 +53,26 @@ public class ConfigDataTreeModule extends
 
         @Override
         public void close() throws Exception {
+            LOG.info("CloseableConfigDataTree.close()");
             // NOP
         }
 
         @Override
         public void modify(final DataTreeModification modification)
                 throws DataValidationFailedException, TranslationException {
+            LOG.trace("CloseableConfigDataTree.modify modification={}", modification);
             delegate.modify(modification);
         }
 
+        @Override
+        public void initialize(final DataTreeModification modification) throws DataValidationFailedException {
+            LOG.trace("CloseableConfigDataTree.initialize modification={}", modification);
+            delegate.initialize(modification);
+        }
+
         @Override
         public DataTreeSnapshot takeSnapshot() {
+            LOG.trace("CloseableConfigDataTree.takeSnapshot");
             return delegate.takeSnapshot();
         }
     }
index 48053c3..0034b12 100644 (file)
@@ -8,9 +8,14 @@ import javax.annotation.Nonnull;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class OperationalDataTreeModule extends
         org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.data.impl.rev160411.AbstractOperationalDataTreeModule {
+
+    private static final Logger LOG = LoggerFactory.getLogger(OperationalDataTreeModule.class);
+
     public OperationalDataTreeModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
                                      org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
         super(identifier, dependencyResolver);
@@ -30,6 +35,7 @@ public class OperationalDataTreeModule extends
 
     @Override
     public java.lang.AutoCloseable createInstance() {
+        LOG.info("OperationalDataTreeModule.createInstance()");
         return new CloseableOperationalDataTree(
                 new OperationalDataTree(getSerializerDependency(), getSchemaServiceDependency().getGlobalContext(),
                         getReaderRegistryDependency()));
@@ -45,12 +51,14 @@ public class OperationalDataTreeModule extends
 
         @Override
         public void close() throws Exception {
+            LOG.info("CloseableOperationalDataTree.close()");
             // NOP
         }
 
         @Override
         public CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> read(
                 @Nonnull final YangInstanceIdentifier path) {
+            LOG.trace("CloseableOperationalDataTree.read path={}", path);
             return delegate.read(path);
         }
     }
index e35c3a4..328d002 100644 (file)
     <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:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:dom-inmemory-data-broker</type>-->
-          <!--<name>netconf-inmemory-data-broker</name>-->
-
-          <!--<schema-service>-->
-            <!--<type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>-->
-            <!--<name>yang-schema-service</name>-->
-          <!--</schema-service>-->
-
-          <!--<config-data-store>-->
-            <!--<type xmlns:config-dom-store-spi="urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:config-dom-store">config-dom-store-spi:config-dom-datastore</type>-->
-            <!--<name>netconf-config-store-service</name>-->
-          <!--</config-data-store>-->
-
-          <!--<operational-data-store>-->
-            <!--<type xmlns:operational-dom-store-spi="urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:operational-dom-store">operational-dom-store-spi:operational-dom-datastore</type>-->
-            <!--<name>netconf-operational-store-service</name>-->
-          <!--</operational-data-store>-->
-        <!--</module>-->
-
-        <!--<module>-->
-          <!--<type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-forwarded-data-broker</type>-->
-          <!--<name>honeycomb-binding-data-broker</name>-->
-          <!--<binding-forwarded-data-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">-->
-
-            <!--&lt;!&ndash;TODO &ndash;&gt;-->
-            <!--&lt;!&ndash;<dom-async-broker>&ndash;&gt;-->
-              <!--&lt;!&ndash;<type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-async-data-broker</type>&ndash;&gt;-->
-              <!--&lt;!&ndash;<name>honeycomb-dom-data-broker</name>&ndash;&gt;-->
-            <!--&lt;!&ndash;</dom-async-broker>&ndash;&gt;-->
-
-            <!--<dom-async-broker>-->
-              <!--<type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-async-data-broker</type>-->
-              <!--<name>netconf-inmemory-data-broker</name>-->
-            <!--</dom-async-broker>-->
-
-            <!--<schema-service>-->
-              <!--<type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>-->
-              <!--<name>yang-schema-service</name>-->
-            <!--</schema-service>-->
-            <!--<binding-mapping-service>-->
-              <!--<type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding:binding-dom-mapping-service</type>-->
-              <!--<name>runtime-mapping-singleton</name>-->
-            <!--</binding-mapping-service>-->
-          <!--</binding-forwarded-data-broker>-->
-        <!--</module>-->
-
-
         <module>
           <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:utils">prefix:delegating-reader-registry</type>
           <name>read-registry</name>
           </reader-registry>
         </module>
 
+        <module>
+          <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:v3po:impl">prefix:honeycomb-dom-data-broker</type>
+          <name>honeycomb-dom-data-broker</name>
+          <config-data-tree>
+            <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:data:api">prefix:honeycomb-modifiable-data-tree</type>
+            <name>config-data-tree</name>
+          </config-data-tree>
+          <operational-data-tree>
+            <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:data:api">prefix:honeycomb-readable-data-tree</type>
+            <name>operational-data-tree</name>
+          </operational-data-tree>
+        </module>
+
+        <module>
+          <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-forwarded-data-broker</type>
+          <name>honeycomb-binding-data-broker</name>
+          <binding-forwarded-data-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
+
+            <dom-async-broker>
+              <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-async-data-broker</type>
+              <name>honeycomb-dom-data-broker</name>
+            </dom-async-broker>
+            <schema-service>
+              <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
+              <name>yang-schema-service</name>
+            </schema-service>
+            <binding-mapping-service>
+              <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding:binding-dom-mapping-service</type>
+              <name>runtime-mapping-singleton</name>
+            </binding-mapping-service>
+          </binding-forwarded-data-broker>
+        </module>
+
         <module>
           <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:v3po:impl">prefix:v3po</type>
           <name>v3po-default</name>
             <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:api">prefix:honeycomb-writer-registry</type>
             <name>write-registry</name>
           </writer-registry>
-          <binding-normalized-node-serializer>
+          <serializer>
             <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-dom-mapping-service</type>
             <name>runtime-mapping-singleton</name>
-          </binding-normalized-node-serializer>
+          </serializer>
           <config-data-tree>
             <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:data:api">prefix:honeycomb-modifiable-data-tree</type>
             <name>config-data-tree</name>
             <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:api">prefix:honeycomb-reader-registry</type>
             <name>read-registry</name>
           </reader-registry>
+          <config-data-tree>
+            <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:data:api">prefix:honeycomb-modifiable-data-tree</type>
+            <name>config-data-tree</name>
+          </config-data-tree>
+          <serializer>
+            <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding:binding-dom-mapping-service</type>
+            <name>runtime-mapping-singleton</name>
+          </serializer>
         </module>
 
       </modules>
 
       <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
 
-        <!--<service>-->
-          <!--<type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-async-data-broker</type>-->
-          <!--<instance>-->
-            <!--<name>netconf-inmemory-data-broker</name>-->
-            <!--<provider>/modules/module[type='dom-inmemory-data-broker'][name='netconf-inmemory-data-broker']</provider>-->
-          <!--</instance>-->
-        <!--</service>-->
-
-        <!--<service>-->
-          <!--<type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-async-data-broker</type>-->
-          <!--<instance>-->
-            <!--<name>honeycomb-binding-data-broker</name>-->
-            <!--<provider>/modules/module[type='binding-forwarded-data-broker'][name='honeycomb-binding-data-broker']</provider>-->
-          <!--</instance>-->
-        <!--</service>-->
+        <service>
+          <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-async-data-broker</type>
+          <instance>
+            <name>honeycomb-dom-data-broker</name>
+            <provider>/modules/module[type='honeycomb-dom-data-broker'][name='honeycomb-dom-data-broker']</provider>
+          </instance>
+        </service>
 
+        <service>
+          <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-async-data-broker</type>
+          <instance>
+            <name>honeycomb-binding-data-broker</name>
+            <provider>/modules/module[type='binding-forwarded-data-broker'][name='honeycomb-binding-data-broker']</provider>
+          </instance>
+        </service>
 
         <service>
           <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:api">prefix:honeycomb-reader-registry</type>
index 84301b7..bbb004b 100644 (file)
@@ -20,22 +20,13 @@ import static com.google.common.base.Preconditions.checkNotNull;
 
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.AsyncFunction;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
 import io.fd.honeycomb.v3po.data.ModifiableDataTree;
 import io.fd.honeycomb.v3po.data.ReadableDataTree;
 import io.fd.honeycomb.v3po.data.impl.DataBroker;
-import io.fd.honeycomb.v3po.translate.Context;
-import io.fd.honeycomb.v3po.translate.TranslationException;
-import io.fd.honeycomb.v3po.translate.read.ReadContext;
 import io.fd.honeycomb.v3po.translate.read.ReaderRegistry;
 import io.fd.honeycomb.v3po.translate.write.WriterRegistry;
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.List;
-import java.util.Map;
 import javax.annotation.Nonnull;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
@@ -43,19 +34,11 @@ import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
 import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
 import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
 import org.opendaylight.controller.sal.core.api.Broker;
 import org.opendaylight.controller.sal.core.api.Provider;
 import org.opendaylight.controller.sal.core.api.model.SchemaService;
-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.VppState;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomainKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.BridgeDomains;
-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.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
@@ -66,13 +49,9 @@ import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
 import org.opendaylight.yangtools.binding.data.codec.api.BindingNormalizedNodeSerializer;
 import org.opendaylight.yangtools.concepts.ObjectRegistration;
-import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -136,7 +115,7 @@ public final class VppDataBrokerInitializationProvider implements Provider, Auto
         final DOMMountPointService.DOMMountPointBuilder mountPointBuilder = mountPointService.createMountPoint(path);
         mountPointBuilder.addInitialSchemaContext(globalContext);
 
-        broker = initVppDataBroker(operationalDataTree, serializer, configDataTree);
+        broker = new DataBroker(operationalDataTree, configDataTree);
         mountPointBuilder.addService(DOMDataBroker.class, broker);
 
         mountPointRegistration = mountPointBuilder.register();
@@ -145,9 +124,6 @@ public final class VppDataBrokerInitializationProvider implements Provider, Auto
                 mountPoint.getSchemaContext());
 
         createMountPointPlaceholder();
-
-        // TODO initial sync has to go out of here
-//        initialVppConfigSynchronization(broker);
     }
 
     @Override
@@ -168,98 +144,6 @@ public final class VppDataBrokerInitializationProvider implements Provider, Auto
         }
     }
 
-    private DOMDataBroker initVppDataBroker(final ReadableDataTree operationalDataTree,
-                                            final BindingNormalizedNodeSerializer serializer,
-                                            final ModifiableDataTree configDataTree) {
-        // init operational data tree before data broker is initialized
-
-        try {
-            initConfig(serializer, configDataTree);
-        } catch (Exception e) {
-            LOG.warn("Failed to initialize config", e);
-        }
-
-        return new DataBroker(operationalDataTree, configDataTree);
-    }
-
-    // FIXME move to initializer after wiring is finished
-    private void initConfig(final BindingNormalizedNodeSerializer serializer, final ModifiableDataTree configDataTree)
-            throws TranslationException, DataValidationFailedException {
-        LOG.info("Config initialization");
-
-        final Optional<? extends DataObject> data = readerRegistry.read(InstanceIdentifier.create(VppState.class), new ReadContextImpl());
-        LOG.info("Config initialization data={}", data);
-
-        if (data.isPresent()) {
-            // conversion
-            VppState vppOperationalData = (VppState) data.get();
-            final Vpp vppConfigData = convert(vppOperationalData);
-
-            final Map.Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> normalizedData =
-                    serializer.toNormalizedNode(InstanceIdentifier.create(Vpp.class), vppConfigData);
-
-            final DataTreeModification modification = configDataTree.takeSnapshot().newModification();
-            final YangInstanceIdentifier biPath = normalizedData.getKey();
-            final NormalizedNode<?, ?> biData = normalizedData.getValue();
-            LOG.info("Config initialization biPath={}, biData={}", biPath, biData);
-            modification.write(biPath, biData);
-            modification.ready();
-
-            LOG.info("Config writing modification ...");
-            configDataTree.modify(modification); // TODO do not write to VPP
-            LOG.info("Config writing modification written successfully.");
-        } else {
-            LOG.info("Data is not present");
-        }
-    }
-
-    private Vpp convert(final VppState vppState) {
-        final BridgeDomains bridgeDomains = vppState.getBridgeDomains();
-        final List<BridgeDomain> bridgeDomainList = bridgeDomains.getBridgeDomain();
-
-        VppBuilder vppBuilder = new VppBuilder();
-        org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.BridgeDomainsBuilder bdsBuilder = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.BridgeDomainsBuilder();
-        final List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomain>
-                listOfBDs = new ArrayList<>();
-
-        // TODO use reflexion
-        for (BridgeDomain bd : bridgeDomainList) {
-            org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomainBuilder bdBuilder = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomainBuilder();
-            bdBuilder.setLearn(bd.isLearn());
-            bdBuilder.setUnknownUnicastFlood(bd.isUnknownUnicastFlood());
-            bdBuilder.setArpTermination(bd.isArpTermination());
-            bdBuilder.setFlood(bd.isFlood());
-            bdBuilder.setForward(bd.isForward());
-            bdBuilder.setKey(new BridgeDomainKey(bd.getKey().getName()));
-            // TODO bdBuilder.setL2Fib(bd.getL2Fib());
-            bdBuilder.setName(bd.getName());
-            listOfBDs.add(bdBuilder.build());
-        }
-
-        bdsBuilder.setBridgeDomain(listOfBDs);
-        vppBuilder.setBridgeDomains(bdsBuilder.build());
-        return vppBuilder.build();
-    }
-
-
-    // TODO move to utility module
-    private static final class ReadContextImpl implements ReadContext {
-        public final Context ctx = new Context();
-
-        @Nonnull
-        @Override
-        public Context getContext() {
-            return ctx;
-        }
-
-        @Override
-        public void close() {
-            // Make sure to clear the storage in case some customizer stored it  to prevent memory leaks
-            ctx.close();
-        }
-    }
-
-
     /**
      * Writes placeholder data into MD-SAL's global datastore to indicate the presence of VPP mountpoint.
      */
@@ -279,47 +163,6 @@ public final class VppDataBrokerInitializationProvider implements Provider, Auto
         }
     }
 
-    // TODO operational and config models are not 1-1
-    // decide what part of operational data should be written to config during initialization
-    private void initialVppConfigSynchronization(final DOMDataBroker broker) {
-        // read from operational
-        final DOMDataReadOnlyTransaction readTx = broker.newReadOnlyTransaction();
-
-        final YangInstanceIdentifier
-                id = YangInstanceIdentifier.builder().node(VppState.QNAME).node(BridgeDomains.QNAME).build();
-
-        LOG.trace("initialVppStateSynchronization id: {}", id);
-
-        final ListenableFuture<Void> writeFuture = Futures.transform(
-                readTx.read(LogicalDatastoreType.OPERATIONAL, id),
-                new AsyncFunction<Optional<NormalizedNode<?, ?>>, Void>() {
-                    @Override
-                    public ListenableFuture<Void> apply(final Optional<NormalizedNode<?, ?>> readResult)
-                            throws Exception {
-                        if (readResult.isPresent()) {
-                            final DOMDataWriteTransaction writeTx = broker.newWriteOnlyTransaction();
-                            final NormalizedNode<?, ?> node = readResult.get();
-                            LOG.trace("Read result: {}", node);
-
-                            // FIXME
-                            // this will fail because we are reading OPERATIONAL data and writing to CONFIGURATION
-                            // we need to provide extensible way to register initializer that would
-                            // translate between models
-
-                            // writeTx.put(LogicalDatastoreType.CONFIGURATION, id, node);
-                            return writeTx.submit();
-                        } else {
-                            return Futures
-                                    .immediateFailedFuture(
-                                            new IllegalStateException("Failed to read data from VPP."));
-                        }
-                    }
-                });
-
-        Futures.addCallback(writeFuture,
-                new LoggingFuturesCallBack<Void>("Initializing VPP config DataTree failed", LOG));
-    }
-
     public Optional<DOMDataBroker> getBroker() {
         return Optional.fromNullable(broker);
     }
diff --git a/v3po/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/v3po/impl/rev141210/DataBrokerModule.java b/v3po/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/v3po/impl/rev141210/DataBrokerModule.java
new file mode 100644 (file)
index 0000000..76f0144
--- /dev/null
@@ -0,0 +1,104 @@
+package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.impl.rev141210;
+
+import io.fd.honeycomb.v3po.data.impl.DataBroker;
+import java.util.Map;
+import javax.annotation.Nonnull;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBrokerExtension;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataChangeListener;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DataBrokerModule extends
+        org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.impl.rev141210.AbstractDataBrokerModule {
+
+    private static final Logger LOG = LoggerFactory.getLogger(DataBrokerModule.class);
+
+    public DataBrokerModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+                            org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+        super(identifier, dependencyResolver);
+    }
+
+    public DataBrokerModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+                            org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,
+                            org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.impl.rev141210.DataBrokerModule 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() {
+        LOG.info("DataBrokerModule.createInstance()");
+        return new CloseableDataBroker(
+                new DataBroker(getOperationalDataTreeDependency(), getConfigDataTreeDependency()));
+    }
+
+    private static final class CloseableDataBroker implements AutoCloseable, DOMDataBroker {
+
+        private final DataBroker delegate;
+
+        CloseableDataBroker(final DataBroker delegate) {
+            this.delegate = delegate;
+        }
+
+        @Override
+        public void close() throws Exception {
+            LOG.info("CloseableDataBroker.close()");
+            // NOP
+        }
+
+        @Override
+        public DOMDataReadOnlyTransaction newReadOnlyTransaction() {
+            LOG.trace("CloseableDataBroker.newReadOnlyTransaction()");
+            return delegate.newReadOnlyTransaction();
+        }
+
+        @Override
+        public DOMDataReadWriteTransaction newReadWriteTransaction() {
+            LOG.trace("CloseableDataBroker.newReadWriteTransaction()");
+            return delegate.newReadWriteTransaction();
+        }
+
+        @Override
+        public DOMDataWriteTransaction newWriteOnlyTransaction() {
+            LOG.trace("CloseableDataBroker.newWriteOnlyTransaction()");
+            return delegate.newWriteOnlyTransaction();
+        }
+
+        @Override
+        public ListenerRegistration<DOMDataChangeListener> registerDataChangeListener(final LogicalDatastoreType store,
+                                                                                      final YangInstanceIdentifier path,
+                                                                                      final DOMDataChangeListener listener,
+                                                                                      final DataChangeScope triggeringScope) {
+            LOG.trace("CloseableDataBroker.createTransactionChain store={}, path={}, listener={}, triggeringScope={}",
+                    store, path, listener, triggeringScope);
+            return delegate.registerDataChangeListener(store, path, listener, triggeringScope);
+        }
+
+        @Override
+        public DOMTransactionChain createTransactionChain(final TransactionChainListener listener) {
+            LOG.trace("CloseableDataBroker.createTransactionChain listener={}", listener);
+            return delegate.createTransactionChain(listener);
+        }
+
+        @Nonnull
+        @Override
+        public Map<Class<? extends DOMDataBrokerExtension>, DOMDataBrokerExtension> getSupportedExtensions() {
+            LOG.trace("CloseableDataBroker.getSupportedExtensions()");
+            return delegate.getSupportedExtensions();
+        }
+    }
+}
diff --git a/v3po/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/v3po/impl/rev141210/DataBrokerModuleFactory.java b/v3po/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/v3po/impl/rev141210/DataBrokerModuleFactory.java
new file mode 100644 (file)
index 0000000..cc30bea
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+* Generated file
+*
+* Generated from: yang module name: v3po-impl yang module local name: honeycomb-dom-data-broker
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Mon Apr 11 07:53:38 CEST 2016
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.impl.rev141210;
+public class DataBrokerModuleFactory extends org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.impl.rev141210.AbstractDataBrokerModuleFactory {
+
+}
index bae4a29..9597804 100644 (file)
@@ -58,7 +58,7 @@ public class V3poModule extends
         domBroker.registerProvider(new InitializationProvider());
 
         final V3poProvider provider = new V3poProvider(domBroker, getVppJapiDependency(), getReaderRegistryDependency(),
-                getWriterRegistryDependency(), getBindingNormalizedNodeSerializerDependency(),
+                getWriterRegistryDependency(), getSerializerDependency(),
                 getConfigDataTreeDependency(), getOperationalDataTreeDependency());
         getBrokerDependency().registerProvider(provider);
         return provider;
index b9868c4..c0240cd 100644 (file)
@@ -72,7 +72,7 @@ module v3po-impl {
                 }
             }
 
-            container binding-normalized-node-serializer {
+            container serializer {
                 uses config:service-ref {
                     refine type {
                         mandatory true;
@@ -123,4 +123,35 @@ module v3po-impl {
 
         }
     }
+
+    identity honeycomb-dom-data-broker {
+        base config:module-type;
+        config:provided-service dom:dom-async-data-broker;
+        config:java-name-prefix DataBroker;
+    }
+
+    augment "/config:modules/config:module/config:configuration" {
+        case honeycomb-dom-data-broker {
+            when "/config:modules/config:module/config:type = 'honeycomb-dom-data-broker'";
+
+            container config-data-tree {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity dapi:honeycomb-modifiable-data-tree;
+                    }
+                }
+            }
+
+            container operational-data-tree {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity dapi:honeycomb-readable-data-tree;
+                    }
+                }
+            }
+
+        }
+    }
 }
index 002a1c8..a73fa81 100644 (file)
             <artifactId>data-api</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <!-- Testing Dependencies -->
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-all</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
 </project>
diff --git a/v3po/vpp-cfg-init/src/main/java/io/fd/honeycomb/v3po/vpp/data/init/AbstractDataTreeConverter.java b/v3po/vpp-cfg-init/src/main/java/io/fd/honeycomb/v3po/vpp/data/init/AbstractDataTreeConverter.java
new file mode 100644 (file)
index 0000000..3048dc1
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.v3po.vpp.data.init;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Optional;
+import io.fd.honeycomb.v3po.data.ModifiableDataTree;
+import io.fd.honeycomb.v3po.translate.Context;
+import io.fd.honeycomb.v3po.translate.read.ReadContext;
+import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
+import io.fd.honeycomb.v3po.translate.read.ReaderRegistry;
+import java.util.Map;
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.binding.data.codec.api.BindingNormalizedNodeSerializer;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Base class for initializers which perform conversion between operational and config YANG model.
+ *
+ * @param <C> Config data object
+ * @param <O> Operational data object
+ */
+@Beta
+public abstract class AbstractDataTreeConverter<O extends DataObject, C extends DataObject>
+        implements DataTreeInitializer {
+    private static final Logger LOG = LoggerFactory.getLogger(AbstractDataTreeConverter.class);
+
+    private final ReaderRegistry readerRegistry;
+    private final ModifiableDataTree configDataTree;
+    private final BindingNormalizedNodeSerializer serializer;
+    private final InstanceIdentifier<O> idOper;
+    private final InstanceIdentifier<C> idConfig;
+
+    public AbstractDataTreeConverter(@Nonnull final ReaderRegistry readerRegistry,
+                                     @Nonnull final ModifiableDataTree configDataTree,
+                                     @Nonnull final BindingNormalizedNodeSerializer serializer,
+                                     @Nonnull final InstanceIdentifier<O> idOper,
+                                     @Nonnull final InstanceIdentifier<C> idConfig) {
+        this.readerRegistry = checkNotNull(readerRegistry, "readerRegistry should not be null");
+        this.configDataTree = checkNotNull(configDataTree, "configDataTree should not be null");
+        this.serializer = checkNotNull(serializer, "serializer should not be null");
+        this.idOper = checkNotNull(idOper, "idOper should not be null");
+        this.idConfig = checkNotNull(idConfig, "idConfig should not be null");
+    }
+
+    @Override
+    public final void initialize() throws InitializeException {
+        LOG.debug("AbstractDataTreeConverter.initialize()");
+
+        final Optional<? extends DataObject> data;
+        try (ReadContext ctx = new ReadContextImpl()) {
+            data = readerRegistry.read(idOper, ctx);
+        } catch (ReadFailedException e) {
+            LOG.warn("Failed to read operational state", e);
+            return;
+        }
+        LOG.debug("Config initialization data={}", data);
+
+        if (data.isPresent()) {
+            // conversion
+            final O operationalData = idOper.getTargetType().cast(data.get());
+            final C configData = convert(operationalData);
+
+            final Map.Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> normalizedData =
+                    serializer.toNormalizedNode(idConfig, configData);
+
+            final DataTreeModification modification = configDataTree.takeSnapshot().newModification();
+            final YangInstanceIdentifier biPath = normalizedData.getKey();
+            final NormalizedNode<?, ?> biData = normalizedData.getValue();
+            LOG.debug("Config initialization biPath={}, biData={}", biPath, biData);
+            modification.write(biPath, biData);
+            modification.ready();
+
+            LOG.debug("Config writing modification ...");
+            try {
+                configDataTree.initialize(modification);
+                LOG.debug("Config writing modification written successfully.");
+            } catch (DataValidationFailedException e) {
+                throw new InitializeException("Failed to read operational state", e);
+            }
+        } else {
+            LOG.warn("Data is not present");
+        }
+    }
+
+    protected abstract C convert(final O operationalData);
+
+    // TODO move to utility module
+    private static final class ReadContextImpl implements ReadContext {
+        public final Context ctx = new Context();
+
+        @Nonnull
+        @Override
+        public Context getContext() {
+            return ctx;
+        }
+
+        @Override
+        public void close() {
+            // Make sure to clear the storage in case some customizer stored it  to prevent memory leaks
+            ctx.close();
+        }
+    }
+}
diff --git a/v3po/vpp-cfg-init/src/main/java/io/fd/honeycomb/v3po/vpp/data/init/DataTreeInitializer.java b/v3po/vpp-cfg-init/src/main/java/io/fd/honeycomb/v3po/vpp/data/init/DataTreeInitializer.java
new file mode 100644 (file)
index 0000000..3cb6f14
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * 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.vpp.data.init;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Service for config data tree initialization.
+ * Implementation reads operational data and initializes config data tree.
+ * Initialization does not cause any change in VPP state, unlike ordinary writes to config.
+ */
+@Beta
+public interface DataTreeInitializer extends AutoCloseable {
+
+    /**
+     * Initializes config data tree for supported root node.
+     * @throws InitializeException if initialization failed
+     */
+    void initialize() throws InitializeException;
+
+    /**
+     * Removes all data managed by the initializer.
+     */
+    @Override
+    void close() throws Exception;
+
+    class InitializeException extends Exception {
+
+        public InitializeException(final String message, final Throwable cause) {
+            super(message, cause);
+        }
+    }
+}
index bdb6338..8760f0f 100644 (file)
 
 package io.fd.honeycomb.v3po.vpp.data.init;
 
-public interface InitializerRegistry extends AutoCloseable {
+import com.google.common.annotations.Beta;
 
-    void initialize();
+/**
+ * Data tree initializer suitable as a holder for all other root initializers, providing initializeAll feature.
+ */
+@Beta
+public interface InitializerRegistry extends DataTreeInitializer {
 
-    void clean();
+    /**
+     * Performs initialize on all registered root initializers.
+     * @throws if initialization failed
+     */
+    @Override
+    void initialize() throws InitializeException;
 }
index eaf86a6..e5220f7 100644 (file)
 
 package io.fd.honeycomb.v3po.vpp.data.init;
 
+import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
 
-import com.google.common.base.Optional;
-import io.fd.honeycomb.v3po.translate.Context;
-import io.fd.honeycomb.v3po.translate.read.ReadContext;
-import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
-import io.fd.honeycomb.v3po.translate.read.ReaderRegistry;
+import java.util.List;
 import javax.annotation.Nonnull;
-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.vpp.state.BridgeDomains;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class InitializerRegistryImpl implements InitializerRegistry, AutoCloseable {
+public class InitializerRegistryImpl implements InitializerRegistry {
     private static final Logger LOG = LoggerFactory.getLogger(InitializerRegistryImpl.class);
-    private final ReaderRegistry readerRegistry;
+    private final List<DataTreeInitializer> initializers;
 
-    public InitializerRegistryImpl(@Nonnull final ReaderRegistry readerRegistry) {
-       this.readerRegistry = checkNotNull(readerRegistry, "readerRegistry should not be null");
+    public InitializerRegistryImpl(@Nonnull List<DataTreeInitializer> initializers) {
+        this.initializers = checkNotNull(initializers, "initializers should not be null");
+        checkArgument(!initializers.contains(null), "initializers should not contain null elements");
     }
 
-
     @Override
     public void close() throws Exception {
-        LOG.info("Initializer.close()");
-        // TODO remove data
-    }
-
-    public void initialize() {
-        try {
-         initializeBridgeDomains();
-        } catch (Exception e) {
-            LOG.error("Initialization failed", e);
+        LOG.debug("InitializerRegistryImpl.close()");
+        for (DataTreeInitializer initializer : initializers) {
+            initializer.close();
         }
     }
 
     @Override
-    public void clean() {
-
-    }
-
-    // TODO make configurable
-    private void initializeBridgeDomains() throws ReadFailedException {
-
-        final InstanceIdentifier<BridgeDomains> bdsID =
-                InstanceIdentifier.create(VppState.class).child(BridgeDomains.class);
-        final ReadContext ctx = new ReadContextImpl();
-        final Optional<? extends DataObject> data = readerRegistry.read(bdsID, ctx);
-
-        LOG.info("BridgeDomains data: {}", data);
-
-    }
-
-    // TODO move to utility module
-    private static final class ReadContextImpl implements ReadContext {
-        public final Context ctx = new Context();
-
-        @Nonnull
-        @Override
-        public Context getContext() {
-            return ctx;
-        }
-
-        @Override
-        public void close() {
-            // Make sure to clear the storage in case some customizer stored it  to prevent memory leaks
-            ctx.close();
+    public void initialize() throws InitializeException {
+        // TODO check if readers are there
+        LOG.debug("InitializerRegistryImpl.initialize()");
+        for (DataTreeInitializer initializer : initializers) {
+            initializer.initialize();
         }
     }
 }
diff --git a/v3po/vpp-cfg-init/src/main/java/io/fd/honeycomb/v3po/vpp/data/init/VppInitializer.java b/v3po/vpp-cfg-init/src/main/java/io/fd/honeycomb/v3po/vpp/data/init/VppInitializer.java
new file mode 100644 (file)
index 0000000..c0316c0
--- /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.vpp.data.init;
+
+import io.fd.honeycomb.v3po.data.ModifiableDataTree;
+import io.fd.honeycomb.v3po.translate.read.ReaderRegistry;
+import java.util.ArrayList;
+import java.util.List;
+import javax.annotation.Nonnull;
+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.VppState;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomainKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.BridgeDomains;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomain;
+import org.opendaylight.yangtools.binding.data.codec.api.BindingNormalizedNodeSerializer;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class VppInitializer extends AbstractDataTreeConverter<VppState, Vpp> {
+    private static final Logger LOG = LoggerFactory.getLogger(VppInitializer.class);
+
+    public VppInitializer(@Nonnull final ReaderRegistry readerRegistry,
+                          @Nonnull final ModifiableDataTree configDataTree,
+                          @Nonnull final BindingNormalizedNodeSerializer serializer) {
+        super(readerRegistry, configDataTree, serializer, InstanceIdentifier.create(VppState.class), InstanceIdentifier.create(Vpp.class) );
+    }
+
+    @Override
+    public void close() throws Exception {
+        // NOP
+        LOG.debug("VppStateInitializer.close()");
+        // FIXME implement delete
+    }
+
+    @Override
+    protected Vpp convert(final VppState operationalData) {
+        LOG.debug("VppStateInitializer.convert()");
+        final BridgeDomains bridgeDomains = operationalData.getBridgeDomains();
+        final List<BridgeDomain> bridgeDomainList = bridgeDomains.getBridgeDomain();
+
+        VppBuilder vppBuilder = new VppBuilder();
+        org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.BridgeDomainsBuilder
+                bdsBuilder =
+                new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.BridgeDomainsBuilder();
+        final List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomain>
+                listOfBDs = new ArrayList<>();
+
+        // TODO use reflexion
+        for (BridgeDomain bd : bridgeDomainList) {
+            org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomainBuilder
+                    bdBuilder =
+                    new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomainBuilder();
+            bdBuilder.setLearn(bd.isLearn());
+            bdBuilder.setUnknownUnicastFlood(bd.isUnknownUnicastFlood());
+            bdBuilder.setArpTermination(bd.isArpTermination());
+            bdBuilder.setFlood(bd.isFlood());
+            bdBuilder.setForward(bd.isForward());
+            bdBuilder.setKey(new BridgeDomainKey(bd.getKey().getName()));
+            // TODO bdBuilder.setL2Fib(bd.getL2Fib());
+            bdBuilder.setName(bd.getName());
+            listOfBDs.add(bdBuilder.build());
+        }
+
+        bdsBuilder.setBridgeDomain(listOfBDs);
+        vppBuilder.setBridgeDomains(bdsBuilder.build());
+        return vppBuilder.build();
+    }
+}
index ecfbaa6..8b6f589 100644 (file)
@@ -1,15 +1,30 @@
 package org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.data.init.rev160407;
 
+import io.fd.honeycomb.v3po.data.ModifiableDataTree;
 import io.fd.honeycomb.v3po.translate.read.ReaderRegistry;
+import io.fd.honeycomb.v3po.vpp.data.init.DataTreeInitializer;
 import io.fd.honeycomb.v3po.vpp.data.init.InitializerRegistry;
 import io.fd.honeycomb.v3po.vpp.data.init.InitializerRegistryImpl;
+import io.fd.honeycomb.v3po.vpp.data.init.VppInitializer;
+import java.util.Collections;
+import org.opendaylight.yangtools.binding.data.codec.api.BindingNormalizedNodeSerializer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
-public class VppConfigurationInitializerModule extends org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.data.init.rev160407.AbstractVppConfigurationInitializerModule {
-    public VppConfigurationInitializerModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+public class VppConfigurationInitializerModule extends
+        org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.data.init.rev160407.AbstractVppConfigurationInitializerModule {
+
+    private static final Logger LOG = LoggerFactory.getLogger(VppConfigurationInitializerModule.class);
+
+    public VppConfigurationInitializerModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+                                             org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
         super(identifier, dependencyResolver);
     }
 
-    public VppConfigurationInitializerModule(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.data.init.rev160407.VppConfigurationInitializerModule oldModule, java.lang.AutoCloseable oldInstance) {
+    public VppConfigurationInitializerModule(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.data.init.rev160407.VppConfigurationInitializerModule oldModule,
+                                             java.lang.AutoCloseable oldInstance) {
         super(identifier, dependencyResolver, oldModule, oldInstance);
     }
 
@@ -20,11 +35,23 @@ public class VppConfigurationInitializerModule extends org.opendaylight.yang.gen
 
     @Override
     public java.lang.AutoCloseable createInstance() {
+        LOG.info("VppConfigurationInitializerModule.createInstance()");
         final ReaderRegistry readerRegistry = getReaderRegistryDependency();
+        final ModifiableDataTree configDataTree = getConfigDataTreeDependency();
+        final BindingNormalizedNodeSerializer serializer = getSerializerDependency();
+
+        // TODO make configurable
+        final VppInitializer vppInitializer =
+                new VppInitializer(readerRegistry, configDataTree, serializer);
 
-        InitializerRegistry initializer = new InitializerRegistryImpl(readerRegistry);
+        final InitializerRegistry initializer =
+                new InitializerRegistryImpl(Collections.<DataTreeInitializer>singletonList(vppInitializer));
 
-        initializer.initialize();
+        try {
+            initializer.initialize();
+        } catch (Exception e) {
+            LOG.warn("Failed to initialize config", e);
+        }
 
         return initializer;
     }
index 2f6822c..15a842e 100644 (file)
@@ -4,7 +4,9 @@ module vpp-cfg-init {
     prefix "init";
 
     import config { prefix config; revision-date 2013-04-05; }
+    import opendaylight-md-sal-binding { prefix md-sal-binding; revision-date 2013-10-28;}
     import translate-api { prefix tapi; revision-date 2016-04-06; }
+    import data-api { prefix dapi; revision-date 2016-04-11; }
 
     description
         "This module contains initializers for VPP config data tree";
@@ -37,6 +39,25 @@ module vpp-cfg-init {
                     }
                 }
             }
+
+            // TODO swich to binding broker
+            container config-data-tree {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity dapi:honeycomb-modifiable-data-tree;
+                    }
+                }
+            }
+
+            container serializer {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity md-sal-binding:binding-normalized-node-serializer;
+                    }
+                }
+            }
         }
     }
 
diff --git a/v3po/vpp-cfg-init/src/test/java/io/fd/honeycomb/v3po/vpp/data/init/InitializerRegistryImplTest.java b/v3po/vpp-cfg-init/src/test/java/io/fd/honeycomb/v3po/vpp/data/init/InitializerRegistryImplTest.java
new file mode 100644 (file)
index 0000000..d77ac3f
--- /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.vpp.data.init;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.MockitoAnnotations.initMocks;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+
+public class InitializerRegistryImplTest {
+
+    @Mock(name="dti1")
+    private DataTreeInitializer dti1;
+    @Mock(name="dti2")
+    private DataTreeInitializer dti2;
+    @Mock(name="dti3")
+    private DataTreeInitializer dti3;
+
+    private ArrayList<DataTreeInitializer> initializers;
+
+    private InitializerRegistryImpl initializerRegistry;
+
+    @Before
+    public void setUp() throws Exception {
+        initMocks(this);
+        initializers = new ArrayList<>();
+        initializers.add(dti1);
+        initializers.add(dti2);
+        initializers.add(dti3);
+        initializerRegistry = new InitializerRegistryImpl(initializers);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testConstructorFailed() throws Exception {
+        new InitializerRegistryImpl(Arrays.asList(dti1, null));
+    }
+
+    @Test
+    public void testInitialize() throws Exception {
+        initializerRegistry.initialize();
+
+        verify(dti1).initialize();
+        verify(dti2).initialize();
+        verify(dti3).initialize();
+    }
+
+    @Test
+    public void testClose() throws Exception {
+        initializerRegistry.close();
+
+        verify(dti1).close();
+        verify(dti2).close();
+        verify(dti3).close();
+    }
+}
\ No newline at end of file