Merge "Unified Two Phase Commit implementation, fixed BA to BI connection"
authorEd Warnicke <eaw@cisco.com>
Mon, 11 Nov 2013 12:30:54 +0000 (12:30 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Mon, 11 Nov 2013 12:30:54 +0000 (12:30 +0000)
31 files changed:
opendaylight/distribution/opendaylight/pom.xml
opendaylight/md-sal/sal-binding-broker/pom.xml
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RuntimeCodeGenerator.xtend
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/BindingAwareBrokerImpl.xtend
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/DataBrokerImpl.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/DataBrokerImpl.xtend [deleted file]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/DataTransactionImpl.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentDataServiceConnector.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentMappingService.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentRpcConnector.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingMapping.xtend [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/ConnectorActivator.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/Constants.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/MappingServiceImpl.xtend [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/util/ClassLoaderUtils.java [moved from opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/osgi/ClassLoaderUtils.java with 56% similarity]
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/BrokerIntegrationTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/MappingServiceTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-it/pom.xml
opendaylight/md-sal/sal-binding-it/src/main/java/org/opendaylight/controller/test/sal/binding/it/TestHelper.java
opendaylight/md-sal/sal-binding-it/src/test/java/org/opendaylight/controller/test/sal/binding/it/DataServiceTest.java
opendaylight/md-sal/sal-common-impl/pom.xml
opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/routing/AbstractDataReadRouter.java
opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/AbstractDataBroker.xtend [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BrokerActivator.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/DataBrokerImpl.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/DataBrokerImpl.xtend [deleted file]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/DataTransactionImpl.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/DataReaderRouter.xtend
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/HashMapDataStore.xtend [moved from opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/HashMapDataStore.xtend with 52% similarity]
opendaylight/md-sal/samples/toaster-it/pom.xml
opendaylight/md-sal/samples/toaster-it/src/test/java/org/opendaylight/controller/sample/toaster/it/ToasterTest.java

index a9a6209..abfc064 100644 (file)
          </dependency>
          <dependency>
           <groupId>org.opendaylight.yangtools</groupId>
-          <artifactId>binding-generator-util</artifactId>
+          <artifactId>binding-generator-spi</artifactId>
           <version>${yangtools.binding.version}</version>
          </dependency>
          <dependency>
           <groupId>org.opendaylight.yangtools</groupId>
-          <artifactId>binding-model-api</artifactId>
+          <artifactId>binding-generator-api</artifactId>
           <version>${yangtools.binding.version}</version>
          </dependency>
          <dependency>
           <groupId>org.opendaylight.yangtools</groupId>
-          <artifactId>binding-generator-spi</artifactId>
+          <artifactId>binding-generator-impl</artifactId>
+          <version>${yangtools.binding.version}</version>
+         </dependency>
+         <dependency>
+          <groupId>org.opendaylight.yangtools</groupId>
+          <artifactId>binding-generator-util</artifactId>
+          <version>${yangtools.binding.version}</version>
+         </dependency>
+         <dependency>
+          <groupId>org.opendaylight.yangtools</groupId>
+          <artifactId>binding-model-api</artifactId>
           <version>${yangtools.binding.version}</version>
          </dependency>
          <dependency>
index b0e2023..35264e7 100644 (file)
@@ -16,6 +16,7 @@
 
     <build>
         <plugins>
+        
             <plugin>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>yang-maven-plugin</artifactId>
@@ -51,6 +52,7 @@
                     </dependency>
                 </dependencies>
             </plugin>
+            
             <plugin>
                 <groupId>org.codehaus.mojo</groupId>
                 <artifactId>build-helper-maven-plugin</artifactId>
             <groupId>org.osgi</groupId>
             <artifactId>org.osgi.core</artifactId>
             <version>${osgi.core.version}</version>
+        <scope>provided</scope>
         </dependency>
         <dependency>
             <groupId>com.google.guava</groupId>
             <artifactId>javassist</artifactId>
             <version>3.17.1-GA</version>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>binding-generator-impl</artifactId>
+            <version>0.6.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>yang-parser-impl</artifactId>
+            <version>0.5.9-SNAPSHOT</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal-core-api</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal-broker-impl</artifactId>
+            <version>1.0-SNAPSHOT</version>
+            <scope>runtime</scope>
+        </dependency>
         <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
             <groupId>org.eclipse.xtend</groupId>
             <artifactId>org.eclipse.xtend.lib</artifactId>
         </dependency>
+       <dependency>
+       <groupId>org.eclipse.xtend</groupId>
+       <artifactId>org.eclipse.xtend.standalone</artifactId>
+       <version>2.4.3</version>
+       <scope>runtime</scope>
+       </dependency> 
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal-binding-config</artifactId>
             <version>1.0-SNAPSHOT</version>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller.model</groupId>
+            <artifactId>model-flow-service</artifactId>
+            <version>1.0-SNAPSHOT</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>yang-data-impl</artifactId>
+            <version>0.5.9-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>yang-model-util</artifactId>
+            <version>0.5.9-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+            <version>${slf4j.version}</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 </project>
index 87cc42c..ea6dc13 100644 (file)
@@ -33,7 +33,7 @@ import java.util.Arrays
 import static extension org.opendaylight.controller.sal.binding.codegen.YangtoolsMappingHelper.*
 import static extension org.opendaylight.controller.sal.binding.codegen.RuntimeCodeSpecification.*
 import java.util.HashSet
-import static org.opendaylight.controller.sal.binding.impl.osgi.ClassLoaderUtils.*
+import static org.opendaylight.controller.sal.binding.impl.util.ClassLoaderUtils.*
 import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory
 import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory.NotificationInvoker
 import java.util.Set
index d9a3dd5..31d5d01 100644 (file)
@@ -40,10 +40,11 @@ import org.opendaylight.yangtools.concepts.AbstractObjectRegistration
 import org.opendaylight.yangtools.yang.binding.BaseIdentity
 import com.google.common.collect.Multimap
 import com.google.common.collect.HashMultimap
-import static org.opendaylight.controller.sal.binding.impl.osgi.ClassLoaderUtils.*
+import static org.opendaylight.controller.sal.binding.impl.util.ClassLoaderUtils.*
 import java.util.concurrent.Executors
 import java.util.Collections
 import org.opendaylight.yangtools.yang.binding.DataObject
+import org.opendaylight.controller.sal.binding.impl.connect.dom.ConnectorActivator
 
 class BindingAwareBrokerImpl implements BindingAwareBroker, AutoCloseable {
     private static val log = LoggerFactory.getLogger(BindingAwareBrokerImpl)
@@ -86,7 +87,8 @@ class BindingAwareBrokerImpl implements BindingAwareBroker, AutoCloseable {
     
     ServiceRegistration<DataBrokerService> dataConsumerRegistration
     
-    private HashMapDataStore store = new HashMapDataStore();
+    ConnectorActivator connectorActivator
+   
     
     public new(BundleContext bundleContext) {
         _brokerBundleContext = bundleContext;
@@ -115,11 +117,9 @@ class BindingAwareBrokerImpl implements BindingAwareBroker, AutoCloseable {
         notifyConsumerRegistration = brokerBundleContext.registerService(NotificationService, notifyBroker, brokerProperties)
         dataProviderRegistration = brokerBundleContext.registerService(DataProviderService, dataBroker, brokerProperties)
         dataConsumerRegistration = brokerBundleContext.registerService(DataBrokerService, dataBroker, brokerProperties)
-        
-        
-        getDataBroker().registerDataReader(root, store);
-        getDataBroker().registerCommitHandler(root, store)
-        
+
+        connectorActivator = new ConnectorActivator(dataBroker,brokerBundleContext);
+        connectorActivator.start();
         log.info("MD-SAL: Binding Aware Broker Started");
     }
 
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/DataBrokerImpl.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/DataBrokerImpl.java
new file mode 100644 (file)
index 0000000..7a1ca11
--- /dev/null
@@ -0,0 +1,93 @@
+package org.opendaylight.controller.sal.binding.impl;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+
+import org.opendaylight.controller.md.sal.common.api.data.DataReader;
+import org.opendaylight.controller.md.sal.common.impl.service.AbstractDataBroker;
+import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.controller.sal.binding.impl.util.BindingAwareDataReaderRouter;
+import org.opendaylight.controller.sal.common.DataStoreIdentifier;
+import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.DataRoot;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
+
+public class DataBrokerImpl extends AbstractDataBroker<InstanceIdentifier<? extends DataObject>, DataObject, DataChangeListener> implements
+        DataProviderService {
+
+    public DataBrokerImpl() {
+        setDataReadRouter(new BindingAwareDataReaderRouter());
+    }
+
+    @Override
+    public DataTransactionImpl beginTransaction() {
+        return new DataTransactionImpl(this);
+    }
+
+    @Override
+    public <T extends DataRoot> T getData(DataStoreIdentifier store, Class<T> rootType) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public <T extends DataRoot> T getData(DataStoreIdentifier store, T filter) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public <T extends DataRoot> T getCandidateData(DataStoreIdentifier store, Class<T> rootType) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public <T extends DataRoot> T getCandidateData(DataStoreIdentifier store, T filter) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public RpcResult<DataRoot> editCandidateData(DataStoreIdentifier store, DataRoot changeSet) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Future<RpcResult<Void>> commit(DataStoreIdentifier store) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public DataObject getData(InstanceIdentifier<? extends DataObject> data) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public DataObject getConfigurationData(InstanceIdentifier<?> data) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public void registerChangeListener(InstanceIdentifier<? extends DataObject> path, DataChangeListener changeListener) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    @Override
+    public void unregisterChangeListener(InstanceIdentifier<? extends DataObject> path,
+            DataChangeListener changeListener) {
+        // TODO Auto-generated method stub
+        
+    }
+    
+    
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/DataBrokerImpl.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/DataBrokerImpl.xtend
deleted file mode 100644 (file)
index 6ed63b2..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-package org.opendaylight.controller.sal.binding.impl
-
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
-import org.opendaylight.controller.sal.binding.api.data.DataChangeListener
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus
-import org.opendaylight.controller.md.sal.common.api.data.DataReader
-import org.opendaylight.yangtools.concepts.AbstractObjectRegistration
-import org.opendaylight.yangtools.concepts.ListenerRegistration
-import com.google.common.collect.Multimap
-import static com.google.common.base.Preconditions.*;
-import java.util.List
-import com.google.common.collect.HashMultimap
-import java.util.concurrent.ExecutorService
-import java.util.concurrent.Callable
-import org.opendaylight.yangtools.yang.common.RpcResult
-import org.opendaylight.controller.sal.common.util.Rpcs
-import java.util.Collections
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction
-import java.util.ArrayList
-import org.opendaylight.controller.sal.binding.impl.util.BindingAwareDataReaderRouter
-import org.opendaylight.yangtools.concepts.CompositeObjectRegistration
-import java.util.Arrays
-
-class DataBrokerImpl extends DeprecatedDataAPISupport implements DataProviderService {
-
-    @Property
-    var ExecutorService executor;
-
-    val dataReadRouter = new BindingAwareDataReaderRouter;
-
-    Multimap<InstanceIdentifier, DataChangeListenerRegistration> listeners = HashMultimap.create();
-    Multimap<InstanceIdentifier, DataCommitHandlerRegistration> commitHandlers = HashMultimap.create();
-
-    override beginTransaction() {
-        return new DataTransactionImpl(this);
-    }
-
-    override readConfigurationData(InstanceIdentifier<? extends DataObject> path) {
-        return dataReadRouter.readConfigurationData(path);
-    }
-
-    override readOperationalData(InstanceIdentifier<? extends DataObject> path) {
-        return dataReadRouter.readOperationalData(path);
-    }
-
-    override registerCommitHandler(InstanceIdentifier<? extends DataObject> path,
-        DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> commitHandler) {
-            val registration = new DataCommitHandlerRegistration(path,commitHandler,this);
-            commitHandlers.put(path,registration)
-            return registration;
-    }
-
-    override registerDataChangeListener(InstanceIdentifier<? extends DataObject> path, DataChangeListener listener) {
-        val reg = new DataChangeListenerRegistration(path, listener, this);
-        listeners.put(path, reg);
-        return reg;
-    }
-
-    override registerDataReader(InstanceIdentifier<? extends DataObject> path,DataReader<InstanceIdentifier<? extends DataObject>,DataObject> reader) {
-        
-        val confReg = dataReadRouter.registerConfigurationReader(path,reader);
-        val dataReg = dataReadRouter.registerOperationalReader(path,reader);
-        
-        return new CompositeObjectRegistration(reader,Arrays.asList(confReg,dataReg));
-    }
-
-    protected def removeListener(DataChangeListenerRegistration registration) {
-        listeners.remove(registration.path, registration);
-    }
-
-    protected def removeCommitHandler(DataCommitHandlerRegistration registration) {
-        commitHandlers.remove(registration.path, registration);
-    }
-    
-    protected def getActiveCommitHandlers() {
-        return commitHandlers.entries.map[ value.instance].toSet
-    }
-
-    protected def commit(DataTransactionImpl transaction) {
-        checkNotNull(transaction);
-        transaction.changeStatus(TransactionStatus.SUBMITED);
-        val task = new TwoPhaseCommit(transaction, this);
-        return executor.submit(task);
-    }
-
-}
-
-package class DataChangeListenerRegistration extends AbstractObjectRegistration<DataChangeListener> implements ListenerRegistration<DataChangeListener> {
-
-    DataBrokerImpl dataBroker;
-
-    @Property
-    val InstanceIdentifier<?> path;
-
-    new(InstanceIdentifier<?> path, DataChangeListener instance, DataBrokerImpl broker) {
-        super(instance)
-        dataBroker = broker;
-        _path = path;
-    }
-
-    override protected removeRegistration() {
-        dataBroker.removeListener(this);
-        dataBroker = null;
-    }
-
-}
-
-package class DataCommitHandlerRegistration //
-extends AbstractObjectRegistration<DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject>> {
-
-    DataBrokerImpl dataBroker;
-
-    @Property
-    val InstanceIdentifier<?> path;
-
-    new(InstanceIdentifier<?> path, DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> instance,
-        DataBrokerImpl broker) {
-        super(instance)
-        dataBroker = broker;
-        _path = path;
-    }
-
-    override protected removeRegistration() {
-        dataBroker.removeCommitHandler(this);
-        dataBroker = null;
-    }
-
-}
-
-package class TwoPhaseCommit implements Callable<RpcResult<TransactionStatus>> {
-
-    val DataTransactionImpl transaction;
-    val DataBrokerImpl dataBroker;
-
-    new(DataTransactionImpl transaction, DataBrokerImpl broker) {
-        this.transaction = transaction;
-        this.dataBroker = broker;
-    }
-
-    override call() throws Exception {
-
-        val Iterable<DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject>> commitHandlers = dataBroker.activeCommitHandlers;
-
-        // requesting commits
-        val List<DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject>> handlerTransactions = new ArrayList();
-        try {
-            for (handler : commitHandlers) {
-                handlerTransactions.add(handler.requestCommit(transaction));
-            }
-        } catch (Exception e) {
-            return rollback(handlerTransactions,e);
-        }
-        val List<RpcResult<Void>> results = new ArrayList();
-        try {
-            for (subtransaction : handlerTransactions) {
-                results.add(subtransaction.finish());
-            }
-        } catch (Exception e) {
-            return rollback(handlerTransactions,e);
-        }
-
-        return Rpcs.getRpcResult(true, TransactionStatus.COMMITED, Collections.emptySet());
-    }
-
-    def rollback(List<DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject>> transactions,Exception e) {
-        for (transaction : transactions) {
-            transaction.rollback()
-        }
-        // FIXME return encoutered error.
-        return Rpcs.getRpcResult(false, TransactionStatus.FAILED, Collections.emptySet());
-    }
-}
index c970fc5..f7967be 100644 (file)
@@ -1,89 +1,22 @@
 package org.opendaylight.controller.sal.binding.impl;
 
-import java.util.concurrent.Future;
-
 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
-import org.opendaylight.controller.md.sal.common.impl.AbstractDataModification;
-import org.opendaylight.controller.md.sal.common.impl.ListenerRegistry;
+import org.opendaylight.controller.md.sal.common.impl.service.AbstractDataTransaction;
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction.DataTransactionListener;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.concepts.util.ListenerRegistry;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-
-public class DataTransactionImpl extends AbstractDataModification<InstanceIdentifier<? extends DataObject>, DataObject>
-        implements DataModificationTransaction {
-
-    private final Object identifier;
-
-    private TransactionStatus status;
-    private ListenerRegistry<DataTransactionListener> listeners;
-
-    final DataBrokerImpl broker;
 
+public class DataTransactionImpl extends AbstractDataTransaction<InstanceIdentifier<? extends DataObject>, DataObject> 
+    implements DataModificationTransaction {
+    private final ListenerRegistry<DataTransactionListener> listeners = new ListenerRegistry<DataTransactionListener>();
+    
+    
+    
     public DataTransactionImpl(DataBrokerImpl dataBroker) {
         super(dataBroker);
-        identifier = new Object();
-        broker = dataBroker;
-        status = TransactionStatus.NEW;
-        listeners = new ListenerRegistry<>();
-    }
-
-    @Override
-    public Future<RpcResult<TransactionStatus>> commit() {
-        return broker.commit(this);
-    }
-
-    @Override
-    public DataObject readConfigurationData(
-            org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject> path) {
-        return broker.readConfigurationData(path);
-    }
-
-    @Override
-    public DataObject readOperationalData(InstanceIdentifier<? extends DataObject> path) {
-        return broker.readOperationalData(path);
-    }
-
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + ((broker == null) ? 0 : broker.hashCode());
-        result = prime * result + ((identifier == null) ? 0 : identifier.hashCode());
-        return result;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj)
-            return true;
-        if (obj == null)
-            return false;
-        if (getClass() != obj.getClass())
-            return false;
-        DataTransactionImpl other = (DataTransactionImpl) obj;
-        if (broker == null) {
-            if (other.broker != null)
-                return false;
-        } else if (!broker.equals(other.broker))
-            return false;
-        if (identifier == null) {
-            if (other.identifier != null)
-                return false;
-        } else if (!identifier.equals(other.identifier))
-            return false;
-        return true;
-    }
-
-    @Override
-    public TransactionStatus getStatus() {
-        return status;
-    }
-
-    @Override
-    public Object getIdentifier() {
-        return identifier;
     }
 
     @Override
@@ -91,11 +24,9 @@ public class DataTransactionImpl extends AbstractDataModification<InstanceIdenti
         return listeners.register(listener);
     }
 
-    public void changeStatus(TransactionStatus status) {
-        this.status = status;
-        Iterable<ListenerRegistration<DataTransactionListener>> listenersToNotify = listeners.getListeners();
-        for (ListenerRegistration<DataTransactionListener> listenerRegistration : listenersToNotify) {
+    protected void onStatusChange(TransactionStatus status) {
+        for (ListenerRegistration<DataTransactionListener> listenerRegistration : listeners) {
             listenerRegistration.getInstance().onStatusUpdated(this, status);
         }
     }
-}
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentDataServiceConnector.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentDataServiceConnector.java
new file mode 100644 (file)
index 0000000..ff897aa
--- /dev/null
@@ -0,0 +1,151 @@
+package org.opendaylight.controller.sal.binding.impl.connect.dom;
+
+import java.util.Collections;
+import java.util.Map.Entry;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+import org.opendaylight.controller.config.api.jmx.CommitStatus;
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
+import org.opendaylight.controller.md.sal.common.api.data.DataModification;
+import org.opendaylight.controller.md.sal.common.api.data.DataReader;
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.controller.sal.binding.api.data.RuntimeDataProvider;
+import org.opendaylight.controller.sal.common.util.Rpcs;
+import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
+import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+
+import com.google.common.base.Preconditions;
+
+public class BindingIndependentDataServiceConnector implements //
+        RuntimeDataProvider, //
+        DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> {
+
+    private static final InstanceIdentifier<? extends DataObject> ROOT = InstanceIdentifier.builder().toInstance();
+
+    private BindingIndependentMappingService mappingService;
+
+    private DataBrokerService biDataService;
+
+    private DataProviderService baDataService;
+
+    @Override
+    public DataObject readOperationalData(InstanceIdentifier<? extends DataObject> path) {
+        // TODO Auto-generated method stub
+        org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path);
+        CompositeNode result = biDataService.readOperationalData(biPath);
+        return mappingService.dataObjectFromDataDom(path, result);
+    }
+
+    @Override
+    public DataObject readConfigurationData(InstanceIdentifier<? extends DataObject> path) {
+        org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path);
+        CompositeNode result = biDataService.readConfigurationData(biPath);
+        return mappingService.dataObjectFromDataDom(path, result);
+    }
+
+    @Override
+    public org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject> requestCommit(
+            DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
+
+        DataModificationTransaction translated = translateTransaction(modification);
+        return new WrappedTransaction(translated, modification);
+    }
+
+    private DataModificationTransaction translateTransaction(
+            DataModification<InstanceIdentifier<? extends DataObject>, DataObject> source) {
+        DataModificationTransaction target = biDataService.beginTransaction();
+        for (Entry<InstanceIdentifier<? extends DataObject>, DataObject> entry : source.getUpdatedConfigurationData()
+                .entrySet()) {
+            Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> biEntry = mappingService
+                    .toDataDom(entry);
+            target.putConfigurationData(biEntry.getKey(), biEntry.getValue());
+        }
+        for (Entry<InstanceIdentifier<? extends DataObject>, DataObject> entry : source.getUpdatedOperationalData()
+                .entrySet()) {
+            Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> biEntry = mappingService
+                    .toDataDom(entry);
+            target.putOperationalData(biEntry.getKey(), biEntry.getValue());
+        }
+        for(InstanceIdentifier<? extends DataObject> entry : source.getRemovedConfigurationData()) {
+            org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biEntry = mappingService.toDataDom(entry);
+            target.removeConfigurationData(biEntry);
+        }
+        for(InstanceIdentifier<? extends DataObject> entry : source.getRemovedOperationalData()) {
+            org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biEntry = mappingService.toDataDom(entry);
+            target.removeOperationalData(biEntry);
+        }
+        return target;
+    }
+
+    private class WrappedTransaction implements
+            DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject> {
+
+        private DataModificationTransaction backing;
+        private DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification;
+
+        public WrappedTransaction(DataModificationTransaction backing,
+                DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
+            this.backing = backing;
+            this.modification = modification;
+        }
+
+        @Override
+        public DataModification<InstanceIdentifier<? extends DataObject>, DataObject> getModification() {
+            return modification;
+        }
+
+        @Override
+        public RpcResult<Void> finish() throws IllegalStateException {
+            Future<RpcResult<TransactionStatus>> result = backing.commit();
+            try {
+                RpcResult<TransactionStatus> biresult = result.get();
+            } catch (InterruptedException e) {
+                throw new IllegalStateException("", e);
+            } catch (ExecutionException e) {
+                throw new IllegalStateException("", e);
+            }
+            return Rpcs.<Void> getRpcResult(true, null, Collections.<RpcError> emptySet());
+        }
+
+        @Override
+        public RpcResult<Void> rollback() throws IllegalStateException {
+            // backing.cancel();
+            return Rpcs.<Void> getRpcResult(true, null, Collections.<RpcError> emptySet());
+        }
+
+    }
+
+    public DataBrokerService getBiDataService() {
+        return biDataService;
+    }
+
+    public void setBiDataService(DataBrokerService biDataService) {
+        this.biDataService = biDataService;
+    }
+
+    public DataProviderService getBaDataService() {
+        return baDataService;
+    }
+
+    public void setBaDataService(DataProviderService baDataService) {
+        this.baDataService = baDataService;
+    }
+
+    public void start() {
+        baDataService.registerDataReader(ROOT, this);
+        baDataService.registerCommitHandler(ROOT, this);
+    }
+
+    public void setMappingService(BindingIndependentMappingService mappingService) {
+        this.mappingService = mappingService;
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentMappingService.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentMappingService.java
new file mode 100644 (file)
index 0000000..d8fbc70
--- /dev/null
@@ -0,0 +1,19 @@
+package org.opendaylight.controller.sal.binding.impl.connect.dom;
+
+import java.util.Map.Entry;
+
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+
+public interface BindingIndependentMappingService {
+
+    CompositeNode toDataDom(DataObject data);
+
+    Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> toDataDom(
+            Entry<InstanceIdentifier<? extends DataObject>, DataObject> entry);
+
+    org.opendaylight.yangtools.yang.data.api.InstanceIdentifier toDataDom(InstanceIdentifier<? extends DataObject> path);
+
+    DataObject dataObjectFromDataDom(InstanceIdentifier<? extends DataObject> path, CompositeNode result);
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentRpcConnector.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentRpcConnector.java
new file mode 100644 (file)
index 0000000..d22da30
--- /dev/null
@@ -0,0 +1,5 @@
+package org.opendaylight.controller.sal.binding.impl.connect.dom;
+
+public class BindingIndependentRpcConnector {
+
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingMapping.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingMapping.xtend
new file mode 100644 (file)
index 0000000..9a6330e
--- /dev/null
@@ -0,0 +1,402 @@
+package org.opendaylight.controller.sal.binding.impl.connect.dom
+
+import org.opendaylight.yangtools.yang.common.QName
+import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleContext
+import java.util.List
+import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilder
+import org.opendaylight.yangtools.sal.binding.model.api.Type
+import org.opendaylight.yangtools.yang.model.api.SchemaNode
+import java.util.Map
+import org.opendaylight.yangtools.yang.model.api.SchemaPath
+import org.opendaylight.yangtools.yang.model.api.SchemaContext
+import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil
+import org.opendaylight.yangtools.binding.generator.util.Types
+import java.util.HashMap
+import org.opendaylight.yangtools.yang.data.api.CompositeNode
+import org.opendaylight.yangtools.yang.binding.DataContainer
+import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl
+import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty
+import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType
+import java.util.Collections
+import java.util.ArrayList
+import org.opendaylight.yangtools.yang.data.api.Node
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode
+import org.opendaylight.yangtools.yang.model.api.ChoiceNode
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode
+import org.opendaylight.yangtools.sal.binding.generator.impl.BindingGeneratorImpl
+import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl
+import org.opendaylight.yangtools.yang.model.api.NotificationDefinition
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition
+import org.opendaylight.yangtools.yang.model.api.type.BooleanTypeDefinition
+import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.opendaylight.yangtools.yang.binding.DataObject
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.Item
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates
+import org.opendaylight.yangtools.yang.model.util.ExtendedType
+import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject
+import com.google.common.collect.FluentIterable
+import org.opendaylight.yangtools.yang.data.api.SimpleNode
+import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil
+import org.opendaylight.controller.sal.binding.impl.util.ClassLoaderUtils
+import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition
+
+class BindingMapping {
+
+    val Map<Type, GeneratedTypeBuilder> typeToDefinition = new HashMap();
+    val Map<Type, SchemaNode> typeToSchemaNode = new HashMap();
+
+    def QName getSchemaNode(Class<?> cls) {
+        val ref = Types.typeForClass(cls);
+        return typeToSchemaNode.get(ref)?.QName;
+    }
+
+    def void updateBinding(SchemaContext schemaContext, ModuleContext moduleBindingContext) {
+        updateBindingFor(moduleBindingContext.childNodes, schemaContext);
+
+    }
+
+    def org.opendaylight.yangtools.yang.data.api.InstanceIdentifier toDataDom(
+        InstanceIdentifier<? extends DataObject> obj) {
+        val pathArguments = obj.path;
+        var Class<? extends DataObject> parent;
+        val dataDomArgs = new ArrayList<PathArgument>();
+        for (pathArgument : pathArguments) {
+            dataDomArgs.add(pathArgument.toDataDomPathArgument(parent));
+            parent = pathArgument.type;
+        }
+
+        return new org.opendaylight.yangtools.yang.data.api.InstanceIdentifier(dataDomArgs);
+    }
+
+    
+
+    def DataObject dataObjectFromDataDom(InstanceIdentifier<? extends DataObject> identifier, CompositeNode node) {
+        if (node == null) {
+            return null;
+        }
+        val targetClass = identifier.targetType;
+        val classLoader = targetClass.classLoader;
+        val ref = Types.typeForClass(targetClass);
+        val targetType = typeToDefinition.get(ref);
+        val targetSchema = typeToSchemaNode.get(ref);
+        return node.toDataObject(classLoader, targetType.toInstance, targetSchema);
+
+    }
+
+    def dispatch PathArgument toDataDomPathArgument(IdentifiableItem argument, Class<? extends DataObject> parent) {
+        val Class rawType = argument.type;
+        val ref = Types.typeForClass(rawType);
+        val schemaType = typeToSchemaNode.get(ref);
+        val qname = schemaType.QName
+
+        val Object key = argument.key;
+        val predicates = key.toPredicates(schemaType as ListSchemaNode);
+
+        return new NodeIdentifierWithPredicates(qname, predicates);
+    }
+    
+    def dispatch PathArgument toDataDomPathArgument(Item<?> argument, Class<? extends DataObject> parent) {
+        val ref = Types.typeForClass(argument.type);
+        val qname = typeToSchemaNode.get(ref).QName
+        return new NodeIdentifier(qname);
+    }
+
+    def Map<QName, Object> toPredicates(Object identifier, ListSchemaNode node) {
+        val keyDefinitions = node.keyDefinition;
+        val map = new HashMap<QName, Object>();
+        for (keydef : keyDefinitions) {
+            val keyNode = node.getDataChildByName(keydef) as LeafSchemaNode;
+            val value = identifier.getSimpleValue(keydef, keyNode.type);
+            map.put(keydef, value.value);
+        }
+        return map;
+    }
+
+    def void updateBindingFor(Map<SchemaPath, GeneratedTypeBuilder> map, SchemaContext module) {
+        for (entry : map.entrySet) {
+            val schemaNode = SchemaContextUtil.findDataSchemaNode(module, entry.key);
+            typeToDefinition.put(entry.value, entry.value);
+            typeToSchemaNode.put(entry.value, schemaNode)
+        }
+    }
+
+    def CompositeNode toCompositeNode(DataContainer data) {
+        val type = data.implementedInterface;
+        val typeRef = Types.typeForClass(type);
+        val schemaNode = typeToSchemaNode.get(typeRef);
+        val generatedType = typeToDefinition.get(typeRef);
+
+        return data.toDataDom(schemaNode, generatedType);
+    }
+
+    private def dispatch CompositeNode toDataDom(DataContainer data, ContainerSchemaNode node,
+        GeneratedTypeBuilder builder) {
+        val subnodes = data.toDataDomComponents(node);
+        return new CompositeNodeTOImpl(node.QName, null, subnodes);
+    }
+
+    private def dispatch CompositeNode toDataDom(DataContainer data, NotificationDefinition node,
+        GeneratedTypeBuilder builder) {
+        val subnodes = data.toDataDomComponents(node);
+        return new CompositeNodeTOImpl(node.QName, null, subnodes);
+    }
+
+    private def dispatch CompositeNode toDataDom(DataContainer data, ListSchemaNode node,
+        GeneratedTypeBuilder builder) {
+        val subnodes = data.toDataDomComponents(node);
+        return new CompositeNodeTOImpl(node.QName, null, subnodes);
+    }
+
+    private def List<Node<?>> toDataDomComponents(DataContainer data, DataNodeContainer node) {
+        val subnodes = new ArrayList<Node<?>>();
+        for (childNode : node.childNodes) {
+            val value = childNode.dataDomFromParent(data);
+            if (value !== null) {
+                subnodes.addAll(value);
+            }
+        }
+        return subnodes;
+    }
+
+    private def List<Node<?>> dataDomFromParent(DataSchemaNode node, DataContainer container) {
+        if (node.augmenting) {
+            return Collections.emptyList();
+        }
+        return dataDomFromParentImpl(node, container);
+    }
+
+    private def dispatch List<Node<?>> dataDomFromParentImpl(LeafSchemaNode node, DataContainer container) {
+        val value = container.getSimpleValue(node.QName, node.type);
+        if (value !== null) {
+            return Collections.<Node<?>>singletonList(value);
+        }
+        return Collections.emptyList();
+    }
+
+    private def dispatch List<Node<?>> dataDomFromParentImpl(LeafListSchemaNode node, DataContainer container) {
+        val values = container.getSimpleValues(node);
+        if (values !== null) {
+            //val it = new ArrayList<Node<?>>();
+            //for (value : values) {
+            //}
+
+        }
+        return Collections.emptyList();
+    }
+
+    def getSimpleValues(DataContainer container, LeafListSchemaNode node) {
+        return Collections.emptyList();
+    }
+
+    private def dispatch List<Node<?>> dataDomFromParentImpl(ListSchemaNode node, DataContainer container) {
+        val qname = node.QName;
+        val values = container.<List>getValue(qname, List) as List<? extends DataContainer>;
+        if (values === null) {
+            return Collections.emptyList;
+        }
+        val it = new ArrayList<Node<?>>();
+        for (value : values) {
+            add(value.toCompositeNode());
+        }
+
+        return it;
+    }
+
+    private def dispatch List<Node<?>> dataDomFromParentImpl(ChoiceNode node, DataContainer container) {
+    }
+
+    private def dispatch List<Node<?>> serializeValueImpl(List<?> list, GeneratedTypeBuilder builder,
+        ListSchemaNode node) {
+        val it = new ArrayList<Node<?>>();
+        for (value : list) {
+
+            val serVal = value.serializeValueImpl(builder, node);
+            if (serVal !== null) {
+                addAll(serVal);
+            }
+        }
+        return it;
+    }
+
+    private def dispatch Node<?> getSimpleValue(Object container, QName name, ExtendedType type) {
+        getSimpleValue(container, name, type.baseType);
+    }
+
+    private def dispatch Node<?> getSimpleValue(Object container, QName name, StringTypeDefinition type) {
+        val value = container.getValue(name, String);
+        if(value === null) return null;
+        return new SimpleNodeTOImpl(name, null, value);
+    }
+
+    private def dispatch Node<?> getSimpleValue(Object container, QName name, TypeDefinition<?> type) {
+        val value = container.getValue(name, Object);
+        if(value === null) return null;
+        return new SimpleNodeTOImpl(name, null, value);
+    }
+
+    private def dispatch Node<?> getSimpleValue(Object container, QName name, BooleanTypeDefinition type) {
+        val value = container.getValue(name, Boolean);
+        if(value === null) return null;
+        return new SimpleNodeTOImpl(name, null, value);
+    }
+
+    private def dispatch Node<?> getSimpleValue(Object container, QName name, BinaryTypeDefinition type) {
+        val Object value = container.getValue(name, Object); //Constants.BYTES_CLASS);
+        if(value === null) return null;
+        return new SimpleNodeTOImpl(name, null, value);
+    }
+
+    private def <T> T getValue(Object object, QName node, Class<T> type) {
+        val methodName = BindingGeneratorImpl.getterMethodName(node.localName, Types.typeForClass(type));
+        var clz = object.class;
+        if (object instanceof DataContainer) {
+            clz = (object as DataContainer).implementedInterface;
+        }
+        val method = clz.getMethod(methodName);
+        if (method === null) {
+            return null;
+        }
+        val value = method.invoke(object);
+        if (value === null) {
+            return null;
+        }
+        if (type.isAssignableFrom(value.class)) {
+            return value  as T;
+        }
+        return value.getEncapsulatedValue(type);
+    }
+
+    private def <T> T getEncapsulatedValue(Object value, Class<T> type) {
+        val method = value.class.getMethod("getValue");
+        if (method !== null && type.isAssignableFrom(method.returnType)) {
+            return method.invoke(value) as T;
+        }
+        return null;
+    }
+
+    private def dispatch List<Node<?>> serializeValueImpl(DataContainer data, GeneratedTypeBuilder builder,
+        SchemaNode node) {
+        return Collections.<Node<?>>singletonList(data.toDataDom(node, builder));
+    }
+
+    private def dispatch List<Node<?>> serializeValueImpl(Object object, GeneratedTypeBuilder builder,
+        SchemaNode node) {
+    }
+
+    def DataObject toDataObject(CompositeNode node, ClassLoader loader, GeneratedType type, SchemaNode schema) {
+
+        // Nasty reflection hack (for now)
+        val builderClass = loader.loadClass(type.builderFQN);
+        val builder = builderClass.newInstance;
+        val buildMethod = builderClass.getMethod("build");
+
+        node.fillDataObject(builder, loader, type, schema);
+
+        return buildMethod.invoke(builder) as DataObject;
+    }
+
+    def dispatch void fillDataObject(CompositeNode node, Object builder, ClassLoader loader, GeneratedType type,
+        ListSchemaNode schema) {
+
+        if (schema.keyDefinition !== null && !schema.keyDefinition.empty) {
+
+            val value = node.keyToBindingKey(loader, type, schema);
+            builder.setProperty("key", value);
+        }
+    }
+
+    def dispatch void fillDataObject(CompositeNode node, Object builder, ClassLoader loader, GeneratedType type,
+        ContainerSchemaNode schema) {
+    }
+
+    
+    def Object keyToBindingKey(CompositeNode node, ClassLoader loader, GeneratedType type, ListSchemaNode schema) {
+        val keyClass = loader.loadClass(type.keyFQN);
+        val constructor = keyClass.constructors.get(0);
+        val keyType = type.keyTypeProperties;
+        val args = new ArrayList();
+        for (key : schema.keyDefinition) {
+            val keyProperty = keyType.get(BindingGeneratorUtil.parseToClassName(key.localName));
+            val domKeyValue = node.getFirstSimpleByName(key);
+            val keyValue = domKeyValue.deserializeSimpleValue(loader, keyProperty.returnType,
+                schema.getDataChildByName(key));
+            args.add(keyValue);
+        }
+        return ClassLoaderUtils.construct(constructor, args);
+    }
+
+    def dispatch Object deserializeSimpleValue(SimpleNode<? extends Object> node, ClassLoader loader, Type type,
+        LeafSchemaNode node2) {
+        deserializeSimpleValueImpl(node, loader, type, node2.type);
+    }
+
+    def dispatch Object deserializeSimpleValue(SimpleNode<? extends Object> node, ClassLoader loader, Type type,
+        LeafListSchemaNode node2) {
+        deserializeSimpleValueImpl(node, loader, type, node2.type);
+    }
+
+    def dispatch Object deserializeSimpleValueImpl(SimpleNode<? extends Object> node, ClassLoader loader, Type type,
+        ExtendedType definition) {
+        deserializeSimpleValueImpl(node, loader, type, definition.baseType);
+    }
+
+    def dispatch Object deserializeSimpleValueImpl(SimpleNode<? extends Object> node, ClassLoader loader, Type type,
+        StringTypeDefinition definition) {
+        if (type instanceof GeneratedTransferObject) {
+            val cls = loader.getClassForType(type);
+            val const = cls.getConstructor(String);
+            val str = String.valueOf(node.value);
+            return const.newInstance(str);
+        }
+        return node.value;
+    }
+
+    def Class<?> getClassForType(ClassLoader loader, Type type) {
+        loader.loadClass(type.fullyQualifiedName);
+    }
+
+    def dispatch Object deserializeSimpleValueImpl(SimpleNode<? extends Object> node, ClassLoader loader, Type type,
+        TypeDefinition definition) {
+        throw new UnsupportedOperationException("TODO: auto-generated method stub")
+    }
+
+    def Map<String, GeneratedProperty> getKeyTypeProperties(GeneratedType type) {
+        val method = FluentIterable.from(type.methodDefinitions).findFirst[name == "getKey"]
+        val key = method.returnType as GeneratedTransferObject;
+        val ret = new HashMap<String, GeneratedProperty>();
+        for (prop : key.properties) {
+            ret.put(prop.name, prop);
+        }
+        return ret;
+    }
+
+    def void setProperty(Object object, String property, Object value) {
+        val cls = object.class;
+        val valMethod = cls.getMethod("set" + property.toFirstUpper, value.class);
+        if (valMethod != null)
+            valMethod.invoke(object, value);
+    }
+
+    def String getBuilderFQN(Type type) '''«type.fullyQualifiedName»Builder'''
+
+    def String getKeyFQN(Type type) '''«type.fullyQualifiedName»Key'''
+
+}
+
+@Data
+class PropertyCapture {
+
+    @Property
+    val Type returnType;
+    @Property
+    val String name;
+
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/ConnectorActivator.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/ConnectorActivator.java
new file mode 100644 (file)
index 0000000..c96835b
--- /dev/null
@@ -0,0 +1,73 @@
+package org.opendaylight.controller.sal.binding.impl.connect.dom;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.controller.sal.core.api.Broker;
+import org.opendaylight.controller.sal.core.api.Provider;
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
+import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
+import org.opendaylight.controller.sal.core.api.model.SchemaService;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+
+public class ConnectorActivator implements Provider, ServiceTrackerCustomizer<Broker, Broker> {
+
+    BindingIndependentDataServiceConnector dataConnector;
+    BindingIndependentMappingService mappingService;
+
+    private final DataProviderService baDataService;
+    private BundleContext context;
+
+    private ServiceTracker<Broker, Broker> brokerTracker;
+
+    public ConnectorActivator(DataProviderService dataService, BundleContext context) {
+        baDataService = dataService;
+        this.context = context;
+        brokerTracker = new ServiceTracker<>(context, Broker.class, this);
+    }
+
+    @Override
+    public Collection<ProviderFunctionality> getProviderFunctionality() {
+        return Collections.emptySet();
+    }
+
+    @Override
+    public void onSessionInitiated(ProviderSession session) {
+
+        MappingServiceImpl mappingImpl = new MappingServiceImpl();
+        mappingImpl.setSchemaService(session.getService(SchemaService.class));
+        mappingImpl.start();
+
+        mappingService = mappingImpl;
+        dataConnector = new BindingIndependentDataServiceConnector();
+        dataConnector.setBaDataService(baDataService);
+        dataConnector.setBiDataService(session.getService(DataBrokerService.class));
+        dataConnector.setMappingService(mappingService);
+        dataConnector.start();
+    }
+
+    @Override
+    public Broker addingService(ServiceReference<Broker> reference) {
+        Broker br= context.getService(reference);
+        br.registerProvider(this, context);
+        return br;
+    }
+
+    @Override
+    public void modifiedService(ServiceReference<Broker> reference, Broker service) {
+        // NOOP
+    }
+
+    @Override
+    public void removedService(ServiceReference<Broker> reference, Broker service) {
+        // NOOP
+    }
+
+    public void start() {
+        brokerTracker.open();
+    }
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/Constants.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/Constants.java
new file mode 100644 (file)
index 0000000..1c9a59d
--- /dev/null
@@ -0,0 +1,5 @@
+package org.opendaylight.controller.sal.binding.impl.connect.dom;
+
+public class Constants {
+    public static final Class<byte[]> BYTES_CLASS = byte[].class;
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/MappingServiceImpl.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/MappingServiceImpl.xtend
new file mode 100644 (file)
index 0000000..84a0065
--- /dev/null
@@ -0,0 +1,68 @@
+package org.opendaylight.controller.sal.binding.impl.connect.dom
+
+import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener
+import org.opendaylight.yangtools.yang.model.api.SchemaContext
+import org.opendaylight.yangtools.sal.binding.model.api.CodeGenerator
+import org.opendaylight.yangtools.sal.binding.generator.impl.BindingGeneratorImpl
+import org.opendaylight.yangtools.sal.binding.generator.api.BindingGenerator
+import org.opendaylight.yangtools.yang.data.api.CompositeNode
+import org.opendaylight.yangtools.yang.binding.DataObject
+import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl
+import java.util.Collections
+import java.util.Map.Entry
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import java.util.AbstractMap.SimpleEntry
+import org.opendaylight.controller.sal.core.api.model.SchemaService
+
+class MappingServiceImpl implements SchemaServiceListener, BindingIndependentMappingService {
+
+    var extension BindingMapping mapping = new BindingMapping;
+
+    @Property
+    BindingGeneratorImpl binding;
+
+    @Property
+    SchemaService schemaService;
+
+    override onGlobalContextUpdated(SchemaContext arg0) {
+        recreateBindingContext(arg0);
+    }
+
+    def recreateBindingContext(SchemaContext schemaContext) {
+        val newBinding = new BindingGeneratorImpl();
+        newBinding.generateTypes(schemaContext);
+        val newMapping = new BindingMapping();
+        for (entry : newBinding.moduleContexts.entrySet) {
+            val module = entry.key;
+            val context = entry.value;
+            
+            newMapping.updateBinding(schemaContext, context);
+        }
+        mapping = newMapping
+    }
+
+    override CompositeNode toDataDom(DataObject data) {
+        mapping.toCompositeNode(data);
+    }
+
+    override Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> toDataDom(
+        Entry<InstanceIdentifier<? extends DataObject>, DataObject> entry) {
+        val key = mapping.toDataDom(entry.key);
+        val data = mapping.toCompositeNode(entry.value);
+        return new SimpleEntry(key, data);
+    }
+
+    override org.opendaylight.yangtools.yang.data.api.InstanceIdentifier toDataDom(
+        InstanceIdentifier<? extends DataObject> path) {
+        return mapping.toDataDom(path);
+    }
+    
+    override dataObjectFromDataDom(InstanceIdentifier<? extends DataObject> path, CompositeNode result) {
+        return mapping.dataObjectFromDataDom(path,result);
+    }
+    
+    public def void start() {
+        schemaService.registerSchemaServiceListener(this);
+        recreateBindingContext(schemaService.globalContext);
+    }
+}
@@ -1,10 +1,17 @@
-package org.opendaylight.controller.sal.binding.impl.osgi;
+package org.opendaylight.controller.sal.binding.impl.util;
 
 
 
 import java.util.concurrent.Callable;
+
 import static com.google.common.base.Preconditions.*;
 
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+
+import org.opendaylight.yangtools.yang.binding.Identifier;
+
 public class ClassLoaderUtils {
     
     public static <V> V withClassLoader(ClassLoader cls,Callable<V> function) throws Exception {
@@ -21,4 +28,9 @@ public class ClassLoaderUtils {
             throw new Exception(e);
         }
     }
+
+    public static Object construct(Constructor<? extends Object> constructor, ArrayList<Object> objects) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+    Object[] initargs = objects.toArray(new Object[]{});
+    return constructor.newInstance(initargs);
+    }
 }
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/BrokerIntegrationTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/BrokerIntegrationTest.java
new file mode 100644 (file)
index 0000000..0448238
--- /dev/null
@@ -0,0 +1,136 @@
+package org.opendaylight.controller.sal.binding.test.connect.dom;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.controller.sal.binding.impl.DataBrokerImpl;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentDataServiceConnector;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.MappingServiceImpl;
+import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
+import org.opendaylight.controller.sal.dom.broker.impl.HashMapDataStore;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+
+public class BrokerIntegrationTest {
+
+    DataBrokerService biDataService;
+    DataProviderService baDataService;
+    private MappingServiceImpl mappingServiceImpl;
+    private MappingServiceImpl mappingService;
+    private DataBrokerImpl baDataImpl;
+    private org.opendaylight.controller.sal.dom.broker.DataBrokerImpl biDataImpl;
+    private ListeningExecutorService executor;
+    private BindingIndependentDataServiceConnector connectorServiceImpl;
+    private HashMapDataStore dataStore;
+    
+    
+    @Before
+    public void setUp() {
+        executor = MoreExecutors.sameThreadExecutor();
+        baDataImpl = new DataBrokerImpl();
+        baDataService = baDataImpl;
+        baDataImpl.setExecutor(executor);
+        
+        biDataImpl = new org.opendaylight.controller.sal.dom.broker.DataBrokerImpl();
+        biDataService =  biDataImpl;
+        biDataImpl.setExecutor(executor);
+        
+        dataStore = new HashMapDataStore();
+        org.opendaylight.yangtools.yang.data.api.InstanceIdentifier treeRoot = org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.builder().toInstance();
+        biDataImpl.registerConfigurationReader(treeRoot, dataStore);
+        biDataImpl.registerOperationalReader(treeRoot, dataStore);
+        biDataImpl.registerCommitHandler(treeRoot, dataStore);
+        
+        mappingServiceImpl = new MappingServiceImpl();
+        mappingService = mappingServiceImpl;
+        
+        
+        connectorServiceImpl = new BindingIndependentDataServiceConnector();
+        connectorServiceImpl.setBaDataService(baDataService);
+        connectorServiceImpl.setBiDataService(biDataService);
+        connectorServiceImpl.setMappingService(mappingServiceImpl);
+        connectorServiceImpl.start();
+        
+        String[] yangFiles = new String[] { "yang-ext.yang", "ietf-inet-types.yang", "ietf-yang-types.yang",
+        "node-inventory.yang" };
+        
+        mappingService.onGlobalContextUpdated(MappingServiceTest.getContext(yangFiles));
+    }
+    
+    @Test
+    public void simpleModifyOperation() throws Exception {
+        
+        DataModificationTransaction transaction = baDataService.beginTransaction();
+        assertNotNull(transaction);
+        
+        NodeRef node1 = createNodeRef("0");
+        DataObject  node = baDataService.readConfigurationData(node1.getValue());
+        assertNull(node);
+        Node nodeData1 = createNode("0");
+        
+        transaction.putConfigurationData(node1.getValue(), nodeData1);
+        Future<RpcResult<TransactionStatus>> commitResult = transaction.commit();
+        assertNotNull(commitResult);
+        
+        RpcResult<TransactionStatus> result = commitResult.get();
+        
+        assertNotNull(result);
+        assertNotNull(result.getResult());
+        assertEquals(TransactionStatus.COMMITED, result.getResult());
+        
+        Node readedData = (Node) baDataService.readConfigurationData(node1.getValue());
+        assertNotNull(readedData);
+        assertEquals(nodeData1.getKey(), readedData.getKey());
+        
+        
+        DataModificationTransaction transaction2 = baDataService.beginTransaction();
+        assertNotNull(transaction);
+        
+        transaction2.removeConfigurationData(node1.getValue());
+        
+        Future<RpcResult<TransactionStatus>> commitResult2 = transaction2.commit();
+        assertNotNull(commitResult2);
+        
+        RpcResult<TransactionStatus> result2 = commitResult2.get();
+        
+        assertNotNull(result2);
+        assertNotNull(result2.getResult());
+        assertEquals(TransactionStatus.COMMITED, result2.getResult());
+    
+        DataObject readedData2 = baDataService.readConfigurationData(node1.getValue());
+        assertNull(readedData2);
+    }
+    
+    private static NodeRef createNodeRef(String string) {
+        NodeKey key = new NodeKey(new NodeId(string));
+        InstanceIdentifier<Node> path = InstanceIdentifier.builder().node(Nodes.class).node(Node.class, key)
+                .toInstance();
+        return new NodeRef(path);
+    }
+    
+    private static Node createNode(String string) {
+        NodeBuilder ret = new NodeBuilder();
+        ret.setId(new NodeId(string));
+        ret.setKey(new NodeKey(ret.getId()));
+        return ret.build();
+    }
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/MappingServiceTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/MappingServiceTest.java
new file mode 100644 (file)
index 0000000..b0c2e75
--- /dev/null
@@ -0,0 +1,118 @@
+package org.opendaylight.controller.sal.binding.test.connect.dom;
+
+import static org.junit.Assert.*;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentMappingService;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.MappingServiceImpl;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
+import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleContext;
+import org.opendaylight.yangtools.yang.binding.Augmentation;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
+
+public class MappingServiceTest {
+
+    private static final QName NODES = QName.create("urn:opendaylight:inventory", "2013-08-19", "nodes");
+    private static final QName NODE = QName.create(NODES,"node");
+    private static final QName ID = QName.create(NODES,"id");
+    
+    BindingIndependentMappingService service;
+    private MappingServiceImpl impl;
+
+    @Before
+    public void setUp() {
+        impl = new MappingServiceImpl();
+        service = impl;
+    }
+
+    @Test
+    public void baDataToBiData() throws Exception {
+
+        String[] yangFiles = new String[] { "yang-ext.yang", "ietf-inet-types.yang", "ietf-yang-types.yang",
+                "node-inventory.yang" };
+
+        SchemaContext ctx = getContext(yangFiles);
+
+        impl.onGlobalContextUpdated(ctx);
+
+        NodesBuilder nodes = new NodesBuilder();
+
+        List<Node> nodeList = new ArrayList<>();
+        nodeList.add(createChildNode("foo"));
+        nodeList.add(createChildNode("bar"));
+
+        nodes.setNode(nodeList);
+        Nodes nodesTO = nodes.build();
+        CompositeNode xmlNodes = service.toDataDom(nodesTO);
+        assertNotNull(xmlNodes);
+        List<CompositeNode> invNodes = xmlNodes.getCompositesByName(NODE);
+        assertNotNull(invNodes);
+        assertEquals(2, invNodes.size());
+    }
+
+    @Test
+    public void instanceIdentifierTest() throws Exception {
+
+        String[] yangFiles = new String[] { "yang-ext.yang", "ietf-inet-types.yang", "ietf-yang-types.yang",
+                "node-inventory.yang" };
+        SchemaContext ctx = getContext(yangFiles);
+        impl.onGlobalContextUpdated(ctx);
+
+        NodeKey nodeKey = new NodeKey(new NodeId("foo"));
+        InstanceIdentifier<Node> path = InstanceIdentifier.builder().node(Nodes.class).child(Node.class, nodeKey).toInstance();
+        org.opendaylight.yangtools.yang.data.api.InstanceIdentifier result = service.toDataDom(path);
+        assertNotNull(result);
+        assertEquals(2, result.getPath().size());
+    }
+
+    public static SchemaContext getContext(String[] yangFiles) {
+
+        ClassLoader loader = MappingServiceTest.class.getClassLoader();
+
+        List<InputStream> streams = new ArrayList<>();
+        for (String string : yangFiles) {
+            InputStream stream = loader.getResourceAsStream("META-INF/yang/" + string);
+            streams.add(stream);
+
+        }
+        YangParserImpl parser = new YangParserImpl();
+
+        Set<Module> modules = parser.parseYangModelsFromStreams(streams);
+        return parser.resolveSchemaContext(modules);
+    }
+
+    private Node createChildNode(String id) {
+        NodeBuilder node = new NodeBuilder();
+        NodeId nodeId = new NodeId(id);
+
+        node.setId(nodeId);
+        node.setKey(new NodeKey(nodeId));
+
+        FlowCapableNodeBuilder aug = new FlowCapableNodeBuilder();
+        aug.setManufacturer(id);
+        node.addAugmentation(FlowCapableNode.class, aug.build());
+
+        return node.build();
+    }
+
+}
index a20491b..e242b9e 100644 (file)
       <version>1.0-SNAPSHOT</version>
       <scope>provided</scope>
     </dependency>
+    <dependency>
+            <groupId>org.opendaylight.yangtools.thirdparty</groupId>
+            <artifactId>antlr4-runtime-osgi-nohead</artifactId>
+            <version>4.0</version>
+    </dependency>
   </dependencies>
 </project>
index 3e3ee3a..2f9c397 100644 (file)
@@ -25,6 +25,7 @@ public class TestHelper {
                 mavenBundle(CONTROLLER, "sal-common-api").versionAsInProject(), //
                 mavenBundle(CONTROLLER, "sal-common-impl").versionAsInProject(), //
                 
+                mavenBundle("org.apache.commons", "commons-lang3").versionAsInProject(),
                 mavenBundle("com.google.guava", "guava").versionAsInProject(), //
                 mavenBundle(YANGTOOLS + ".thirdparty", "xtend-lib-osgi").versionAsInProject() //
         );
@@ -44,8 +45,32 @@ public class TestHelper {
                 mavenBundle(CONTROLLER, "sal-binding-config").versionAsInProject(),
                 mavenBundle(CONTROLLER, "sal-binding-broker-impl").versionAsInProject(), //
                 mavenBundle("org.javassist", "javassist").versionAsInProject(), //
-                mavenBundle(CONTROLLER, "sal-common-util").versionAsInProject() //
-        );
+                mavenBundle(CONTROLLER, "sal-common-util").versionAsInProject(), //
+        
+                mavenBundle(YANGTOOLS, "yang-data-api").versionAsInProject(), //
+                mavenBundle(YANGTOOLS, "yang-data-impl").versionAsInProject(), //
+                mavenBundle(YANGTOOLS, "yang-model-api").versionAsInProject(), //
+                mavenBundle(YANGTOOLS, "yang-model-util").versionAsInProject(), //
+                mavenBundle(YANGTOOLS, "yang-parser-api").versionAsInProject(),
+                mavenBundle(YANGTOOLS, "yang-parser-impl").versionAsInProject(),
+                
+                
+                mavenBundle(YANGTOOLS, "binding-generator-spi").versionAsInProject(), //
+                mavenBundle(YANGTOOLS, "binding-model-api").versionAsInProject(), //
+                mavenBundle(YANGTOOLS, "binding-generator-util").versionAsInProject(),
+                mavenBundle(YANGTOOLS, "yang-parser-impl").versionAsInProject(),
+                mavenBundle(YANGTOOLS, "binding-type-provider").versionAsInProject(),
+                mavenBundle(YANGTOOLS, "binding-generator-api").versionAsInProject(),
+                mavenBundle(YANGTOOLS, "binding-generator-spi").versionAsInProject(),
+                mavenBundle(YANGTOOLS, "binding-generator-impl").versionAsInProject(),
+                
+                
+                mavenBundle(CONTROLLER, "sal-core-api").versionAsInProject().update(), //
+                mavenBundle(CONTROLLER, "sal-broker-impl").versionAsInProject(), //
+                mavenBundle(CONTROLLER, "sal-core-spi").versionAsInProject().update(), //
+                
+                mavenBundle(YANGTOOLS + ".thirdparty", "antlr4-runtime-osgi-nohead").versionAsInProject() //
+       );
 
     }
 
index d26f2e7..e1f109b 100644 (file)
@@ -11,6 +11,7 @@ import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext;
 import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.core.api.Broker;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
@@ -21,9 +22,15 @@ import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 
+import com.google.inject.Inject;
+
 public class DataServiceTest extends AbstractTest {
 
     protected DataBrokerService consumerDataService;
+    
+    
+    @Inject
+    Broker broker2;
 
     @Before
     public void setUp() throws Exception {
@@ -61,9 +68,9 @@ public class DataServiceTest extends AbstractTest {
         assertNotNull(result.getResult());
         assertEquals(TransactionStatus.COMMITED, result.getResult());
         
-        DataObject readedData = consumerDataService.readConfigurationData(node1.getValue());
+        Node readedData = (Node) consumerDataService.readConfigurationData(node1.getValue());
         assertNotNull(readedData);
-        assertEquals(nodeData1, readedData);
+        assertEquals(nodeData1.getKey(), readedData.getKey());
         
         
         DataModificationTransaction transaction2 = consumerDataService.beginTransaction();
@@ -97,7 +104,9 @@ public class DataServiceTest extends AbstractTest {
     
     private static Node createNode(String string) {
         NodeBuilder ret = new NodeBuilder();
-        ret.setId(new NodeId(string));
+        NodeId id = new NodeId(string);
+        ret.setKey(new NodeKey(id));
+        ret.setId(id);
         return ret.build();
     }
 }
index 3bd51ec..7fb0580 100644 (file)
@@ -1,50 +1,59 @@
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.opendaylight.controller</groupId>
-    <artifactId>sal-parent</artifactId>
-    <version>1.0-SNAPSHOT</version>
-  </parent>
-  <artifactId>sal-common-impl</artifactId>
-  <packaging>bundle</packaging>
-  <scm>
-    <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
-    <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
-    <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>
-  </scm>
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.opendaylight.controller</groupId>
+        <artifactId>sal-parent</artifactId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <artifactId>sal-common-impl</artifactId>
+    <packaging>bundle</packaging>
+    <scm>
+        <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
+        <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
+        <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>
+    </scm>
 
-  <dependencies>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>sal-common-api</artifactId>
-      <version>1.0-SNAPSHOT</version>
-    </dependency>
-    <dependency>
-      <groupId>com.google.guava</groupId>
-      <artifactId>guava</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.eclipse.xtend</groupId>
-      <artifactId>org.eclipse.xtend.lib</artifactId>
-    </dependency>
-  </dependencies>
+    <dependencies>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal-common-api</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal-common-util</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.xtend</groupId>
+            <artifactId>org.eclipse.xtend.lib</artifactId>
+        </dependency>
+    </dependencies>
 
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.felix</groupId>
-        <artifactId>maven-bundle-plugin</artifactId>
-        <configuration>
-          <instructions>
-            <Export-Package>
-                org.opendaylight.controller.md.sal.common.impl,
-                org.opendaylight.controller.md.sal.common.impl.*
-            </Export-Package>
-          </instructions>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <configuration>
+                    <instructions>
+                        <Export-Package>
+                            org.opendaylight.controller.md.sal.common.impl,
+                            org.opendaylight.controller.md.sal.common.impl.*
+                        </Export-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.eclipse.xtend</groupId>
+                <artifactId>xtend-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
 
 </project>
index 531ce22..d6b3c53 100644 (file)
@@ -35,7 +35,7 @@ public abstract class AbstractDataReadRouter<P extends Path<?>, D> implements Da
     @Override
     public D readOperationalData(P path) {
         FluentIterable<D> dataBits = FluentIterable //
-                .from(getReaders(configReaders, path)).transform(operationalRead(path));
+                .from(getReaders(operationalReaders, path)).transform(operationalRead(path));
         return merge(path,dataBits);
 
     }
diff --git a/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/AbstractDataBroker.xtend b/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/AbstractDataBroker.xtend
new file mode 100644 (file)
index 0000000..b878071
--- /dev/null
@@ -0,0 +1,259 @@
+package org.opendaylight.controller.md.sal.common.impl.service
+
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus
+import org.opendaylight.controller.md.sal.common.api.data.DataReader
+import org.opendaylight.yangtools.concepts.AbstractObjectRegistration
+import org.opendaylight.yangtools.concepts.ListenerRegistration
+import com.google.common.collect.Multimap
+import static com.google.common.base.Preconditions.*;
+import java.util.List
+import com.google.common.collect.HashMultimap
+import java.util.concurrent.ExecutorService
+import java.util.concurrent.Callable
+import org.opendaylight.yangtools.yang.common.RpcResult
+import java.util.Collections
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction
+import java.util.ArrayList
+import org.opendaylight.yangtools.concepts.CompositeObjectRegistration
+import java.util.Arrays
+import org.opendaylight.controller.md.sal.common.api.data.DataProvisionService
+import org.opendaylight.controller.md.sal.common.api.data.DataModificationTransactionFactory
+import org.opendaylight.controller.md.sal.common.api.data.DataChangePublisher
+import org.opendaylight.controller.md.sal.common.api.data.DataChangeListener
+import org.opendaylight.controller.sal.common.util.Rpcs
+import org.opendaylight.controller.md.sal.common.impl.AbstractDataModification
+import java.util.concurrent.Future
+import org.opendaylight.controller.md.sal.common.impl.routing.AbstractDataReadRouter
+import org.opendaylight.yangtools.concepts.Path
+import org.slf4j.LoggerFactory
+
+abstract class AbstractDataBroker<P extends Path<P>,D,DCL extends DataChangeListener<P,D>> implements 
+DataModificationTransactionFactory<P, D>, //
+DataReader<P, D>, //
+DataChangePublisher<P, D, DCL>, //
+DataProvisionService<P,D> {
+
+    @Property
+    var ExecutorService executor;
+
+    @Property
+    var AbstractDataReadRouter<P,D> dataReadRouter;
+
+    Multimap<P, DataChangeListenerRegistration<P,D,DCL>> listeners = HashMultimap.create();
+    Multimap<P, DataCommitHandlerRegistration<P,D>> commitHandlers = HashMultimap.create();
+
+
+    public new() {
+        
+    }
+
+    override final readConfigurationData(P path) {
+        return dataReadRouter.readConfigurationData(path);
+    }
+
+    override final readOperationalData(P path) {
+        return dataReadRouter.readOperationalData(path);
+    }
+
+    override final registerCommitHandler(P path,
+        DataCommitHandler<P, D> commitHandler) {
+            val registration = new DataCommitHandlerRegistration(path,commitHandler,this);
+            commitHandlers.put(path,registration)
+            return registration;
+    }
+
+    override final def registerDataChangeListener(P path, DCL listener) {
+        val reg = new DataChangeListenerRegistration(path, listener, this);
+        listeners.put(path, reg);
+        return reg;
+    }
+
+     final def registerDataReader(P path,DataReader<P,D> reader) {
+        
+        val confReg = dataReadRouter.registerConfigurationReader(path,reader);
+        val dataReg = dataReadRouter.registerOperationalReader(path,reader);
+        
+        return new CompositeObjectRegistration(reader,Arrays.asList(confReg,dataReg));
+    }
+
+    protected  final def removeListener(DataChangeListenerRegistration<P,D,DCL> registration) {
+        listeners.remove(registration.path, registration);
+    }
+
+    protected  final def removeCommitHandler(DataCommitHandlerRegistration<P,D> registration) {
+        commitHandlers.remove(registration.path, registration);
+    }
+    
+    protected  final def getActiveCommitHandlers() {
+        return commitHandlers.entries.map[ value.instance].toSet
+    }
+
+    package final def Future<RpcResult<TransactionStatus>>  commit(AbstractDataTransaction<P,D> transaction) {
+        checkNotNull(transaction);
+        transaction.changeStatus(TransactionStatus.SUBMITED);
+        val task = new TwoPhaseCommit(transaction, this);
+        return executor.submit(task);
+    }
+
+}
+
+package class DataChangeListenerRegistration<P extends Path<P>,D,DCL extends DataChangeListener<P,D>> extends AbstractObjectRegistration<DCL> implements ListenerRegistration<DCL> {
+
+    AbstractDataBroker<P,D,DCL> dataBroker;
+
+    @Property
+    val P path;
+
+    new(P path, DCL instance, AbstractDataBroker<P,D,DCL> broker) {
+        super(instance)
+        dataBroker = broker;
+        _path = path;
+    }
+
+    override protected removeRegistration() {
+        dataBroker.removeListener(this);
+        dataBroker = null;
+    }
+
+}
+
+package class DataCommitHandlerRegistration<P extends Path<P>,D>
+extends AbstractObjectRegistration<DataCommitHandler<P, D>> {
+
+    AbstractDataBroker<P,D,?> dataBroker;
+
+    @Property
+    val P path;
+
+    new(P path, DataCommitHandler<P, D> instance,
+        AbstractDataBroker<P,D,?> broker) {
+        super(instance)
+        dataBroker = broker;
+        _path = path;
+    }
+
+    override protected removeRegistration() {
+        dataBroker.removeCommitHandler(this);
+        dataBroker = null;
+    }
+
+}
+
+package class TwoPhaseCommit<P extends Path<P>,D> implements Callable<RpcResult<TransactionStatus>> {
+    
+    private static val log = LoggerFactory.getLogger(TwoPhaseCommit);
+
+    val AbstractDataTransaction<P,D> transaction;
+    val AbstractDataBroker<P,D,?> dataBroker;
+
+    new(AbstractDataTransaction<P,D> transaction, AbstractDataBroker<P,D,?> broker) {
+        this.transaction = transaction;
+        this.dataBroker = broker;
+    }
+
+    override call() throws Exception {
+
+        val Iterable<DataCommitHandler<P, D>> commitHandlers = dataBroker.activeCommitHandlers;
+
+        // requesting commits
+        val List<DataCommitTransaction<P, D>> handlerTransactions = new ArrayList();
+        try {
+            for (handler : commitHandlers) {
+                handlerTransactions.add(handler.requestCommit(transaction));
+            }
+        } catch (Exception e) {
+            log.error("Request Commit failded",e);
+            return rollback(handlerTransactions,e);
+        }
+        val List<RpcResult<Void>> results = new ArrayList();
+        try {
+            for (subtransaction : handlerTransactions) {
+                results.add(subtransaction.finish());
+            }
+        } catch (Exception e) {
+            log.error("Finish Commit failed",e);
+            return rollback(handlerTransactions,e);
+        }
+
+        return Rpcs.getRpcResult(true, TransactionStatus.COMMITED, Collections.emptySet());
+    }
+
+    def rollback(List<DataCommitTransaction<P, D>> transactions,Exception e) {
+        for (transaction : transactions) {
+            transaction.rollback()
+        }
+        // FIXME return encountered error.
+        return Rpcs.getRpcResult(false, TransactionStatus.FAILED, Collections.emptySet());
+    }
+}
+
+public abstract class AbstractDataTransaction<P extends Path<P>, D> extends AbstractDataModification<P, D> {
+
+    @Property
+    private val Object identifier;
+
+    
+    var TransactionStatus status;
+    
+    
+    var AbstractDataBroker<P, D, ?> broker;
+
+    protected new (AbstractDataBroker<P,D,?> dataBroker) {
+        super(dataBroker);
+        _identifier = new Object();
+        broker = dataBroker;
+        status = TransactionStatus.NEW;
+        //listeners = new ListenerRegistry<>();
+    }
+
+    override  commit() {
+        return broker.commit(this);
+    }
+
+    override readConfigurationData(P path) {
+        return broker.readConfigurationData(path);
+    }
+
+    override readOperationalData(P path) {
+        return broker.readOperationalData(path);
+    }
+
+    override hashCode() {
+        return identifier.hashCode;
+    }
+
+    override equals(Object obj) {
+        if (this === obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        val other = (obj as AbstractDataTransaction<P,D>) ;
+        if (broker == null) {
+            if (other.broker != null)
+                return false;
+        } else if (!broker.equals(other.broker))
+            return false;
+        if (identifier == null) {
+            if (other.identifier != null)
+                return false;
+        } else if (!identifier.equals(other.identifier))
+            return false;
+        return true;
+    }
+
+    override TransactionStatus getStatus() {
+        return status;
+    }
+
+    
+    protected abstract def void onStatusChange(TransactionStatus status);
+    
+    public def changeStatus(TransactionStatus status) {
+        this.status = status;
+        onStatusChange(status);
+    }
+    
+}
index e49cb4b..3af645a 100644 (file)
@@ -8,6 +8,8 @@ import org.opendaylight.controller.sal.core.api.data.DataProviderService;
 import org.opendaylight.controller.sal.core.api.model.SchemaService;
 import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
 import org.opendaylight.controller.sal.core.api.mount.MountService;
+import org.opendaylight.controller.sal.dom.broker.impl.HashMapDataStore;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
@@ -15,6 +17,7 @@ import org.osgi.framework.ServiceRegistration;
 
 public class BrokerActivator implements BundleActivator {
 
+    private static final InstanceIdentifier ROOT = InstanceIdentifier.builder().toInstance();
     BrokerImpl broker;
     private ServiceRegistration<Broker> brokerReg;
     private ServiceRegistration<SchemaService> schemaReg;
@@ -25,13 +28,14 @@ public class BrokerActivator implements BundleActivator {
     private MountPointManagerImpl mountService;
     private ServiceRegistration<MountService> mountReg;
     private ServiceRegistration<MountProvisionService> mountProviderReg;
+    private HashMapDataStore hashMapStore;
 
     @Override
     public void start(BundleContext context) throws Exception {
         Hashtable<String, String> emptyProperties = new Hashtable<String, String>();
         broker = new BrokerImpl();
         broker.setBundleContext(context);
-        brokerReg = context.registerService(Broker.class, broker, emptyProperties);
+        
 
         schemaService = new SchemaServiceImpl();
         schemaService.setContext(context);
@@ -40,14 +44,24 @@ public class BrokerActivator implements BundleActivator {
         schemaReg = context.registerService(SchemaService.class, schemaService, new Hashtable<String, String>());
         
         dataService = new DataBrokerImpl();
+        dataService.setExecutor(broker.getExecutor());
+        
         dataReg = context.registerService(DataBrokerService.class, dataService, emptyProperties);
         dataProviderReg = context.registerService(DataProviderService.class, dataService, emptyProperties);
         
+        hashMapStore = new HashMapDataStore();
+        
+        dataService.registerConfigurationReader(ROOT, hashMapStore);
+        dataService.registerCommitHandler(ROOT, hashMapStore);
+        dataService.registerOperationalReader(ROOT, hashMapStore);
+        
         mountService = new MountPointManagerImpl();
         mountService.setDataBroker(dataService);
         
         mountReg = context.registerService(MountService.class, mountService, emptyProperties);
         mountProviderReg =  context.registerService(MountProvisionService.class, mountService, emptyProperties);
+        
+        brokerReg = context.registerService(Broker.class, broker, emptyProperties);
     }
 
     @Override
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/DataBrokerImpl.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/DataBrokerImpl.java
new file mode 100644 (file)
index 0000000..d95fdcc
--- /dev/null
@@ -0,0 +1,66 @@
+package org.opendaylight.controller.sal.dom.broker;
+
+import org.opendaylight.controller.md.sal.common.api.data.DataReader;
+import org.opendaylight.controller.md.sal.common.impl.service.AbstractDataBroker;
+import org.opendaylight.controller.sal.common.DataStoreIdentifier;
+import org.opendaylight.controller.sal.core.api.data.DataChangeListener;
+import org.opendaylight.controller.sal.core.api.data.DataProviderService;
+import org.opendaylight.controller.sal.core.api.data.DataValidator;
+import org.opendaylight.controller.sal.dom.broker.impl.DataReaderRouter;
+import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+
+public class DataBrokerImpl extends AbstractDataBroker<InstanceIdentifier, CompositeNode, DataChangeListener> implements
+        DataProviderService {
+
+    public DataBrokerImpl() {
+        setDataReadRouter(new DataReaderRouter());
+    }
+
+    @Override
+    public DataTransactionImpl beginTransaction() {
+        return new DataTransactionImpl(this);
+    }
+
+    @Override
+    public Registration<DataReader<InstanceIdentifier, CompositeNode>> registerConfigurationReader(
+            InstanceIdentifier path, DataReader<InstanceIdentifier, CompositeNode> reader) {
+        return getDataReadRouter().registerConfigurationReader(path, reader);
+    }
+
+    @Override
+    public Registration<DataReader<InstanceIdentifier, CompositeNode>> registerOperationalReader(
+            InstanceIdentifier path, DataReader<InstanceIdentifier, CompositeNode> reader) {
+        return getDataReadRouter().registerOperationalReader(path, reader);
+    }
+
+    @Deprecated
+    @Override
+    public void addValidator(DataStoreIdentifier store, DataValidator validator) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Deprecated
+    @Override
+    public void removeValidator(DataStoreIdentifier store, DataValidator validator) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Deprecated
+    @Override
+    public void addRefresher(DataStoreIdentifier store, DataRefresher refresher) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Deprecated
+    @Override
+    public void removeRefresher(DataStoreIdentifier store, DataRefresher refresher) {
+        // TODO Auto-generated method stub
+
+    }
+
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/DataBrokerImpl.xtend b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/DataBrokerImpl.xtend
deleted file mode 100644 (file)
index 8a17c83..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-package org.opendaylight.controller.sal.dom.broker
-
-import org.opendaylight.controller.sal.core.api.data.DataProviderService
-import org.opendaylight.controller.sal.common.DataStoreIdentifier
-import org.opendaylight.controller.sal.core.api.data.DataProviderService.DataRefresher
-import org.opendaylight.controller.sal.core.api.data.DataValidator
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
-import org.opendaylight.controller.sal.dom.broker.impl.DataReaderRouter
-import org.opendaylight.controller.sal.core.api.data.DataChangeListener
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
-import org.opendaylight.yangtools.yang.data.api.CompositeNode
-import org.opendaylight.controller.md.sal.common.api.data.DataReader
-
-class DataBrokerImpl implements DataProviderService {
-
-    val readRouter = new DataReaderRouter();
-
-    override addRefresher(DataStoreIdentifier store, DataRefresher refresher) {
-        // NOOP
-    }
-
-    override addValidator(DataStoreIdentifier store, DataValidator validator) {
-        // NOOP
-    }
-
-    override beginTransaction() {
-        // NOOP
-    }
-
-    override readConfigurationData(InstanceIdentifier path) {
-        readRouter.readConfigurationData(path)
-    }
-
-    override readOperationalData(InstanceIdentifier path) {
-        readRouter.readOperationalData(path)
-    }
-
-    override registerConfigurationReader(InstanceIdentifier path, DataReader<InstanceIdentifier, CompositeNode> reader) {
-        readRouter.registerConfigurationReader(path, reader);
-    }
-
-    override registerOperationalReader(InstanceIdentifier path, DataReader<InstanceIdentifier, CompositeNode> reader) {
-        readRouter.registerOperationalReader(path, reader);
-    }
-
-    override removeRefresher(DataStoreIdentifier store, DataRefresher refresher) {
-        // NOOP
-    }
-
-    override removeValidator(DataStoreIdentifier store, DataValidator validator) {
-        // NOOP
-    }
-
-    override registerDataChangeListener(InstanceIdentifier path, DataChangeListener listener) {
-        // NOOP
-    }
-
-    override registerCommitHandler(InstanceIdentifier path,
-        DataCommitHandler<InstanceIdentifier, CompositeNode> commitHandler) {
-        // NOOP
-    }
-
-}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/DataTransactionImpl.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/DataTransactionImpl.java
new file mode 100644 (file)
index 0000000..5cb01c9
--- /dev/null
@@ -0,0 +1,31 @@
+package org.opendaylight.controller.sal.dom.broker;
+
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.md.sal.common.impl.service.AbstractDataTransaction;
+import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.concepts.util.ListenerRegistry;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+
+public class DataTransactionImpl extends AbstractDataTransaction<InstanceIdentifier, CompositeNode> 
+    implements DataModificationTransaction {
+    private final ListenerRegistry<DataTransactionListener> listeners = new ListenerRegistry<DataTransactionListener>();
+    
+    
+    
+    public DataTransactionImpl(DataBrokerImpl dataBroker) {
+        super(dataBroker);
+    }
+
+    @Override
+    public ListenerRegistration<DataTransactionListener> registerListener(DataTransactionListener listener) {
+        return listeners.register(listener);
+    }
+
+    protected void onStatusChange(TransactionStatus status) {
+        for (ListenerRegistration<DataTransactionListener> listenerRegistration : listeners) {
+            listenerRegistration.getInstance().onStatusUpdated(this, status);
+        }
+    }
+}
\ No newline at end of file
index b0c61c9..fbed2ca 100644 (file)
@@ -8,7 +8,11 @@ import org.opendaylight.controller.md.sal.common.api.data.DataReader
 class DataReaderRouter extends AbstractDataReadRouter<InstanceIdentifier, CompositeNode> {
 
     override protected merge(InstanceIdentifier path, Iterable<CompositeNode> data) {
-        return data.iterator.next
+        val iterator = data.iterator;
+        if(iterator.hasNext) {
+            return data.iterator.next
+        }
+        return null;
     }
 
 }
@@ -1,10 +1,7 @@
-package org.opendaylight.controller.sal.binding.impl
+package org.opendaylight.controller.sal.dom.broker.impl
 
 import org.opendaylight.controller.md.sal.common.api.data.DataReader
-import org.opendaylight.controller.sal.binding.api.data.RuntimeDataProvider
 import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.yangtools.yang.binding.DataObject
 import org.opendaylight.controller.md.sal.common.api.data.DataModification
 import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction
 import org.opendaylight.yangtools.yang.common.RpcResult
@@ -12,58 +9,58 @@ import java.util.Map
 import java.util.concurrent.ConcurrentHashMap
 import org.opendaylight.controller.sal.common.util.Rpcs
 import java.util.Collections
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
+import org.opendaylight.yangtools.yang.data.api.CompositeNode
 
 class HashMapDataStore //
 implements //
-RuntimeDataProvider, DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> {
+DataReader<InstanceIdentifier, CompositeNode>, DataCommitHandler<InstanceIdentifier, CompositeNode> {
 
-    val Map<InstanceIdentifier<? extends DataObject>,DataObject> configuration = new ConcurrentHashMap();
-    val Map<InstanceIdentifier<? extends DataObject>,DataObject> operational = new ConcurrentHashMap();
+    val Map<InstanceIdentifier, CompositeNode> configuration = new ConcurrentHashMap();
+    val Map<InstanceIdentifier, CompositeNode> operational = new ConcurrentHashMap();
 
-
-    override readConfigurationData(InstanceIdentifier<? extends DataObject> path) {
+    override readConfigurationData(InstanceIdentifier path) {
         configuration.get(path);
     }
 
-    override readOperationalData(InstanceIdentifier<? extends DataObject> path) {
+    override readOperationalData(InstanceIdentifier path) {
         operational.get(path);
     }
 
-    override requestCommit(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
-        return new HashMapDataStoreTransaction(modification,this);
+    override requestCommit(DataModification<InstanceIdentifier, CompositeNode> modification) {
+        return new HashMapDataStoreTransaction(modification, this);
     }
-    
+
     def RpcResult<Void> rollback(HashMapDataStoreTransaction transaction) {
-        return Rpcs.getRpcResult(true,null,Collections.emptySet);
+        return Rpcs.getRpcResult(true, null, Collections.emptySet);
     }
-    
+
     def RpcResult<Void> finish(HashMapDataStoreTransaction transaction) {
         val modification = transaction.modification;
         configuration.putAll(modification.updatedConfigurationData);
         operational.putAll(modification.updatedOperationalData);
-        
-        for(removal : modification.removedConfigurationData) {
+
+        for (removal : modification.removedConfigurationData) {
             configuration.remove(removal);
         }
-        for(removal : modification.removedOperationalData) {
+        for (removal : modification.removedOperationalData) {
             operational.remove(removal);
         }
-        return Rpcs.getRpcResult(true,null,Collections.emptySet);
+        return Rpcs.getRpcResult(true, null, Collections.emptySet);
     }
 
 }
 
 class HashMapDataStoreTransaction implements // 
-DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject> {
+DataCommitTransaction<InstanceIdentifier, CompositeNode> {
     @Property
-    val DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification
+    val DataModification<InstanceIdentifier, CompositeNode> modification
 
     @Property
     val HashMapDataStore datastore;
-    
-    
+
     new(
-        DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modify,
+        DataModification<InstanceIdentifier, CompositeNode> modify,
         HashMapDataStore store
     ) {
         _modification = modify;
index 6f53bcd..a1925a5 100644 (file)
             <artifactId>logback-classic</artifactId>
             <version>1.0.9</version>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.yangtools.thirdparty</groupId>
+            <artifactId>antlr4-runtime-osgi-nohead</artifactId>
+            <version>4.0</version>
+        </dependency>
     </dependencies>
 </project>
index 7cd4fa5..337648a 100644 (file)
@@ -23,6 +23,10 @@ public class ToasterTest {
 
     public static final String ODL = "org.opendaylight.controller";
     public static final String YANG = "org.opendaylight.yangtools";
+    public static final String CONTROLLER = "org.opendaylight.controller";
+    public static final String YANGTOOLS = "org.opendaylight.yangtools";
+    
+    
     public static final String SAMPLE = "org.opendaylight.controller.samples";
 
     @Test
@@ -50,9 +54,6 @@ public class ToasterTest {
                 mavenBundle("org.slf4j", "log4j-over-slf4j").versionAsInProject(), //
                 mavenBundle("ch.qos.logback", "logback-core").versionAsInProject(), //
                 mavenBundle("ch.qos.logback", "logback-classic").versionAsInProject(), //
-                mavenBundle(ODL, "sal-binding-api").versionAsInProject(), //
-                mavenBundle(ODL, "sal-binding-config").versionAsInProject(), 
-                mavenBundle(ODL, "sal-binding-broker-impl").versionAsInProject(), //
                 
                 mavenBundle(ODL, "sal-common").versionAsInProject(), //
                 mavenBundle(ODL, "sal-common-api").versionAsInProject(),//
@@ -62,7 +63,37 @@ public class ToasterTest {
                 mavenBundle(ODL, "config-api").versionAsInProject(), //
                 mavenBundle(ODL, "config-manager").versionAsInProject(), //
                 mavenBundle("commons-io", "commons-io").versionAsInProject(),
+                mavenBundle("org.apache.commons", "commons-lang3").versionAsInProject(),
                 
+                mavenBundle(CONTROLLER, "sal-binding-api").versionAsInProject(), //
+                mavenBundle(CONTROLLER, "sal-binding-config").versionAsInProject(),
+                mavenBundle(CONTROLLER, "sal-binding-broker-impl").versionAsInProject(), //
+                mavenBundle("org.javassist", "javassist").versionAsInProject(), //
+                mavenBundle(CONTROLLER, "sal-common-util").versionAsInProject(), //
+        
+                mavenBundle(YANGTOOLS, "yang-data-api").versionAsInProject(), //
+                mavenBundle(YANGTOOLS, "yang-data-impl").versionAsInProject(), //
+                mavenBundle(YANGTOOLS, "yang-model-api").versionAsInProject(), //
+                mavenBundle(YANGTOOLS, "yang-model-util").versionAsInProject(), //
+                mavenBundle(YANGTOOLS, "yang-parser-api").versionAsInProject(),
+                mavenBundle(YANGTOOLS, "yang-parser-impl").versionAsInProject(),
+                
+                
+                mavenBundle(YANGTOOLS, "binding-generator-spi").versionAsInProject(), //
+                mavenBundle(YANGTOOLS, "binding-model-api").versionAsInProject(), //
+                mavenBundle(YANGTOOLS, "binding-generator-util").versionAsInProject(),
+                mavenBundle(YANGTOOLS, "yang-parser-impl").versionAsInProject(),
+                mavenBundle(YANGTOOLS, "binding-type-provider").versionAsInProject(),
+                mavenBundle(YANGTOOLS, "binding-generator-api").versionAsInProject(),
+                mavenBundle(YANGTOOLS, "binding-generator-spi").versionAsInProject(),
+                mavenBundle(YANGTOOLS, "binding-generator-impl").versionAsInProject(),
+                
+                
+                mavenBundle(CONTROLLER, "sal-core-api").versionAsInProject().update(), //
+                mavenBundle(CONTROLLER, "sal-broker-impl").versionAsInProject(), //
+                mavenBundle(CONTROLLER, "sal-core-spi").versionAsInProject().update(), //
+                
+                mavenBundle(YANGTOOLS + ".thirdparty", "antlr4-runtime-osgi-nohead").versionAsInProject(), //
                 
                 mavenBundle(SAMPLE, "sample-toaster").versionAsInProject(), //
                 mavenBundle(SAMPLE, "sample-toaster-consumer").versionAsInProject(), //