Merge "Move the CompositeModificatoinPayload message to proper package The package...
authorMoiz Raja <moraja@cisco.com>
Thu, 14 Aug 2014 17:19:08 +0000 (17:19 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Thu, 14 Aug 2014 17:19:08 +0000 (17:19 +0000)
33 files changed:
opendaylight/commons/opendaylight/pom.xml
opendaylight/distribution/opendaylight/pom.xml
opendaylight/md-sal/inventory-manager/src/main/java/org/opendaylight/controller/md/inventory/manager/FlowCapableInventoryProvider.java
opendaylight/md-sal/inventory-manager/src/main/java/org/opendaylight/controller/md/inventory/manager/InventoryActivator.java
opendaylight/md-sal/inventory-manager/src/main/java/org/opendaylight/controller/md/inventory/manager/InventoryOperation.java
opendaylight/md-sal/inventory-manager/src/main/java/org/opendaylight/controller/md/inventory/manager/NodeChangeCommiter.java
opendaylight/md-sal/sal-binding-broker/pom.xml
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/BindingAsyncDataBrokerImplModule.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/DataBrokerImplModule.java [deleted file]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/DataBrokerImplModuleFactory.java [deleted file]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/ForwardedCompatibleDataBrokerImplModule.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/RuntimeMappingModule.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/AbstractForwardedDataBroker.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingToNormalizedNodeCodec.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/ForwardedBackwardsCompatibleDataBroker.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/ForwardedBindingDataBroker.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/SingletonHolder.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RootDataBrokerImpl.java [deleted file]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedDataBrokerImpl.java [deleted file]
opendaylight/md-sal/sal-binding-broker/src/main/yang/opendaylight-binding-broker-impl.yang
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/BindingNormalizedCodecTest.java
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/test/DataBrokerTestCustomizer.java
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/compat/MultipleAugmentationPutsTest.java
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/util/BindingTestContext.java
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-binding-it/src/test/resources/controller.xml
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowStatsTracker.java
opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyExporter.java
opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyProvider.java
opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/OperationProcessor.java
opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/TopologyOperation.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter.java

index 66a403560e132addee3c6ab35181c1daafd457f7..c74e7ae4108297abcb2799f0a7f81c4b23d892b6 100644 (file)
         <artifactId>binding-generator-impl</artifactId>
         <version>${yangtools.version}</version>
       </dependency>
+      <dependency>
+        <groupId>org.opendaylight.yangtools</groupId>
+        <artifactId>binding-data-codec</artifactId>
+        <version>${yangtools.version}</version>
+      </dependency>
       <dependency>
         <groupId>org.opendaylight.yangtools</groupId>
         <artifactId>binding-generator-spi</artifactId>
index 969ecc2cbed41054fde61fb8aecfe8ae940ed95d..d70bf4641192c488d043e2ba7ff4bc41279b1375 100644 (file)
           <groupId>org.opendaylight.yangtools</groupId>
           <artifactId>binding-generator-impl</artifactId>
         </dependency>
+        <dependency>
+          <groupId>org.opendaylight.yangtools</groupId>
+          <artifactId>binding-data-codec</artifactId>
+        </dependency>
         <dependency>
           <groupId>org.opendaylight.yangtools</groupId>
           <artifactId>binding-generator-spi</artifactId>
index 9724d31f9ae6cd3ab8eaef0c23212bf626cfca84..ff3984a548eeb3a7d6ed2f93da04b2f1c801802b 100644 (file)
@@ -7,21 +7,20 @@
  */
 package org.opendaylight.controller.md.inventory.manager;
 
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
 import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.ExecutionException;
 import java.util.concurrent.LinkedBlockingDeque;
-
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
-import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Preconditions;
-
 class FlowCapableInventoryProvider implements AutoCloseable, Runnable {
     private static final Logger LOG = LoggerFactory.getLogger(FlowCapableInventoryProvider.class);
     private static final int QUEUE_DEPTH = 500;
@@ -29,12 +28,13 @@ class FlowCapableInventoryProvider implements AutoCloseable, Runnable {
 
     private final BlockingQueue<InventoryOperation> queue = new LinkedBlockingDeque<>(QUEUE_DEPTH);
     private final NotificationProviderService notificationService;
-    private final DataProviderService dataService;
+
+    private final DataBroker dataBroker;
     private ListenerRegistration<?> listenerRegistration;
     private Thread thread;
 
-    FlowCapableInventoryProvider(final DataProviderService dataService, final NotificationProviderService notificationService) {
-        this.dataService = Preconditions.checkNotNull(dataService);
+    FlowCapableInventoryProvider(final DataBroker dataBroker, final NotificationProviderService notificationService) {
+        this.dataBroker = Preconditions.checkNotNull(dataBroker);
         this.notificationService = Preconditions.checkNotNull(notificationService);
     }
 
@@ -82,10 +82,10 @@ class FlowCapableInventoryProvider implements AutoCloseable, Runnable {
     @Override
     public void run() {
         try {
-            for (;;) {
+            for (; ; ) {
                 InventoryOperation op = queue.take();
 
-                final DataModificationTransaction tx = dataService.beginTransaction();
+                final ReadWriteTransaction tx = dataBroker.newReadWriteTransaction();
                 LOG.debug("New operations available, starting transaction {}", tx.getIdentifier());
 
                 int ops = 0;
@@ -102,14 +102,17 @@ class FlowCapableInventoryProvider implements AutoCloseable, Runnable {
 
                 LOG.debug("Processed {} operations, submitting transaction {}", ops, tx.getIdentifier());
 
-                try {
-                    final RpcResult<TransactionStatus> result = tx.commit().get();
-                    if(!result.isSuccessful()) {
-                        LOG.error("Transaction {} failed", tx.getIdentifier());
+                final CheckedFuture<Void, TransactionCommitFailedException> result = tx.submit();
+                Futures.addCallback(result, new FutureCallback<Object>() {
+                    @Override
+                    public void onSuccess(Object o) {
+                    }
+
+                    @Override
+                    public void onFailure(Throwable throwable) {
+                        LOG.error("Transaction {} failed.", tx.getIdentifier(), throwable);
                     }
-                } catch (ExecutionException e) {
-                    LOG.warn("Failed to commit inventory change", e.getCause());
-                }
+                });
             }
         } catch (InterruptedException e) {
             LOG.info("Processing interrupted, terminating", e);
index 5bcae367e3e98a6270e01e270adbd2f231256fa9..991611aebc4492c63bd8ece7f7eb1f10289b89da 100644 (file)
@@ -7,10 +7,10 @@
  */
 package org.opendaylight.controller.md.inventory.manager;
 
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
 import org.osgi.framework.BundleContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -21,11 +21,11 @@ public class InventoryActivator extends AbstractBindingAwareProvider {
 
     @Override
     public void onSessionInitiated(final ProviderContext session) {
-        DataProviderService salDataService = session.getSALService(DataProviderService.class);
+        DataBroker dataBroker = session.getSALService(DataBroker.class);
         NotificationProviderService salNotifiService =
                 session.getSALService(NotificationProviderService.class);
 
-        provider = new FlowCapableInventoryProvider(salDataService, salNotifiService);
+        provider = new FlowCapableInventoryProvider(dataBroker, salNotifiService);
         provider.start();
     }
 
index 3be5fcf643fec84694a5ba0ae4eacc1e557a5c01..cfc95799839a40cac8ef195e79d8320c1e42e91e 100644 (file)
@@ -7,10 +7,10 @@
  */
 package org.opendaylight.controller.md.inventory.manager;
 
-import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 
 interface InventoryOperation {
 
-    void applyOperation(DataModificationTransaction tx);
+    void applyOperation(ReadWriteTransaction tx);
 
 }
index 3db3c93fcce11ccf46569514b901ef3c9c99e60d..1b031990ab9f6808aed11c265e0672614559f4c2 100644 (file)
@@ -7,7 +7,9 @@
  */
 package org.opendaylight.controller.md.inventory.manager;
 
-import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnectorUpdated;
@@ -30,8 +32,6 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdenti
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Preconditions;
-
 class NodeChangeCommiter implements OpendaylightInventoryListener {
     private static final Logger LOG = LoggerFactory.getLogger(NodeChangeCommiter.class);
 
@@ -43,21 +43,23 @@ class NodeChangeCommiter implements OpendaylightInventoryListener {
 
     @Override
     public synchronized void onNodeConnectorRemoved(final NodeConnectorRemoved connector) {
+        LOG.debug("Node connector removed notification received.");
         manager.enqueue(new InventoryOperation() {
             @Override
-            public void applyOperation(final DataModificationTransaction tx) {
+            public void applyOperation(final ReadWriteTransaction tx) {
                 final NodeConnectorRef ref = connector.getNodeConnectorRef();
                 LOG.debug("removing node connector {} ", ref.getValue());
-                tx.removeOperationalData(ref.getValue());
+                tx.delete(LogicalDatastoreType.OPERATIONAL, ref.getValue());
             }
         });
     }
 
     @Override
     public synchronized void onNodeConnectorUpdated(final NodeConnectorUpdated connector) {
+        LOG.debug("Node connector updated notification received.");
         manager.enqueue(new InventoryOperation() {
             @Override
-            public void applyOperation(final DataModificationTransaction tx) {
+            public void applyOperation(final ReadWriteTransaction tx) {
                 final NodeConnectorRef ref = connector.getNodeConnectorRef();
                 final NodeConnectorBuilder data = new NodeConnectorBuilder(connector);
                 data.setKey(new NodeConnectorKey(connector.getId()));
@@ -68,22 +70,23 @@ class NodeChangeCommiter implements OpendaylightInventoryListener {
                     final FlowCapableNodeConnector augment = InventoryMapping.toInventoryAugment(flowConnector);
                     data.addAugmentation(FlowCapableNodeConnector.class, augment);
                 }
-                InstanceIdentifier<? extends Object> value = ref.getValue();
+                InstanceIdentifier<NodeConnector> value = (InstanceIdentifier<NodeConnector>) ref.getValue();
                 LOG.debug("updating node connector : {}.", value);
                 NodeConnector build = data.build();
-                tx.putOperationalData(value, build);
+                tx.put(LogicalDatastoreType.OPERATIONAL, value, build);
             }
         });
     }
 
     @Override
     public synchronized void onNodeRemoved(final NodeRemoved node) {
+        LOG.debug("Node removed notification received.");
         manager.enqueue(new InventoryOperation() {
             @Override
-            public void applyOperation(final DataModificationTransaction tx) {
+            public void applyOperation(final ReadWriteTransaction tx) {
                 final NodeRef ref = node.getNodeRef();
                 LOG.debug("removing node : {}", ref.getValue());
-                tx.removeOperationalData((ref.getValue()));
+                tx.delete(LogicalDatastoreType.OPERATIONAL, ref.getValue());
             }
         });
     }
@@ -94,10 +97,10 @@ class NodeChangeCommiter implements OpendaylightInventoryListener {
         if (flowNode == null) {
             return;
         }
-
+        LOG.debug("Node updated notification received.");
         manager.enqueue(new InventoryOperation() {
             @Override
-            public void applyOperation(final DataModificationTransaction tx) {
+            public void applyOperation(final ReadWriteTransaction tx) {
                 final NodeRef ref = node.getNodeRef();
                 final NodeBuilder nodeBuilder = new NodeBuilder(node);
                 nodeBuilder.setKey(new NodeKey(node.getId()));
@@ -110,7 +113,7 @@ class NodeChangeCommiter implements OpendaylightInventoryListener {
                 InstanceIdentifierBuilder<FlowCapableNode> augmentation = builder.augmentation(FlowCapableNode.class);
                 final InstanceIdentifier<FlowCapableNode> path = augmentation.build();
                 LOG.debug("updating node :{} ", path);
-                tx.putOperationalData(path, augment);
+                tx.put(LogicalDatastoreType.OPERATIONAL, path, augment);
             }
         });
     }
index 74cceb1cbd55fc786b78e3f111b2a82a60bd8751..539f9d45c8b8c30ebfcde9da22229bd4c2a547ab 100644 (file)
       <groupId>org.opendaylight.yangtools</groupId>
       <artifactId>binding-generator-impl</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>binding-data-codec</artifactId>
+      <version>0.6.2-SNAPSHOT</version>
+    </dependency>
     <dependency>
       <groupId>org.opendaylight.yangtools</groupId>
       <artifactId>yang-data-impl</artifactId>
index 018e26878c9873490d6c3ed88822edb78efe0280..93d99c832fcc2bbffe5a7c5f851fe2fec2ef7558 100644 (file)
@@ -2,14 +2,13 @@ package org.opendaylight.controller.config.yang.md.sal.binding.impl;
 
 import java.util.Collection;
 import java.util.Collections;
-
+import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
 import org.opendaylight.controller.md.sal.binding.impl.ForwardedBindingDataBroker;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
 import org.opendaylight.controller.sal.core.api.Broker;
 import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
 import org.opendaylight.controller.sal.core.api.Provider;
 import org.opendaylight.controller.sal.core.api.model.SchemaService;
-import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
 
 public class BindingAsyncDataBrokerImplModule extends
         org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractBindingAsyncDataBrokerImplModule implements
@@ -36,7 +35,7 @@ public class BindingAsyncDataBrokerImplModule extends
     @Override
     public java.lang.AutoCloseable createInstance() {
         Broker domBroker = getDomAsyncBrokerDependency();
-        BindingIndependentMappingService mappingService = getBindingMappingServiceDependency();
+        BindingToNormalizedNodeCodec mappingService = getBindingMappingServiceDependency();
 
         // FIXME: Switch this to DOM Broker registration which would not require
         // BundleContext when API are updated.
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/DataBrokerImplModule.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/DataBrokerImplModule.java
deleted file mode 100644 (file)
index 4a4e800..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.config.yang.md.sal.binding.impl;
-
-import java.util.concurrent.ExecutorService;
-
-import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder;
-import org.opendaylight.controller.sal.binding.impl.RootDataBrokerImpl;
-import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingDomConnectorDeployer;
-import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentConnector;
-import org.opendaylight.controller.sal.binding.impl.forward.DomForwardedDataBrokerImpl;
-import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
-import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
-
-/**
-*
-*/
-public final class DataBrokerImplModule extends
-        org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractDataBrokerImplModule {
-
-    public DataBrokerImplModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier,
-            final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
-        super(identifier, dependencyResolver);
-    }
-
-    public DataBrokerImplModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier,
-            final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,
-            final DataBrokerImplModule oldModule, final java.lang.AutoCloseable oldInstance) {
-        super(identifier, dependencyResolver, oldModule, oldInstance);
-    }
-
-    @Override
-    public void validate() {
-        super.validate();
-    }
-
-    @Override
-    public java.lang.AutoCloseable createInstance() {
-        RootDataBrokerImpl dataBindingBroker;
-
-
-        ExecutorService listeningExecutor = SingletonHolder.getDefaultCommitExecutor();
-        BindingIndependentMappingService potentialMapping = getMappingServiceDependency();
-        if (getDomBrokerDependency() != null && potentialMapping != null) {
-
-            dataBindingBroker = createDomConnectedBroker(listeningExecutor,potentialMapping);
-        } else {
-            dataBindingBroker = createStandAloneBroker(listeningExecutor);
-        }
-        dataBindingBroker.registerRuntimeBean(getRootRuntimeBeanRegistratorWrapper());
-        dataBindingBroker.setNotificationExecutor(SingletonHolder.getDefaultChangeEventExecutor());
-        return dataBindingBroker;
-    }
-
-
-    private RootDataBrokerImpl createStandAloneBroker(final ExecutorService listeningExecutor) {
-        RootDataBrokerImpl broker = new RootDataBrokerImpl();
-        broker.setExecutor(listeningExecutor);
-        return broker;
-    }
-
-    private RootDataBrokerImpl createDomConnectedBroker(final ExecutorService listeningExecutor, final BindingIndependentMappingService mappingService) {
-        DomForwardedDataBrokerImpl forwardedBroker = new DomForwardedDataBrokerImpl();
-        forwardedBroker.setExecutor(listeningExecutor);
-        BindingIndependentConnector connector = BindingDomConnectorDeployer.createConnector(mappingService);
-        getDomBrokerDependency().registerProvider(forwardedBroker, null);
-        ProviderSession domContext = forwardedBroker.getDomProviderContext();
-        forwardedBroker.setConnector(connector);
-        forwardedBroker.setDomProviderContext(domContext);
-        forwardedBroker.startForwarding();
-        return forwardedBroker;
-    }
-
-}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/DataBrokerImplModuleFactory.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/DataBrokerImplModuleFactory.java
deleted file mode 100644 (file)
index d3fc5ac..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.config.yang.md.sal.binding.impl;
-
-
-/**
-*
-*/
-public class DataBrokerImplModuleFactory extends
-        org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractDataBrokerImplModuleFactory {
-
-}
index 0ea30f7e66a817f63c63cc81e20f3890170ea7b5..2bc673adfff4219a9b6b84b07fc478fd8fd7164b 100644 (file)
@@ -7,9 +7,10 @@
  */
 package org.opendaylight.controller.config.yang.md.sal.binding.impl;
 
+import com.google.common.util.concurrent.ListeningExecutorService;
 import java.util.Collection;
 import java.util.Collections;
-
+import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
 import org.opendaylight.controller.md.sal.binding.impl.ForwardedBackwardsCompatibleDataBroker;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
 import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder;
@@ -18,9 +19,6 @@ import org.opendaylight.controller.sal.core.api.Broker;
 import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
 import org.opendaylight.controller.sal.core.api.Provider;
 import org.opendaylight.controller.sal.core.api.model.SchemaService;
-import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
-
-import com.google.common.util.concurrent.ListeningExecutorService;
 
 /**
 *
@@ -51,7 +49,7 @@ public final class ForwardedCompatibleDataBrokerImplModule extends
     @Override
     public java.lang.AutoCloseable createInstance() {
         ListeningExecutorService listeningExecutor = SingletonHolder.getDefaultCommitExecutor();
-        BindingIndependentMappingService mappingService = getBindingMappingServiceDependency();
+        BindingToNormalizedNodeCodec mappingService = getBindingMappingServiceDependency();
 
         Broker domBroker = getDomAsyncBrokerDependency();
         ProviderSession session = domBroker.registerProvider(this, null);
@@ -60,7 +58,7 @@ public final class ForwardedCompatibleDataBrokerImplModule extends
         ForwardedBackwardsCompatibleDataBroker dataBroker = new ForwardedBackwardsCompatibleDataBroker(domDataBroker,
                 mappingService, schemaService,listeningExecutor);
 
-        dataBroker.setConnector(BindingDomConnectorDeployer.createConnector(getBindingMappingServiceDependency()));
+        dataBroker.setConnector(BindingDomConnectorDeployer.createConnector(mappingService.getLegacy()));
         dataBroker.setDomProviderContext(session);
         return dataBroker;
     }
index b0c2d742e214046be839cca263dbc0652005aa9b..a15b1d746c5f5709374387f996056f6f979e2025 100644 (file)
@@ -7,12 +7,18 @@
  */
 package org.opendaylight.controller.config.yang.md.sal.binding.impl;
 
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
 import java.util.Hashtable;
 import java.util.Map.Entry;
 import java.util.Set;
-
+import javassist.ClassPool;
+import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
 import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder;
+import org.opendaylight.yangtools.binding.data.codec.gen.impl.StreamWriterGenerator;
+import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry;
 import org.opendaylight.yangtools.concepts.Delegator;
+import org.opendaylight.yangtools.sal.binding.generator.impl.GeneratedClassLoadingStrategy;
 import org.opendaylight.yangtools.sal.binding.generator.impl.RuntimeGeneratedMappingServiceImpl;
 import org.opendaylight.yangtools.yang.binding.DataContainer;
 import org.opendaylight.yangtools.yang.binding.DataObject;
@@ -29,9 +35,6 @@ import org.osgi.framework.ServiceReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-
 /**
 *
 */
@@ -42,14 +45,14 @@ public final class RuntimeMappingModule extends
 
     private BundleContext bundleContext;
 
-    public RuntimeMappingModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
-            org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+    public RuntimeMappingModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+            final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
         super(identifier, dependencyResolver);
     }
 
-    public RuntimeMappingModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
-            org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,
-            RuntimeMappingModule oldModule, java.lang.AutoCloseable oldInstance) {
+    public RuntimeMappingModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+            final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,
+            final RuntimeMappingModule oldModule, final java.lang.AutoCloseable oldInstance) {
         super(identifier, dependencyResolver, oldModule, oldInstance);
     }
 
@@ -61,41 +64,48 @@ public final class RuntimeMappingModule extends
     }
 
     @Override
-    public boolean canReuseInstance(AbstractRuntimeMappingModule oldModule) {
+    public boolean canReuseInstance(final AbstractRuntimeMappingModule oldModule) {
         return true;
     }
 
     @Override
     public java.lang.AutoCloseable createInstance() {
+        final GeneratedClassLoadingStrategy classLoading = getGlobalClassLoadingStrategy();
+        final BindingIndependentMappingService legacyMapping = getGlobalLegacyMappingService(classLoading);
+        BindingNormalizedNodeCodecRegistry codecRegistry = new BindingNormalizedNodeCodecRegistry(new StreamWriterGenerator(SingletonHolder.JAVASSIST));
+        BindingToNormalizedNodeCodec instance = new BindingToNormalizedNodeCodec(classLoading, legacyMapping, codecRegistry);
+        bundleContext.registerService(SchemaContextListener.class, instance, new Hashtable<String,String>());
+        return instance;
+    }
 
-        RuntimeGeneratedMappingServiceProxy potential = tryToReuseGlobalInstance();
-        if(potential != null) {
-            return potential;
+    private BindingIndependentMappingService getGlobalLegacyMappingService(final GeneratedClassLoadingStrategy classLoading) {
+        BindingIndependentMappingService potential = tryToReuseGlobalMappingServiceInstance();
+        if(potential == null) {
+            potential =  new RuntimeGeneratedMappingServiceImpl(ClassPool.getDefault(),classLoading);
+            bundleContext.registerService(SchemaContextListener.class, (SchemaContextListener) potential, new Hashtable<String,String>());
         }
+        return potential;
+    }
 
-        final RuntimeGeneratedMappingServiceImpl service = new RuntimeGeneratedMappingServiceImpl(SingletonHolder.CLASS_POOL);
-        bundleContext.registerService(SchemaContextListener.class, service, new Hashtable<String,String>());
-        return service;
+    private GeneratedClassLoadingStrategy getGlobalClassLoadingStrategy() {
+        ServiceReference<GeneratedClassLoadingStrategy> ref = bundleContext.getServiceReference(GeneratedClassLoadingStrategy.class);
+        return bundleContext.getService(ref);
     }
 
-    private RuntimeGeneratedMappingServiceProxy tryToReuseGlobalInstance() {
+    private BindingIndependentMappingService tryToReuseGlobalMappingServiceInstance() {
         ServiceReference<BindingIndependentMappingService> serviceRef = getBundleContext().getServiceReference(BindingIndependentMappingService.class);
         if(serviceRef == null) {
             return null;
         }
+        return bundleContext.getService(serviceRef);
 
-        BindingIndependentMappingService delegate = bundleContext.getService(serviceRef);
-        if (delegate == null) {
-            return null;
-        }
-        return new RuntimeGeneratedMappingServiceProxy(getBundleContext(),serviceRef,delegate);
     }
 
     private BundleContext getBundleContext() {
         return bundleContext;
     }
 
-    public void setBundleContext(BundleContext bundleContext) {
+    public void setBundleContext(final BundleContext bundleContext) {
         this.bundleContext = bundleContext;
     }
 
@@ -108,9 +118,9 @@ public final class RuntimeMappingModule extends
         private ServiceReference<BindingIndependentMappingService> reference;
         private BundleContext bundleContext;
 
-        public RuntimeGeneratedMappingServiceProxy(BundleContext bundleContext,
-                ServiceReference<BindingIndependentMappingService> serviceRef,
-                BindingIndependentMappingService delegate) {
+        public RuntimeGeneratedMappingServiceProxy(final BundleContext bundleContext,
+                final ServiceReference<BindingIndependentMappingService> serviceRef,
+                final BindingIndependentMappingService delegate) {
             this.bundleContext = Preconditions.checkNotNull(bundleContext);
             this.reference = Preconditions.checkNotNull(serviceRef);
             this.delegate = Preconditions.checkNotNull(delegate);
@@ -122,47 +132,47 @@ public final class RuntimeMappingModule extends
         }
 
         @Override
-        public CompositeNode toDataDom(DataObject data) {
+        public CompositeNode toDataDom(final DataObject data) {
             return delegate.toDataDom(data);
         }
 
         @Override
         public Entry<YangInstanceIdentifier, CompositeNode> toDataDom(
-                Entry<org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>, DataObject> entry) {
+                final Entry<org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>, DataObject> entry) {
             return delegate.toDataDom(entry);
         }
 
         @Override
         public YangInstanceIdentifier toDataDom(
-                org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject> path) {
+                final org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject> path) {
             return delegate.toDataDom(path);
         }
 
         @Override
         public DataObject dataObjectFromDataDom(
-                org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject> path,
-                CompositeNode result) throws DeserializationException {
+                final org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject> path,
+                final CompositeNode result) throws DeserializationException {
             return delegate.dataObjectFromDataDom(path, result);
         }
 
         @Override
-        public org.opendaylight.yangtools.yang.binding.InstanceIdentifier<?> fromDataDom(YangInstanceIdentifier entry)
+        public org.opendaylight.yangtools.yang.binding.InstanceIdentifier<?> fromDataDom(final YangInstanceIdentifier entry)
                 throws DeserializationException {
             return delegate.fromDataDom(entry);
         }
 
         @Override
-        public Set<QName> getRpcQNamesFor(Class<? extends RpcService> service) {
+        public Set<QName> getRpcQNamesFor(final Class<? extends RpcService> service) {
             return delegate.getRpcQNamesFor(service);
         }
 
         @Override
-        public Optional<Class<? extends RpcService>> getRpcServiceClassFor(String namespace, String revision) {
+        public Optional<Class<? extends RpcService>> getRpcServiceClassFor(final String namespace, final String revision) {
             return delegate.getRpcServiceClassFor(namespace,revision);
         }
 
         @Override
-        public DataContainer dataObjectFromDataDom(Class<? extends DataContainer> inputClass, CompositeNode domInput) {
+        public DataContainer dataObjectFromDataDom(final Class<? extends DataContainer> inputClass, final CompositeNode domInput) {
             return delegate.dataObjectFromDataDom(inputClass, domInput);
         }
 
index e632e6336aaf959808a28f9ecc209432c504b4eb..f843b23f9b2cc9d15a55c2d9a4373cde3baffecc 100644 (file)
@@ -9,7 +9,6 @@ package org.opendaylight.controller.md.sal.binding.impl;
 
 import com.google.common.base.Objects;
 import com.google.common.base.Optional;
-
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
@@ -19,7 +18,6 @@ import java.util.Iterator;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
-
 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
@@ -37,33 +35,28 @@ import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
 import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public abstract class AbstractForwardedDataBroker implements Delegator<DOMDataBroker>, DomForwardedBroker, SchemaContextListener, AutoCloseable {
+public abstract class AbstractForwardedDataBroker implements Delegator<DOMDataBroker>, DomForwardedBroker,
+        SchemaContextListener, AutoCloseable {
 
     private static final Logger LOG = LoggerFactory.getLogger(AbstractForwardedDataBroker.class);
     // The Broker to whom we do all forwarding
     private final DOMDataBroker domDataBroker;
 
-    // Mapper to convert from Binding Independent objects to Binding Aware
-    // objects
-    private final BindingIndependentMappingService mappingService;
-
     private final BindingToNormalizedNodeCodec codec;
     private BindingIndependentConnector connector;
     private ProviderSession context;
     private final ListenerRegistration<SchemaContextListener> schemaListenerRegistration;
 
-    protected AbstractForwardedDataBroker(final DOMDataBroker domDataBroker,
-            final BindingIndependentMappingService mappingService,final SchemaService schemaService) {
+    protected AbstractForwardedDataBroker(final DOMDataBroker domDataBroker, final BindingToNormalizedNodeCodec codec,
+            final SchemaService schemaService) {
         this.domDataBroker = domDataBroker;
-        this.mappingService = mappingService;
-        this.codec = new BindingToNormalizedNodeCodec(mappingService);
+        this.codec = codec;
         this.schemaListenerRegistration = schemaService.registerSchemaContextListener(this);
     }
 
@@ -71,10 +64,6 @@ public abstract class AbstractForwardedDataBroker implements Delegator<DOMDataBr
         return codec;
     }
 
-    protected BindingIndependentMappingService getMappingService() {
-        return mappingService;
-    }
-
     @Override
     public DOMDataBroker getDelegate() {
         return domDataBroker;
@@ -82,12 +71,11 @@ public abstract class AbstractForwardedDataBroker implements Delegator<DOMDataBr
 
     @Override
     public void onGlobalContextUpdated(final SchemaContext ctx) {
-        codec.onGlobalContextUpdated(ctx);
+        // NOOP
     }
 
     public ListenerRegistration<DataChangeListener> registerDataChangeListener(final LogicalDatastoreType store,
-            final InstanceIdentifier<?> path, final DataChangeListener listener,
-            final DataChangeScope triggeringScope) {
+            final InstanceIdentifier<?> path, final DataChangeListener listener, final DataChangeScope triggeringScope) {
         DOMDataChangeListener domDataChangeListener = new TranslatingDataChangeInvoker(store, path, listener,
                 triggeringScope);
         YangInstanceIdentifier domPath = codec.toNormalized(path);
@@ -96,23 +84,16 @@ public abstract class AbstractForwardedDataBroker implements Delegator<DOMDataBr
         return new ListenerRegistrationImpl(listener, domRegistration);
     }
 
-    protected Map<InstanceIdentifier<?>, DataObject> toBinding(
-            InstanceIdentifier<?> path,
+    protected Map<InstanceIdentifier<?>, DataObject> toBinding(final InstanceIdentifier<?> path,
             final Map<YangInstanceIdentifier, ? extends NormalizedNode<?, ?>> normalized) {
         Map<InstanceIdentifier<?>, DataObject> newMap = new HashMap<>();
 
         for (Map.Entry<YangInstanceIdentifier, ? extends NormalizedNode<?, ?>> entry : sortedEntries(normalized)) {
             try {
-                Optional<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> potential = getCodec().toBinding(
-                        entry);
+                Optional<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> potential = getCodec().toBinding(entry);
                 if (potential.isPresent()) {
                     Entry<InstanceIdentifier<? extends DataObject>, DataObject> binding = potential.get();
                     newMap.put(binding.getKey(), binding.getValue());
-                } else if (entry.getKey().getLastPathArgument() instanceof YangInstanceIdentifier.AugmentationIdentifier) {
-                    DataObject bindingDataObject = getCodec().toBinding(path, entry.getValue());
-                    if (bindingDataObject != null) {
-                        newMap.put(path, bindingDataObject);
-                    }
                 }
             } catch (DeserializationException e) {
                 LOG.warn("Failed to transform {}, omitting it", entry, e);
@@ -123,8 +104,7 @@ public abstract class AbstractForwardedDataBroker implements Delegator<DOMDataBr
 
     private static final Comparator<Entry<YangInstanceIdentifier, ?>> MAP_ENTRY_COMPARATOR = new Comparator<Entry<YangInstanceIdentifier, ?>>() {
         @Override
-        public int compare(final Entry<YangInstanceIdentifier, ?> left,
-                final Entry<YangInstanceIdentifier, ?> right) {
+        public int compare(final Entry<YangInstanceIdentifier, ?> left, final Entry<YangInstanceIdentifier, ?> right) {
             final Iterator<?> li = left.getKey().getPathArguments().iterator();
             final Iterator<?> ri = right.getKey().getPathArguments().iterator();
 
@@ -144,7 +124,7 @@ public abstract class AbstractForwardedDataBroker implements Delegator<DOMDataBr
         }
     };
 
-    private static <T> Iterable<Entry<YangInstanceIdentifier,T>> sortedEntries(final Map<YangInstanceIdentifier, T> map) {
+    private static <T> Iterable<Entry<YangInstanceIdentifier, T>> sortedEntries(final Map<YangInstanceIdentifier, T> map) {
         if (!map.isEmpty()) {
             ArrayList<Entry<YangInstanceIdentifier, T>> entries = new ArrayList<>(map.entrySet());
             Collections.sort(entries, MAP_ENTRY_COMPARATOR);
@@ -154,7 +134,7 @@ public abstract class AbstractForwardedDataBroker implements Delegator<DOMDataBr
         }
     }
 
-    protected Set<InstanceIdentifier<?>> toBinding(InstanceIdentifier<?> path,
+    protected Set<InstanceIdentifier<?>> toBinding(final InstanceIdentifier<?> path,
             final Set<YangInstanceIdentifier> normalized) {
         Set<InstanceIdentifier<?>> hashSet = new HashSet<>();
         for (YangInstanceIdentifier normalizedPath : normalized) {
@@ -177,12 +157,7 @@ public abstract class AbstractForwardedDataBroker implements Delegator<DOMDataBr
         if (path.isWildcarded()) {
             return Optional.absent();
         }
-
-        try {
-            return Optional.fromNullable(getCodec().toBinding(path, data));
-        } catch (DeserializationException e) {
-            return Optional.absent();
-        }
+        return (Optional) getCodec().deserializeFunction(path).apply(Optional.<NormalizedNode<?, ?>> of(data));
     }
 
     private class TranslatingDataChangeInvoker implements DOMDataChangeListener {
@@ -200,8 +175,7 @@ public abstract class AbstractForwardedDataBroker implements Delegator<DOMDataBr
         }
 
         @Override
-        public void onDataChanged(
-                final AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change) {
+        public void onDataChanged(final AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change) {
             bindingDataChangeListener.onDataChanged(new TranslatedDataChangeEvent(change, path));
         }
     }
@@ -261,7 +235,7 @@ public abstract class AbstractForwardedDataBroker implements Delegator<DOMDataBr
         @Override
         public DataObject getOriginalSubtree() {
             if (originalDataCache == null) {
-                if(domEvent.getOriginalSubtree() != null) {
+                if (domEvent.getOriginalSubtree() != null) {
                     originalDataCache = toBindingData(path, domEvent.getOriginalSubtree());
                 } else {
                     originalDataCache = Optional.absent();
@@ -273,7 +247,7 @@ public abstract class AbstractForwardedDataBroker implements Delegator<DOMDataBr
         @Override
         public DataObject getUpdatedSubtree() {
             if (updatedDataCache == null) {
-                if(domEvent.getUpdatedSubtree() != null) {
+                if (domEvent.getUpdatedSubtree() != null) {
                     updatedDataCache = toBindingData(path, domEvent.getUpdatedSubtree());
                 } else {
                     updatedDataCache = Optional.absent();
index 66caaea7083af18f1ffaedc3113f4e35d167b4ff..1e2d2b17f0b1846ab9272f6683f2a0f00cd1c070 100644 (file)
  */
 package org.opendaylight.controller.md.sal.binding.impl;
 
-import java.lang.reflect.Method;
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
 import java.util.AbstractMap.SimpleEntry;
-import java.util.Collection;
-import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Map.Entry;
-import java.util.Set;
-
-import javax.annotation.Nullable;
-
 import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationException;
 import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationOperation;
 import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizer;
-import org.opendaylight.yangtools.yang.binding.Augmentation;
-import org.opendaylight.yangtools.yang.binding.BindingMapping;
+import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry;
+import org.opendaylight.yangtools.sal.binding.generator.impl.GeneratedClassLoadingStrategy;
+import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
-import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.QNameModule;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
 import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
-import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-
-public class BindingToNormalizedNodeCodec implements SchemaContextListener {
+public class BindingToNormalizedNodeCodec implements SchemaContextListener,AutoCloseable {
 
     private static final Logger LOG = LoggerFactory.getLogger(BindingToNormalizedNodeCodec.class);
 
     private final BindingIndependentMappingService bindingToLegacy;
+    private final BindingNormalizedNodeCodecRegistry codecRegistry;
     private DataNormalizer legacyToNormalized;
+    private final GeneratedClassLoadingStrategy classLoadingStrategy;
 
-    public BindingToNormalizedNodeCodec(final BindingIndependentMappingService mappingService) {
+    public BindingToNormalizedNodeCodec(final GeneratedClassLoadingStrategy classLoadingStrategy, final BindingIndependentMappingService mappingService, final BindingNormalizedNodeCodecRegistry codecRegistry) {
         super();
         this.bindingToLegacy = mappingService;
+        this.classLoadingStrategy = classLoadingStrategy;
+        this.codecRegistry = codecRegistry;
+
     }
 
     public org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier toNormalized(
             final InstanceIdentifier<? extends DataObject> binding) {
-
-        // Used instance-identifier codec do not support serialization of last
-        // path
-        // argument if it is Augmentation (behaviour expected by old datastore)
-        // in this case, we explicitly check if last argument is augmentation
-        // to process it separately
-        if (isAugmentationIdentifier(binding)) {
-            return toNormalizedAugmented(binding);
-        }
-        return toNormalizedImpl(binding);
+        return codecRegistry.toYangInstanceIdentifier(binding);
     }
 
+    @SuppressWarnings({ "unchecked", "rawtypes" })
     public Entry<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, NormalizedNode<?, ?>> toNormalizedNode(
             final InstanceIdentifier<? extends DataObject> bindingPath, final DataObject bindingObject) {
-        return toNormalizedNode(toBindingEntry(bindingPath, bindingObject));
+        return codecRegistry.toNormalizedNode((InstanceIdentifier) bindingPath, bindingObject);
 
     }
 
     public Entry<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, NormalizedNode<?, ?>> toNormalizedNode(
             final Entry<org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>, DataObject> binding) {
-        Entry<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, CompositeNode> legacyEntry = bindingToLegacy
-                .toDataDom(binding);
-        Entry<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, NormalizedNode<?, ?>> normalizedEntry = legacyToNormalized
-                .toNormalized(legacyEntry);
-        LOG.trace("Serialization of {}, Legacy Representation: {}, Normalized Representation: {}", binding,
-                legacyEntry, normalizedEntry);
-        if (isAugmentation(binding.getKey().getTargetType())) {
-
-            for (DataContainerChild<? extends PathArgument, ?> child : ((DataContainerNode<?>) normalizedEntry
-                    .getValue()).getValue()) {
-                if (child instanceof AugmentationNode) {
-                    ImmutableList<PathArgument> childArgs = ImmutableList.<PathArgument> builder()
-                            .addAll(normalizedEntry.getKey().getPathArguments()).add(child.getIdentifier()).build();
-                    org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier childPath = org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier
-                            .create(childArgs);
-                    return toDOMEntry(childPath, child);
-                }
-            }
-
-        }
-        return normalizedEntry;
-
+        return toNormalizedNode(binding.getKey(),binding.getValue());
     }
 
     /**
@@ -125,109 +75,13 @@ public class BindingToNormalizedNodeCodec implements SchemaContextListener {
     public Optional<InstanceIdentifier<? extends DataObject>> toBinding(
             final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier normalized)
                     throws DeserializationException {
-
-        PathArgument lastArgument = Iterables.getLast(normalized.getPathArguments());
-        // Used instance-identifier codec do not support serialization of last
-        // path
-        // argument if it is AugmentationIdentifier (behaviour expected by old
-        // datastore)
-        // in this case, we explicitly check if last argument is augmentation
-        // to process it separately
-        if (lastArgument instanceof AugmentationIdentifier) {
-            return toBindingAugmented(normalized);
-        }
-        return toBindingImpl(normalized);
-    }
-
-    private Optional<InstanceIdentifier<? extends DataObject>> toBindingAugmented(
-            final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier normalized)
-                    throws DeserializationException {
-        Optional<InstanceIdentifier<? extends DataObject>> potential = toBindingImpl(normalized);
-        // Shorthand check, if codec already supports deserialization
-        // of AugmentationIdentifier we will return
-        if (potential.isPresent() && isAugmentationIdentifier(potential.get())) {
-            return potential;
-        }
-
-        int normalizedCount = getAugmentationCount(normalized);
-        AugmentationIdentifier lastArgument = (AugmentationIdentifier) Iterables.getLast(normalized.getPathArguments());
-
-        // Here we employ small trick - Binding-aware Codec injects an pointer
-        // to augmentation class
-        // if child is referenced - so we will reference child and then shorten
-        // path.
-        LOG.trace("Looking for candidates to match {}", normalized);
-        for (QName child : lastArgument.getPossibleChildNames()) {
-            org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier childPath = normalized.node(child);
-            try {
-                if (isNotRepresentable(childPath)) {
-                    LOG.trace("Path {} is not BI-representable, skipping it", childPath);
-                    continue;
-                }
-            } catch (DataNormalizationException e) {
-                LOG.warn("Failed to denormalize path {}, skipping it", childPath, e);
-                continue;
-            }
-
-            Optional<InstanceIdentifier<? extends DataObject>> baId = toBindingImpl(childPath);
-            if (!baId.isPresent()) {
-                LOG.debug("No binding-aware identifier found for path {}, skipping it", childPath);
-                continue;
-            }
-
-            InstanceIdentifier<? extends DataObject> potentialPath = shortenToLastAugment(baId.get());
-            int potentialAugmentCount = getAugmentationCount(potentialPath);
-            if (potentialAugmentCount == normalizedCount) {
-                LOG.trace("Found matching path {}", potentialPath);
-                return Optional.<InstanceIdentifier<? extends DataObject>> of(potentialPath);
-            }
-
-            LOG.trace("Skipping mis-matched potential path {}", potentialPath);
-        }
-
-        LOG.trace("Failed to find augmentation matching {}", normalized);
-        return Optional.absent();
-    }
-
-    private Optional<InstanceIdentifier<? extends DataObject>> toBindingImpl(
-            final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier normalized)
-                    throws DeserializationException {
-        org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier legacyPath;
-
         try {
-            if (isNotRepresentable(normalized)) {
-                return Optional.absent();
-            }
-            legacyPath = legacyToNormalized.toLegacy(normalized);
-        } catch (DataNormalizationException e) {
-            throw new IllegalStateException("Could not denormalize path.", e);
-        }
-        LOG.trace("InstanceIdentifier Path Deserialization: Legacy representation {}, Normalized representation: {}",
-                legacyPath, normalized);
-        return Optional.<InstanceIdentifier<? extends DataObject>> of(bindingToLegacy.fromDataDom(legacyPath));
-    }
-
-    private boolean isNotRepresentable(final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier normalized)
-            throws DataNormalizationException {
-        DataNormalizationOperation<?> op = findNormalizationOperation(normalized);
-        if (op.isMixin() && op.getIdentifier() instanceof NodeIdentifier) {
-            return true;
-        }
-        if (op.isLeaf()) {
-            return true;
+            return  Optional.<InstanceIdentifier<? extends DataObject>>of(codecRegistry.fromYangInstanceIdentifier(normalized));
+        } catch (IllegalArgumentException e) {
+            return Optional.absent();
         }
-        return false;
     }
 
-    private DataNormalizationOperation<?> findNormalizationOperation(
-            final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier normalized)
-                    throws DataNormalizationException {
-        DataNormalizationOperation<?> current = legacyToNormalized.getRootOperation();
-        for (PathArgument arg : normalized.getPathArguments()) {
-            current = current.getChild(arg);
-        }
-        return current;
-    }
 
     private static final Entry<org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>, DataObject> toBindingEntry(
             final org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject> key,
@@ -236,45 +90,19 @@ public class BindingToNormalizedNodeCodec implements SchemaContextListener {
                 key, value);
     }
 
-    private static final Entry<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, NormalizedNode<?, ?>> toDOMEntry(
-            final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier key, final NormalizedNode<?, ?> value) {
-        return new SimpleEntry<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, NormalizedNode<?, ?>>(key,
-                value);
-    }
-
-    public DataObject toBinding(final InstanceIdentifier<?> path, final NormalizedNode<?, ?> normalizedNode)
-            throws DeserializationException {
-        CompositeNode legacy = null;
-        if (isAugmentationIdentifier(path) && normalizedNode instanceof AugmentationNode) {
-            QName augIdentifier = BindingReflections.findQName(path.getTargetType());
-            ContainerNode virtualNode = Builders.containerBuilder() //
-                    .withNodeIdentifier(new NodeIdentifier(augIdentifier)) //
-                    .withChild((DataContainerChild<?, ?>) normalizedNode) //
-                    .build();
-            legacy = (CompositeNode) DataNormalizer.toLegacy(virtualNode);
-        } else {
-            legacy = (CompositeNode) DataNormalizer.toLegacy(normalizedNode);
-        }
-
-        return bindingToLegacy.dataObjectFromDataDom(path, legacy);
-    }
-
     public DataNormalizer getDataNormalizer() {
         return legacyToNormalized;
     }
 
+    @SuppressWarnings("unchecked")
     public Optional<Entry<org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>, DataObject>> toBinding(
             final Entry<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, ? extends NormalizedNode<?, ?>> normalized)
                     throws DeserializationException {
-        Optional<InstanceIdentifier<? extends DataObject>> potentialPath = toBinding(normalized.getKey());
-        if (potentialPath.isPresent()) {
-            InstanceIdentifier<? extends DataObject> bindingPath = potentialPath.get();
-            DataObject bindingData = toBinding(bindingPath, normalized.getValue());
-            if (bindingData == null) {
-                LOG.warn("Failed to deserialize {} to Binding format. Binding path is: {}", normalized, bindingPath);
-            }
-            return Optional.of(toBindingEntry(bindingPath, bindingData));
-        } else {
+        try {
+            @SuppressWarnings("rawtypes")
+            Entry binding = codecRegistry.fromNormalizedNode(normalized.getKey(), normalized.getValue());
+            return Optional.<Entry<org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>, DataObject>>fromNullable(binding);
+        } catch (IllegalArgumentException e) {
             return Optional.absent();
         }
     }
@@ -282,269 +110,11 @@ public class BindingToNormalizedNodeCodec implements SchemaContextListener {
     @Override
     public void onGlobalContextUpdated(final SchemaContext arg0) {
         legacyToNormalized = new DataNormalizer(arg0);
+        codecRegistry.onBindingRuntimeContextUpdated(BindingRuntimeContext.create(classLoadingStrategy, arg0));
     }
 
-    private org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier toNormalizedAugmented(
-            final InstanceIdentifier<?> augPath) {
-        org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier processed = toNormalizedImpl(augPath);
-        // If used instance identifier codec added supports for deserialization
-        // of last AugmentationIdentifier we will just reuse it
-        if (isAugmentationIdentifier(processed)) {
-            return processed;
-        }
-        Optional<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier> additionalSerialized;
-        additionalSerialized = toNormalizedAugmentedUsingChildContainers(augPath, processed);
-
-        if (additionalSerialized.isPresent()) {
-            return additionalSerialized.get();
-        }
-        additionalSerialized = toNormalizedAugmentedUsingChildLeafs(augPath, processed);
-        if (additionalSerialized.isPresent()) {
-            return additionalSerialized.get();
-        }
-        throw new IllegalStateException("Unabled to construct augmentation identfier for " + augPath);
-    }
-
-    /**
-     * Tries to find correct augmentation identifier using children leafs
-     *
-     * This method uses normalized Instance Identifier of parent node to fetch
-     * schema and {@link BindingReflections#getModuleInfo(Class)} to learn about
-     * augmentation namespace, specificly, in which module it was defined.
-     *
-     * Then it uses it to filter all available augmentations for parent by
-     * module. After that it walks augmentations in particular module and
-     * pick-up first which at least one leaf name matches supplied augmentation.
-     * We could do this safely since YANG explicitly states that no any existing
-     * augmentations must differ in leaf fully qualified names.
-     *
-     *
-     * @param augPath
-     *            Binding Aware Path which ends with augment
-     * @param parentPath
-     *            Processed path
-     * @return
-     */
-    private Optional<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier> toNormalizedAugmentedUsingChildLeafs(
-            final InstanceIdentifier<?> augPath,
-            final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier parentPath) {
-        try {
-            DataNormalizationOperation<?> parentOp = legacyToNormalized.getOperation(parentPath);
-            if(!parentOp.getDataSchemaNode().isPresent()) {
-                return Optional.absent();
-            }
-            DataSchemaNode parentSchema = parentOp.getDataSchemaNode().get();
-            if (parentSchema instanceof AugmentationTarget) {
-                Set<AugmentationSchema> augmentations = ((AugmentationTarget) parentSchema).getAvailableAugmentations();
-                LOG.info("Augmentations for {}, {}", augPath, augmentations);
-                Optional<AugmentationSchema> schema = findAugmentation(augPath.getTargetType(), augmentations);
-                if (schema.isPresent()) {
-                    AugmentationIdentifier augmentationIdentifier = DataNormalizationOperation
-                            .augmentationIdentifierFrom(schema.get());
-                    return Optional.of(parentPath.node(augmentationIdentifier));
-                }
-            }
-        } catch (DataNormalizationException e) {
-            throw new IllegalArgumentException(e);
-        }
-        return Optional.absent();
-    }
-
-    /**
-     * Creates instance identifier for augmentation child, tries to serialize it
-     * Instance Identifier is then shortened to last augmentation.
-     *
-     * This is for situations, where underlying codec is implementing hydrogen
-     * style DOM APIs (which did not supported {@link AugmentationIdentifier}.)
-     *
-     * @param augPath
-     * @param parentPath
-     *            Path to parent node
-     * @return
-     */
-    @SuppressWarnings("rawtypes")
-    private Optional<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier> toNormalizedAugmentedUsingChildContainers(
-            final InstanceIdentifier<?> augPath,
-            final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier parentPath) {
-        for (Class augChild : BindingReflections.getChildrenClasses(augPath.getTargetType())) {
-            @SuppressWarnings("unchecked")
-            InstanceIdentifier<?> childPath = augPath.child(augChild);
-            org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier normalized = toNormalizedImpl(childPath);
-            org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier potentialDiscovered = shortenToLastAugmentation(
-                    normalized, parentPath);
-            if (potentialDiscovered != null) {
-                return Optional.of(potentialDiscovered);
-            }
-        }
-        return Optional.absent();
-    }
-
-    private Optional<AugmentationSchema> findAugmentation(final Class<?> targetType,
-            final Set<AugmentationSchema> augmentations) {
-        YangModuleInfo moduleInfo;
-        try {
-            moduleInfo = BindingReflections.getModuleInfo(targetType);
-        } catch (Exception e) {
-            throw new IllegalStateException(e);
-        }
-        Iterable<AugmentationSchema> filtered = filteredByModuleInfo(augmentations,
-                BindingReflections.getModuleQName(moduleInfo).getModule());
-        filtered.toString();
-        Set<String> targetTypeGetters = getYangModeledGetters(targetType);
-        for (AugmentationSchema schema : filtered) {
-            for (DataSchemaNode child : schema.getChildNodes()) {
-                String getterName = "get" + BindingMapping.getClassName(child.getQName());
-                if (targetTypeGetters.contains(getterName)) {
-                    return Optional.of(schema);
-                }
-            }
-        }
-        return Optional.absent();
-    }
-
-    private static Iterable<AugmentationSchema> filteredByModuleInfo(final Iterable<AugmentationSchema> augmentations,
-            final QNameModule module) {
-        return Iterables.filter(augmentations, new Predicate<AugmentationSchema>() {
-            @Override
-            public boolean apply(final AugmentationSchema schema) {
-                final Collection<DataSchemaNode> childNodes = schema.getChildNodes();
-                return !childNodes.isEmpty() && module.equals(Iterables.get(childNodes, 0).getQName().getModule());
-            }
-        });
-    }
-
-    public static final Set<String> getYangModeledGetters(final Class<?> targetType) {
-        HashSet<String> ret = new HashSet<String>();
-        for (Method method : targetType.getMethods()) {
-            if (isYangModeledGetter(method)) {
-                ret.add(method.getName());
-            }
-        }
-        return ret;
-    }
-
-    /**
-     *
-     * Returns true if supplied method represent getter for YANG modeled value
-     *
-     * @param method
-     *            Method to be tested
-     * @return true if method represent getter for YANG Modeled value.
-     */
-    private static final boolean isYangModeledGetter(final Method method) {
-        return !method.getName().equals("getClass") && !method.getName().equals("getImplementedInterface")
-                && method.getName().startsWith("get") && method.getParameterTypes().length == 0;
-    }
-
-    private org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier shortenToLastAugmentation(
-            final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier normalized,
-            final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier parentPath) {
-        int parentSize = Iterables.size(parentPath.getPathArguments());
-        int position = 0;
-        int foundPosition = -1;
-        for (PathArgument arg : normalized.getPathArguments()) {
-            position++;
-            if (arg instanceof AugmentationIdentifier) {
-                foundPosition = position;
-            }
-        }
-        if (foundPosition > 0 && foundPosition > parentSize) {
-            Iterable<PathArgument> shortened = Iterables.limit(normalized.getPathArguments(), foundPosition);
-            return org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.create(shortened);
-        }
-        return null;
-    }
-
-    private InstanceIdentifier<? extends DataObject> shortenToLastAugment(
-            final InstanceIdentifier<? extends DataObject> binding) {
-        int position = 0;
-        int foundPosition = -1;
-        for (org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument arg : binding.getPathArguments()) {
-            position++;
-            if (isAugmentation(arg.getType())) {
-                foundPosition = position;
-            }
-        }
-        return InstanceIdentifier.create(Iterables.limit(binding.getPathArguments(), foundPosition));
-    }
-
-    private org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier toNormalizedImpl(
-            final InstanceIdentifier<? extends DataObject> binding) {
-        final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier legacyPath = bindingToLegacy
-                .toDataDom(binding);
-        final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier normalized = legacyToNormalized
-                .toNormalized(legacyPath);
-        return normalized;
-    }
-
-    private static boolean isAugmentation(final Class<? extends DataObject> type) {
-        return Augmentation.class.isAssignableFrom(type);
-    }
-
-    private static boolean isAugmentationIdentifier(final InstanceIdentifier<?> potential) {
-        return Augmentation.class.isAssignableFrom(potential.getTargetType());
-    }
-
-    private boolean isAugmentationIdentifier(final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier processed) {
-        return Iterables.getLast(processed.getPathArguments()) instanceof AugmentationIdentifier;
-    }
-
-    private static int getAugmentationCount(final InstanceIdentifier<?> potential) {
-        int count = 0;
-        for (org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument arg : potential.getPathArguments()) {
-            if (isAugmentation(arg.getType())) {
-                count++;
-            }
-
-        }
-        return count;
-    }
-
-    private static int getAugmentationCount(final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier potential) {
-        int count = 0;
-        for (PathArgument arg : potential.getPathArguments()) {
-            if (arg instanceof AugmentationIdentifier) {
-                count++;
-            }
-        }
-        return count;
-    }
-
-    @SuppressWarnings({ "rawtypes", "unchecked" })
     public <T extends DataObject> Function<Optional<NormalizedNode<?, ?>>, Optional<T>>  deserializeFunction(final InstanceIdentifier<T> path) {
-        return new DeserializeFunction(this, path);
-    }
-
-    private static class DeserializeFunction<T extends DataObject> implements Function<Optional<NormalizedNode<?, ?>>, Optional<T>> {
-
-        private final BindingToNormalizedNodeCodec codec;
-        private final InstanceIdentifier<?> path;
-
-        public DeserializeFunction(final BindingToNormalizedNodeCodec codec, final InstanceIdentifier<?> path) {
-            super();
-            this.codec = Preconditions.checkNotNull(codec, "Codec must not be null");
-            this.path = Preconditions.checkNotNull(path, "Path must not be null");
-        }
-
-        @SuppressWarnings("rawtypes")
-        @Nullable
-        @Override
-        public Optional apply(@Nullable final Optional<NormalizedNode<?, ?>> normalizedNode) {
-            if (normalizedNode.isPresent()) {
-                final DataObject dataObject;
-                try {
-                    dataObject = codec.toBinding(path, normalizedNode.get());
-                } catch (DeserializationException e) {
-                    LOG.warn("Failed to create dataobject from node {}", normalizedNode.get(), e);
-                    throw new IllegalStateException("Failed to create dataobject", e);
-                }
-
-                if (dataObject != null) {
-                    return Optional.of(dataObject);
-                }
-            }
-            return Optional.absent();
-        }
+        return codecRegistry.deserializeFunction(path);
     }
 
     /**
@@ -566,4 +136,13 @@ public class BindingToNormalizedNodeCodec implements SchemaContextListener {
         }
         return currentOp.createDefault(path.getLastPathArgument());
     }
+
+    public BindingIndependentMappingService getLegacy() {
+        return bindingToLegacy;
+    }
+
+    @Override
+    public void close() throws Exception {
+        // NOOP Intentionally
+    }
 }
index 237d9678f95f3a743dfbe19a033ca02845b81375..52e114b0ea969436bd4ea2928babf0df7e5f9b96 100644 (file)
@@ -7,6 +7,12 @@
  */
 package org.opendaylight.controller.md.sal.binding.impl;
 
+import com.google.common.base.Function;
+import com.google.common.util.concurrent.AsyncFunction;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -17,7 +23,6 @@ import java.util.Set;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ExecutionException;
-
 import org.opendaylight.controller.md.sal.common.api.RegistrationListener;
 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
@@ -44,17 +49,9 @@ import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
-import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Function;
-import com.google.common.util.concurrent.AsyncFunction;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.ListeningExecutorService;
-
 @SuppressWarnings("deprecation")
 public class ForwardedBackwardsCompatibleDataBroker extends AbstractForwardedDataBroker implements DataProviderService, AutoCloseable {
 
@@ -64,7 +61,7 @@ public class ForwardedBackwardsCompatibleDataBroker extends AbstractForwardedDat
     private final ListeningExecutorService executorService;
 
     public ForwardedBackwardsCompatibleDataBroker(final DOMDataBroker domDataBroker,
-            final BindingIndependentMappingService mappingService, final SchemaService schemaService,final ListeningExecutorService executor) {
+            final BindingToNormalizedNodeCodec mappingService, final SchemaService schemaService,final ListeningExecutorService executor) {
         super(domDataBroker, mappingService,schemaService);
         executorService = executor;
         LOG.info("ForwardedBackwardsCompatibleBroker started.");
index 6359b60684ef45e18d2185d1231b14b165497724..ef66d80ed445b1e323dc5c2ad770236e42eb64a8 100644 (file)
@@ -16,7 +16,6 @@ import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
 import org.opendaylight.controller.sal.core.api.model.SchemaService;
-import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
 
 /**
  * The DataBrokerImpl simply defers to the DOMDataBroker for all its operations.
@@ -30,8 +29,8 @@ import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMapping
  */
 public class ForwardedBindingDataBroker extends AbstractForwardedDataBroker implements DataBroker {
 
-    public ForwardedBindingDataBroker(final DOMDataBroker domDataBroker, final BindingIndependentMappingService mappingService, final SchemaService schemaService) {
-        super(domDataBroker, mappingService,schemaService);
+    public ForwardedBindingDataBroker(final DOMDataBroker domDataBroker, final BindingToNormalizedNodeCodec codec, final SchemaService schemaService) {
+        super(domDataBroker, codec,schemaService);
     }
 
     @Override
index 1ec4aa2d30bc9da7307891a41050bfc33e55642a..f037e679be72fbb037318708c98217325782dd66 100644 (file)
@@ -7,6 +7,10 @@
  */
 package org.opendaylight.controller.sal.binding.codegen.impl;
 
+import com.google.common.util.concurrent.ForwardingBlockingQueue;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -16,24 +20,19 @@ import java.util.concurrent.RejectedExecutionHandler;
 import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
-
 import javassist.ClassPool;
-
 import org.apache.commons.lang3.StringUtils;
 import org.opendaylight.controller.sal.binding.codegen.RuntimeCodeGenerator;
 import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory;
+import org.opendaylight.yangtools.sal.binding.generator.util.JavassistUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.util.concurrent.ForwardingBlockingQueue;
-import com.google.common.util.concurrent.ListeningExecutorService;
-import com.google.common.util.concurrent.MoreExecutors;
-import com.google.common.util.concurrent.ThreadFactoryBuilder;
-
 public class SingletonHolder {
     private static final Logger logger = LoggerFactory.getLogger(SingletonHolder.class);
 
     public static final ClassPool CLASS_POOL = ClassPool.getDefault();
+    public static final JavassistUtils JAVASSIST = JavassistUtils.forClassPool(CLASS_POOL);
     public static final org.opendaylight.controller.sal.binding.codegen.impl.RuntimeCodeGenerator RPC_GENERATOR_IMPL = new org.opendaylight.controller.sal.binding.codegen.impl.RuntimeCodeGenerator(
             CLASS_POOL);
     public static final RuntimeCodeGenerator RPC_GENERATOR = RPC_GENERATOR_IMPL;
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RootDataBrokerImpl.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RootDataBrokerImpl.java
deleted file mode 100644 (file)
index a1cae26..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.binding.impl;\r
-\r
-import org.opendaylight.controller.config.yang.md.sal.binding.impl.Data;\r
-import org.opendaylight.controller.config.yang.md.sal.binding.impl.DataBrokerImplRuntimeMXBean;\r
-import org.opendaylight.controller.config.yang.md.sal.binding.impl.DataBrokerImplRuntimeRegistration;\r
-import org.opendaylight.controller.config.yang.md.sal.binding.impl.DataBrokerImplRuntimeRegistrator;\r
-import org.opendaylight.controller.config.yang.md.sal.binding.impl.Transactions;\r
-import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentConnector;\r
-\r
-public class RootDataBrokerImpl extends DataBrokerImpl implements DataBrokerImplRuntimeMXBean {\r
-\r
-    private final Transactions transactions = new Transactions();\r
-    private final Data data = new Data();\r
-    private BindingIndependentConnector bindingIndependentConnector;\r
-    private DataBrokerImplRuntimeRegistration runtimeBeanRegistration;\r
-\r
-    public BindingIndependentConnector getBindingIndependentConnector() {\r
-        return bindingIndependentConnector;\r
-    }\r
-\r
-    public Transactions getTransactions() {\r
-        transactions.setCreated(getCreatedTransactionsCount().get());\r
-        transactions.setSubmitted(getSubmittedTransactionsCount().get());\r
-        transactions.setSuccessful(getFinishedTransactionsCount().get());\r
-        transactions.setFailed(getFailedTransactionsCount().get());\r
-        return transactions;\r
-    }\r
-\r
-    @Override\r
-    public Data getData() {\r
-        data.setTransactions(getTransactions());\r
-        return data;\r
-    }\r
-\r
-    public void setBindingIndependentConnector(BindingIndependentConnector runtimeMapping) {\r
-        this.bindingIndependentConnector = runtimeMapping;\r
-    }\r
-\r
-    public void registerRuntimeBean(DataBrokerImplRuntimeRegistrator rootRegistrator) {\r
-        runtimeBeanRegistration = rootRegistrator.register(this);\r
-    }\r
-\r
-}\r
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedDataBrokerImpl.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/forward/DomForwardedDataBrokerImpl.java
deleted file mode 100644 (file)
index 3d0e4de..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.binding.impl.forward;
-
-import java.util.Collection;
-import java.util.Collections;
-
-import org.opendaylight.controller.sal.binding.impl.RootDataBrokerImpl;
-import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingDomConnectorDeployer;
-import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentConnector;
-import org.opendaylight.controller.sal.core.api.Provider;
-import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
-
-public class DomForwardedDataBrokerImpl extends RootDataBrokerImpl implements Provider, DomForwardedBroker {
-
-    private BindingIndependentConnector connector;
-    private ProviderSession domProviderContext;
-
-    public void setConnector(BindingIndependentConnector connector) {
-        this.connector = connector;
-    }
-
-    @Override
-    public void onSessionInitiated(ProviderSession session) {
-        this.setDomProviderContext(session);
-    }
-
-    @Override
-    public Collection<ProviderFunctionality> getProviderFunctionality() {
-        return Collections.emptySet();
-    }
-
-    @Override
-    public BindingIndependentConnector getConnector() {
-        return connector;
-    }
-
-    @Override
-    public ProviderSession getDomProviderContext() {
-        return domProviderContext;
-    }
-
-    public void setDomProviderContext(ProviderSession domProviderContext) {
-        this.domProviderContext = domProviderContext;
-    }
-
-    @Override
-    public void startForwarding() {
-        BindingDomConnectorDeployer.startDataForwarding(getConnector(), this, getDomProviderContext());
-    }
-}
index cee4b1efb3a3107e27fa5325dd6d3f92cc937609..aec27235910633fb34389208e02b550c81a85a43 100644 (file)
@@ -18,10 +18,9 @@ module opendaylight-sal-binding-broker-impl {
 
     identity binding-dom-mapping-service {
         base config:service-type;
-        config:java-class "org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService";
+        config:java-class "org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec";
     }
 
-
     identity binding-broker-impl {
         base config:module-type;
         config:provided-service sal:binding-broker-osgi-registry;
@@ -29,13 +28,6 @@ module opendaylight-sal-binding-broker-impl {
         config:java-name-prefix BindingBrokerImpl;
     }
 
-    identity binding-data-broker {
-        base config:module-type;
-        config:provided-service sal:binding-data-broker;
-        config:provided-service sal:binding-data-consumer-broker;
-        config:java-name-prefix DataBrokerImpl;
-    }
-
     identity binding-data-compatible-broker {
         base config:module-type;
         config:provided-service sal:binding-data-broker;
@@ -131,29 +123,6 @@ module opendaylight-sal-binding-broker-impl {
         }
     }
 
-    augment "/config:modules/config:module/config:configuration" {
-        case binding-data-broker {
-            when "/config:modules/config:module/config:type = 'binding-data-broker'";
-            container dom-broker {
-                uses config:service-ref {
-                    refine type {
-                        mandatory true;
-                        config:required-identity dom:dom-broker-osgi-registry;
-                    }
-                }
-            }
-
-            container mapping-service {
-                uses config:service-ref {
-                    refine type {
-                        mandatory true;
-                        config:required-identity binding-dom-mapping-service;
-                    }
-                }
-            }
-        }
-    }
-
     augment "/config:modules/config:module/config:configuration" {
         case binding-data-compatible-broker {
             when "/config:modules/config:module/config:type = 'binding-data-compatible-broker'";
@@ -178,14 +147,6 @@ module opendaylight-sal-binding-broker-impl {
         }
     }
 
-    augment "/config:modules/config:module/config:state" {
-        case binding-data-broker {
-            when "/config:modules/config:module/config:type = 'binding-data-broker'";
-            container data {
-                uses common:data-state;
-            }
-        }
-    }
     augment "/config:modules/config:module/config:state" {
         case binding-rpc-broker {
             when "/config:modules/config:module/config:type = 'binding-rpc-broker'";
index fd0a169694c5836b52fe02bc1207805cd071ffef..815fc452594e837965b1bd7d66a1814cf87bf299 100644 (file)
@@ -1,8 +1,8 @@
 package org.opendaylight.controller.md.sal.binding.impl.test;
 
 import static org.junit.Assert.assertTrue;
-import javassist.ClassPool;
 
+import javassist.ClassPool;
 import org.junit.Test;
 import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
 import org.opendaylight.controller.md.sal.binding.test.AbstractSchemaAwareTest;
@@ -11,7 +11,11 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controll
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.Top;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.two.level.list.TopLevelList;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.two.level.list.TopLevelListKey;
+import org.opendaylight.yangtools.binding.data.codec.gen.impl.StreamWriterGenerator;
+import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry;
+import org.opendaylight.yangtools.sal.binding.generator.impl.GeneratedClassLoadingStrategy;
 import org.opendaylight.yangtools.sal.binding.generator.impl.RuntimeGeneratedMappingServiceImpl;
+import org.opendaylight.yangtools.sal.binding.generator.util.JavassistUtils;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
@@ -34,7 +38,9 @@ public class BindingNormalizedCodecTest extends AbstractSchemaAwareTest {
     @Override
     protected void setupWithSchema(final SchemaContext context) {
         mappingService = new RuntimeGeneratedMappingServiceImpl(ClassPool.getDefault());
-        codec = new BindingToNormalizedNodeCodec(mappingService);
+        StreamWriterGenerator streamWriter = new StreamWriterGenerator(JavassistUtils.forClassPool(ClassPool.getDefault()));
+        BindingNormalizedNodeCodecRegistry registry = new BindingNormalizedNodeCodecRegistry(streamWriter);
+        codec = new BindingToNormalizedNodeCodec(GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy(), mappingService, registry);
         mappingService.onGlobalContextUpdated(context);
         codec.onGlobalContextUpdated(context);
     };
index 60eec55ca55df3df580318e5608ea08f1a319801..106fcea0e9f178470c26eab42fe1bf7c36eb4e08 100644 (file)
@@ -7,9 +7,14 @@
  */
 package org.opendaylight.controller.md.sal.binding.test;
 
+import com.google.common.collect.ImmutableMap;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+
 import javassist.ClassPool;
 
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
 import org.opendaylight.controller.md.sal.binding.impl.ForwardedBackwardsCompatibleDataBroker;
 import org.opendaylight.controller.md.sal.binding.impl.ForwardedBindingDataBroker;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
@@ -19,20 +24,22 @@ import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore;
 import org.opendaylight.controller.sal.binding.test.util.MockSchemaService;
 import org.opendaylight.controller.sal.core.api.model.SchemaService;
 import org.opendaylight.controller.sal.core.spi.data.DOMStore;
+import org.opendaylight.yangtools.binding.data.codec.gen.impl.DataObjectSerializerGenerator;
+import org.opendaylight.yangtools.binding.data.codec.gen.impl.StreamWriterGenerator;
+import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry;
+import org.opendaylight.yangtools.sal.binding.generator.impl.GeneratedClassLoadingStrategy;
 import org.opendaylight.yangtools.sal.binding.generator.impl.RuntimeGeneratedMappingServiceImpl;
+import org.opendaylight.yangtools.sal.binding.generator.util.JavassistUtils;
 import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
-import com.google.common.collect.ImmutableMap;
-import com.google.common.util.concurrent.ListeningExecutorService;
-import com.google.common.util.concurrent.MoreExecutors;
-
 public class DataBrokerTestCustomizer {
 
     private DOMDataBroker domDataBroker;
     private final RuntimeGeneratedMappingServiceImpl mappingService;
     private final MockSchemaService schemaService;
     private ImmutableMap<LogicalDatastoreType, DOMStore> datastores;
+    private final BindingToNormalizedNodeCodec bindingToNormalized ;
 
     public ImmutableMap<LogicalDatastoreType, DOMStore> createDatastores() {
         return ImmutableMap.<LogicalDatastoreType, DOMStore>builder()
@@ -43,7 +50,13 @@ public class DataBrokerTestCustomizer {
 
     public DataBrokerTestCustomizer() {
         schemaService = new MockSchemaService();
-        mappingService = new RuntimeGeneratedMappingServiceImpl(ClassPool.getDefault());
+        ClassPool pool = ClassPool.getDefault();
+        mappingService = new RuntimeGeneratedMappingServiceImpl(pool);
+        DataObjectSerializerGenerator generator = StreamWriterGenerator.create(JavassistUtils.forClassPool(pool));
+        BindingNormalizedNodeCodecRegistry codecRegistry = new BindingNormalizedNodeCodecRegistry(generator);
+        GeneratedClassLoadingStrategy loading = GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy();
+        bindingToNormalized = new BindingToNormalizedNodeCodec(loading, mappingService, codecRegistry);
+        schemaService.registerSchemaContextListener(bindingToNormalized);
     }
 
     public DOMStore createConfigurationDatastore() {
@@ -69,14 +82,13 @@ public class DataBrokerTestCustomizer {
     }
 
     public DataBroker createDataBroker() {
-        return new ForwardedBindingDataBroker(getDOMDataBroker(), getMappingService(), getSchemaService());
+        return new ForwardedBindingDataBroker(getDOMDataBroker(), bindingToNormalized, schemaService );
     }
 
     public ForwardedBackwardsCompatibleDataBroker createBackwardsCompatibleDataBroker() {
-        return new ForwardedBackwardsCompatibleDataBroker(getDOMDataBroker(), getMappingService(), getSchemaService(), MoreExecutors.sameThreadExecutor());
+        return new ForwardedBackwardsCompatibleDataBroker(getDOMDataBroker(), bindingToNormalized, getSchemaService(), MoreExecutors.sameThreadExecutor());
     }
 
-
     private SchemaService getSchemaService() {
         return schemaService;
     }
index 7b67d3b10f4d2eacd2659eefdd1a72af2ca51482..63e0e2290aadd37e697d6a36d6de3fb779c3ab7f 100644 (file)
@@ -16,7 +16,6 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
-
 import org.junit.Test;
 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
 import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
@@ -76,7 +75,7 @@ public class MultipleAugmentationPutsTest extends AbstractDataServiceTest implem
      *
      * @throws Exception
      */
-    @Test( timeout = 15000)
+    @Test()
     public void testAugmentSerialization() throws Exception {
 
         baDataService.registerDataChangeListener(NODES_INSTANCE_ID_BA, this);
@@ -122,7 +121,7 @@ public class MultipleAugmentationPutsTest extends AbstractDataServiceTest implem
         testNodeRemove();
     }
 
-    private <T extends Augmentation<Node>> Node createTestNode(Class<T> augmentationClass, T augmentation) {
+    private <T extends Augmentation<Node>> Node createTestNode(final Class<T> augmentationClass, final T augmentation) {
         NodeBuilder nodeBuilder = new NodeBuilder();
         nodeBuilder.setId(new NodeId(NODE_ID));
         nodeBuilder.setKey(NODE_KEY);
@@ -130,7 +129,7 @@ public class MultipleAugmentationPutsTest extends AbstractDataServiceTest implem
         return nodeBuilder.build();
     }
 
-    private DataModificationTransaction commitNodeAndVerifyTransaction(Node original) throws Exception {
+    private DataModificationTransaction commitNodeAndVerifyTransaction(final Node original) throws Exception {
         DataModificationTransaction transaction = baDataService.beginTransaction();
         transaction.putOperationalData(NODE_INSTANCE_ID_BA, original);
         RpcResult<TransactionStatus> result = transaction.commit().get();
@@ -148,7 +147,7 @@ public class MultipleAugmentationPutsTest extends AbstractDataServiceTest implem
         assertNull(node);
     }
 
-    private AugmentationVerifier<Node> verifyNode(Nodes nodes, Node original) {
+    private AugmentationVerifier<Node> verifyNode(final Nodes nodes, final Node original) {
         assertNotNull(nodes);
         assertNotNull(nodes.getNode());
         assertEquals(1, nodes.getNode().size());
@@ -158,7 +157,7 @@ public class MultipleAugmentationPutsTest extends AbstractDataServiceTest implem
         return new AugmentationVerifier<Node>(readedNode);
     }
 
-    private void assertBindingIndependentVersion(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier nodeId) {
+    private void assertBindingIndependentVersion(final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier nodeId) {
         CompositeNode node = biDataService.readOperationalData(nodeId);
         assertNotNull(node);
     }
@@ -171,7 +170,7 @@ public class MultipleAugmentationPutsTest extends AbstractDataServiceTest implem
         return nodeMeterStatistics(10, false);
     }
 
-    private NodeMeterStatistics nodeMeterStatistics(int count, boolean setDuration) {
+    private NodeMeterStatistics nodeMeterStatistics(final int count, final boolean setDuration) {
         NodeMeterStatisticsBuilder nmsb = new NodeMeterStatisticsBuilder();
         MeterStatisticsBuilder meterStats = new MeterStatisticsBuilder();
 
@@ -207,7 +206,7 @@ public class MultipleAugmentationPutsTest extends AbstractDataServiceTest implem
     }
 
     @Override
-    public void onDataChanged(DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+    public void onDataChanged(final DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
         receivedChangeEvent = change;
     }
 
index fef5715f50deea8ac6038b8684dc832c779cf582..d0a326adff83054ff99cbc9e0b1278dde8ed6ad4 100644 (file)
@@ -9,12 +9,19 @@ package org.opendaylight.controller.sal.binding.test.util;
 
 import static com.google.common.base.Preconditions.checkState;
 
+import com.google.common.annotations.Beta;
+import com.google.common.collect.ClassToInstanceMap;
+import com.google.common.collect.ImmutableClassToInstanceMap;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.MutableClassToInstanceMap;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
 import java.util.Set;
 import java.util.concurrent.Future;
-
 import javassist.ClassPool;
-
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
 import org.opendaylight.controller.md.sal.binding.impl.ForwardedBackwardsCompatibleDataBroker;
 import org.opendaylight.controller.md.sal.binding.impl.ForwardedBindingDataBroker;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
@@ -43,9 +50,14 @@ import org.opendaylight.controller.sal.core.spi.data.DOMStore;
 import org.opendaylight.controller.sal.dom.broker.BrokerImpl;
 import org.opendaylight.controller.sal.dom.broker.MountPointManagerImpl;
 import org.opendaylight.controller.sal.dom.broker.impl.SchemaAwareRpcBroker;
+import org.opendaylight.yangtools.binding.data.codec.gen.impl.DataObjectSerializerGenerator;
+import org.opendaylight.yangtools.binding.data.codec.gen.impl.StreamWriterGenerator;
+import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.sal.binding.generator.impl.GeneratedClassLoadingStrategy;
 import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleInfoBackedContext;
 import org.opendaylight.yangtools.sal.binding.generator.impl.RuntimeGeneratedMappingServiceImpl;
+import org.opendaylight.yangtools.sal.binding.generator.util.JavassistUtils;
 import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
 import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
 import org.opendaylight.yangtools.yang.common.QName;
@@ -56,15 +68,6 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.annotations.Beta;
-import com.google.common.collect.ClassToInstanceMap;
-import com.google.common.collect.ImmutableClassToInstanceMap;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.MutableClassToInstanceMap;
-import com.google.common.util.concurrent.ListeningExecutorService;
-import com.google.common.util.concurrent.MoreExecutors;
-
 @Beta
 public class BindingTestContext implements AutoCloseable {
 
@@ -74,6 +77,7 @@ public class BindingTestContext implements AutoCloseable {
     private static final Logger LOG = LoggerFactory.getLogger(BindingTestContext.class);
 
     private RuntimeGeneratedMappingServiceImpl mappingServiceImpl;
+    private BindingToNormalizedNodeCodec codec;
 
     private DomForwardedBindingBrokerImpl baBrokerImpl;
     private DataBrokerImpl baDataImpl;
@@ -129,7 +133,7 @@ public class BindingTestContext implements AutoCloseable {
     public void startNewDataBroker() {
         checkState(executor != null, "Executor needs to be set");
         checkState(newDOMDataBroker != null, "DOM Data Broker must be set");
-        dataBroker = new ForwardedBindingDataBroker(newDOMDataBroker, mappingServiceImpl, mockSchemaService);
+        dataBroker = new ForwardedBindingDataBroker(newDOMDataBroker, codec, mockSchemaService);
     }
 
     public void startNewDomDataBroker() {
@@ -250,6 +254,12 @@ public class BindingTestContext implements AutoCloseable {
         checkState(classPool != null, "ClassPool needs to be present");
         mappingServiceImpl = new RuntimeGeneratedMappingServiceImpl(classPool);
         mockSchemaService.registerSchemaContextListener(mappingServiceImpl);
+
+        DataObjectSerializerGenerator generator = StreamWriterGenerator.create(JavassistUtils.forClassPool(classPool));
+        BindingNormalizedNodeCodecRegistry codecRegistry = new BindingNormalizedNodeCodecRegistry(generator);
+        GeneratedClassLoadingStrategy loading = GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy();
+        codec = new BindingToNormalizedNodeCodec(loading, mappingServiceImpl, codecRegistry);
+        mockSchemaService.registerSchemaContextListener(codec);
     }
 
     private void updateYangSchema(final ImmutableSet<YangModuleInfo> moduleInfos) {
@@ -280,7 +290,7 @@ public class BindingTestContext implements AutoCloseable {
     }
 
     public void startNewBindingDataBroker() {
-        ForwardedBackwardsCompatibleDataBroker forwarded = new ForwardedBackwardsCompatibleDataBroker(newDOMDataBroker, mappingServiceImpl,mockSchemaService, executor);
+        ForwardedBackwardsCompatibleDataBroker forwarded = new ForwardedBackwardsCompatibleDataBroker(newDOMDataBroker, codec,mockSchemaService, executor);
         baData = forwarded;
     }
 
index 83a69969b7b8c8bd0be90111227bda05cd61fd58..344694381a222850fb23ccac0cc8415b3296f472 100644 (file)
@@ -112,6 +112,7 @@ public class TestHelper {
                 mavenBundle(YANGTOOLS, "binding-generator-api").versionAsInProject(), mavenBundle(YANGTOOLS,
                         "binding-generator-spi").versionAsInProject(), //
                 mavenBundle(YANGTOOLS, "binding-generator-impl").versionAsInProject(),
+                mavenBundle(YANGTOOLS, "binding-data-codec").versionAsInProject(),
                 mavenBundle(YANGTOOLS + ".thirdparty", "antlr4-runtime-osgi-nohead").versionAsInProject(), // //
 
                 mavenBundle(CONTROLLER, "sal-core-api").versionAsInProject().update(), //
index 8a390b337e1849ae8cf2c15f7799073ace928ee2..33039ea2314329e0a132606bff58894e7cb84585 100644 (file)
@@ -11,9 +11,10 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 
+import com.google.inject.Inject;
 import java.util.concurrent.Future;
-
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext;
@@ -22,7 +23,6 @@ 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;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
@@ -31,8 +31,6 @@ 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;
@@ -45,12 +43,20 @@ public class DataServiceTest extends AbstractTest {
     public void setUp() throws Exception {
     }
 
+    /*
+     *
+     * Ignored this, because classes here are constructed from
+     * very different class loader as MD-SAL is run into,
+     * this is code is run from different classloader.
+     *
+     */
     @Test
+    @Ignore
     public void test() throws Exception {
         BindingAwareConsumer consumer1 = new BindingAwareConsumer() {
 
             @Override
-            public void onSessionInitialized(ConsumerContext session) {
+            public void onSessionInitialized(final ConsumerContext session) {
                 consumerDataService = session.getSALService(DataBrokerService.class);
             }
         };
@@ -62,12 +68,12 @@ public class DataServiceTest extends AbstractTest {
         DataModificationTransaction transaction = consumerDataService.beginTransaction();
         assertNotNull(transaction);
 
-        NodeRef node1 = createNodeRef("0");
-        DataObject  node = consumerDataService.readConfigurationData(node1.getValue());
+        InstanceIdentifier<Node> node1 = createNodeRef("0");
+        DataObject  node = consumerDataService.readConfigurationData(node1);
         assertNull(node);
         Node nodeData1 = createNode("0");
 
-        transaction.putConfigurationData(node1.getValue(), nodeData1);
+        transaction.putConfigurationData(node1, nodeData1);
         Future<RpcResult<TransactionStatus>> commitResult = transaction.commit();
         assertNotNull(commitResult);
 
@@ -77,7 +83,7 @@ public class DataServiceTest extends AbstractTest {
         assertNotNull(result.getResult());
         assertEquals(TransactionStatus.COMMITED, result.getResult());
 
-        Node readedData = (Node) consumerDataService.readConfigurationData(node1.getValue());
+        Node readedData = (Node) consumerDataService.readConfigurationData(node1);
         assertNotNull(readedData);
         assertEquals(nodeData1.getKey(), readedData.getKey());
 
@@ -85,7 +91,7 @@ public class DataServiceTest extends AbstractTest {
         DataModificationTransaction transaction2 = consumerDataService.beginTransaction();
         assertNotNull(transaction);
 
-        transaction2.removeConfigurationData(node1.getValue());
+        transaction2.removeConfigurationData(node1);
 
         Future<RpcResult<TransactionStatus>> commitResult2 = transaction2.commit();
         assertNotNull(commitResult2);
@@ -96,21 +102,19 @@ public class DataServiceTest extends AbstractTest {
         assertNotNull(result2.getResult());
         assertEquals(TransactionStatus.COMMITED, result2.getResult());
 
-        DataObject readedData2 = consumerDataService.readConfigurationData(node1.getValue());
+        DataObject readedData2 = consumerDataService.readConfigurationData(node1);
         assertNull(readedData2);
 
 
     }
 
 
-    private static NodeRef createNodeRef(String string) {
+    private static InstanceIdentifier<Node> createNodeRef(final String string) {
         NodeKey key = new NodeKey(new NodeId(string));
-        InstanceIdentifier<Node> path = InstanceIdentifier.builder(Nodes.class).child(Node.class, key).build();
-
-        return new NodeRef(path);
+        return  InstanceIdentifier.builder(Nodes.class).child(Node.class, key).build();
     }
 
-    private static Node createNode(String string) {
+    private static Node createNode(final String string) {
         NodeBuilder ret = new NodeBuilder();
         NodeId id = new NodeId(string);
         ret.setKey(new NodeKey(id));
index 63a921d6f309db37a0a438bbadbafdaadb528485..5e37f36a2c1d6e16c85696315d5427e1a2f2d9de 100644 (file)
                 <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
                     <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
                         <module>
-                            <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">
-                                prefix:schema-service-singleton
-                            </type>
+                            <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:schema-service-singleton</type>
                             <name>yang-schema-service</name>
                         </module>
                         <module>
-                            <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">
-                                prefix:hash-map-data-store
-                            </type>
-                            <name>hash-map-data-store</name>
+                            <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:runtime-generated-mapping</type>
+                            <name>runtime-mapping-singleton</name>
                         </module>
                         <module>
-                            <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">
-                                prefix:dom-broker-impl
-                            </type>
-                            <name>dom-broker</name>
-                            <data-store xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">
-                                <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">
-                                    dom:dom-data-store
-                                </type>
-                                <name>ref_hash-map-data-store</name>
-                            </data-store>
+                            <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-notification-broker</type>
+                            <name>binding-notification-broker</name>
                         </module>
                         <module>
-                            <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
-                                prefix:binding-broker-impl
-                            </type>
+                            <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-broker-impl</type>
                             <name>binding-broker-impl</name>
-                            <notification-service
-                                    xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
-                                <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">
-                                    binding:binding-notification-service
-                                </type>
-                                <name>ref_binding-notification-broker</name>
+                            <notification-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
+                                <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-notification-service</type>
+                                <name>binding-notification-broker</name>
                             </notification-service>
                             <data-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
-                                <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">
-                                    binding:binding-data-broker
-                                </type>
-                                <name>ref_binding-data-broker</name>
+                                <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-data-broker</type>
+                                <name>binding-data-broker</name>
                             </data-broker>
                         </module>
+                        <!--
+                             Tree-based in-memory data store. This is the data store which is currently
+                             recommended for single-node deployments.
+                        -->
                         <module>
-                            <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
-                                prefix:runtime-generated-mapping
-                            </type>
-                            <name>runtime-mapping-singleton</name>
+                            <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:dom-inmemory-data-broker</type>
+                            <name>inmemory-data-broker</name>
+                            <schema-service>
+                                <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
+                                <name>yang-schema-service</name>
+                            </schema-service>
                         </module>
                         <module>
-                            <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
-                                prefix:binding-notification-broker
-                            </type>
-                            <name>binding-notification-broker</name>
+                            <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:dom-broker-impl</type>
+                            <name>inmemory-dom-broker</name>
+                            <async-data-broker>
+                                <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-async-data-broker</type>
+                                <name>inmemory-data-broker</name>
+                            </async-data-broker>
                         </module>
                         <module>
-                            <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
-                                prefix:binding-data-broker
-                            </type>
-                            <name>binding-data-broker</name>
-                            <dom-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
-                                <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">
-                                    dom:dom-broker-osgi-registry
-                                </type>
-                                <name>ref_dom-broker</name>
-                            </dom-broker>
-                            <mapping-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
-                                <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
-                                    binding:binding-dom-mapping-service
-                                </type>
-                                <name>ref_runtime-mapping-singleton</name>
-                            </mapping-service>
+                            <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-data-compatible-broker</type>
+                            <name>inmemory-binding-data-broker</name>
+                            <dom-async-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
+                                <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
+                                <name>dom-broker</name>
+                            </dom-async-broker>
+                            <binding-mapping-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
+                                <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding:binding-dom-mapping-service</type>
+                                <name>runtime-mapping-singleton</name>
+                            </binding-mapping-service>
+                        </module>
+                        <module>
+                            <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-forwarded-data-broker</type>
+                            <name>binding-async-data-broker</name>
+                            <binding-forwarded-data-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
+                                <dom-async-broker>
+                                    <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
+                                    <name>dom-broker</name>
+                                </dom-async-broker>
+                                <binding-mapping-service>
+                                    <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding:binding-dom-mapping-service</type>
+                                    <name>runtime-mapping-singleton</name>
+                                </binding-mapping-service>
+                            </binding-forwarded-data-broker>
                         </module>
                     </modules>
 
                     <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
                         <service>
-                            <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">
-                                dom:schema-service
-                            </type>
+                            <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
                             <instance>
-                                <name>ref_yang-schema-service</name>
-                                <provider>
-                                    /config/modules/module[name='schema-service-singleton']/instance[name='yang-schema-service']
-                                </provider>
+                                <name>yang-schema-service</name>
+                                <provider>/modules/module[type='schema-service-singleton'][name='yang-schema-service']</provider>
                             </instance>
                         </service>
                         <service>
-                            <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">
-                                binding:binding-notification-service
-                            </type>
+                            <type xmlns:binding-impl="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding-impl:binding-dom-mapping-service</type>
                             <instance>
-                                <name>ref_binding-notification-broker</name>
-                                <provider>
-                                    /config/modules/module[name='binding-notification-broker']/instance[name='binding-notification-broker']
-                                </provider>
+                                <name>runtime-mapping-singleton</name>
+                                <provider>/modules/module[type='runtime-generated-mapping'][name='runtime-mapping-singleton']</provider>
                             </instance>
                         </service>
                         <service>
-                            <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">
-                                dom:dom-data-store
-                            </type>
+                            <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-notification-service</type>
                             <instance>
-                                <name>ref_hash-map-data-store</name>
-                                <provider>
-                                    /config/modules/module[name='hash-map-data-store']/instance[name='hash-map-data-store']
-                                </provider>
+                                <name>binding-notification-broker</name>
+                                <provider>/modules/module[type='binding-notification-broker'][name='binding-notification-broker']</provider>
                             </instance>
                         </service>
-
                         <service>
-                            <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">
-                                binding:binding-broker-osgi-registry
-                            </type>
+                            <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-broker-osgi-registry</type>
                             <instance>
-                                <name>ref_binding-broker-impl</name>
-                                <provider>
-                                    /config/modules/module[name='binding-broker-impl']/instance[name='binding-broker-impl']
-                                </provider>
+                                <name>binding-osgi-broker</name>
+                                <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
                             </instance>
                         </service>
                         <service>
                                 <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
                             </instance>
                         </service>
+
+                        <service>
+                            <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
+                            <instance>
+                                <name>dom-broker</name>
+                                <provider>/modules/module[type='dom-broker-impl'][name='inmemory-dom-broker']</provider>
+                            </instance>
+                        </service>
+
                         <service>
-                            <type xmlns:binding-impl="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
-                                binding-impl:binding-dom-mapping-service
-                            </type>
+                            <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-data-broker</type>
                             <instance>
-                                <name>ref_runtime-mapping-singleton</name>
-                                <provider>
-                                    /config/modules/module[name='runtime-generated-mapping']/instance[name='runtime-mapping-singleton']
-                                </provider>
+                                <name>binding-data-broker</name>
+                                <provider>/modules/module[type='binding-data-compatible-broker'][name='inmemory-binding-data-broker']</provider>
                             </instance>
                         </service>
+
                         <service>
-                            <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">
-                                dom:dom-broker-osgi-registry
-                            </type>
+                            <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-async-data-broker</type>
                             <instance>
-                                <name>ref_dom-broker</name>
-                                <provider>/config/modules/module[name='dom-broker-impl']/instance[name='dom-broker']
-                                </provider>
+                                <name>binding-data-broker</name>
+                                <provider>/modules/module[type='binding-forwarded-data-broker'][name='binding-async-data-broker']</provider>
                             </instance>
                         </service>
+
                         <service>
-                            <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">
-                                binding:binding-data-broker
-                            </type>
+                            <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-async-data-broker</type>
                             <instance>
-                                <name>ref_binding-data-broker</name>
-                                <provider>
-                                    /config/modules/module[name='binding-data-broker']/instance[name='binding-data-broker']
-                                </provider>
+                                <name>inmemory-data-broker</name>
+                                <provider>/modules/module[type='dom-inmemory-data-broker'][name='inmemory-data-broker']</provider>
                             </instance>
                         </service>
                     </services>
index edf7388a769a662a0ea7848694501c08a864ac0a..1a14de6f5d5b9049e4199ce743fc7ba95ad913e3 100644 (file)
@@ -32,6 +32,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.f
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.GenericStatistics;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -52,11 +53,10 @@ final class FlowStatsTracker extends AbstractListeningStatsTracker<FlowAndStatis
 
     @Override
     protected void cleanupSingleStat(final DataModificationTransaction trans, final FlowStatsEntry item) {
-        InstanceIdentifier<?> flowRef = getNodeIdentifierBuilder()
-                            .augmentation(FlowCapableNode.class)
-                            .child(Table.class, new TableKey(item.getTableId()))
-                            .child(Flow.class,item.getFlow().getKey())
-                            .augmentation(FlowStatisticsData.class).toInstance();
+        KeyedInstanceIdentifier<Flow, FlowKey> flowRef = getNodeIdentifier()
+                .augmentation(FlowCapableNode.class)
+                .child(Table.class, new TableKey(item.getTableId()))
+                .child(Flow.class, item.getFlow().getKey());
         trans.removeOperationalData(flowRef);
     }
 
index 6dbfd7225b81fe7651881e21f954dee73c729a7f..d7ce9485c63ec92b9fdb48a576246faa0f5ad7e2 100644 (file)
@@ -15,8 +15,14 @@ import static org.opendaylight.md.controller.topology.manager.FlowCapableNodeMap
 import static org.opendaylight.md.controller.topology.manager.FlowCapableNodeMapping.toTopologyNode;
 import static org.opendaylight.md.controller.topology.manager.FlowCapableNodeMapping.toTopologyNodeId;
 
-import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader;
-import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnectorUpdated;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeUpdated;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.FlowTopologyDiscoveryListener;
@@ -41,10 +47,12 @@ import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-import com.google.common.base.Preconditions;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 class FlowCapableTopologyExporter implements FlowTopologyDiscoveryListener, OpendaylightInventoryListener {
+
+    private final Logger LOG = LoggerFactory.getLogger(FlowCapableTopologyExporter.class);
     private final InstanceIdentifier<Topology> topology;
     private final OperationProcessor processor;
 
@@ -55,13 +63,21 @@ class FlowCapableTopologyExporter implements FlowTopologyDiscoveryListener, Open
 
     @Override
     public void onNodeRemoved(final NodeRemoved notification) {
+
+        final NodeId nodeId = toTopologyNodeId(getNodeKey(notification.getNodeRef()).getId());
+        final InstanceIdentifier<Node> nodeInstance = toNodeIdentifier(notification.getNodeRef());
+
         processor.enqueueOperation(new TopologyOperation() {
             @Override
-            public void applyOperation(final DataModificationTransaction transaction) {
-                NodeId nodeId = toTopologyNodeId(getNodeKey(notification.getNodeRef()).getId());
-                InstanceIdentifier<Node> nodeInstance = toNodeIdentifier(notification.getNodeRef());
-                transaction.removeOperationalData(nodeInstance);
-                removeAffectedLinks(transaction, nodeId);
+            public void applyOperation(final ReadWriteTransaction transaction) {
+                removeAffectedLinks(nodeId);
+            }
+        });
+
+        processor.enqueueOperation(new TopologyOperation() {
+            @Override
+            public void applyOperation(ReadWriteTransaction transaction) {
+                transaction.delete(LogicalDatastoreType.OPERATIONAL, nodeInstance);
             }
         });
     }
@@ -72,10 +88,10 @@ class FlowCapableTopologyExporter implements FlowTopologyDiscoveryListener, Open
         if (fcnu != null) {
             processor.enqueueOperation(new TopologyOperation() {
                 @Override
-                public void applyOperation(final DataModificationTransaction transaction) {
-                    Node node = toTopologyNode(toTopologyNodeId(notification.getId()), notification.getNodeRef());
-                    InstanceIdentifier<Node> path = getNodePath(toTopologyNodeId(notification.getId()));
-                    transaction.putOperationalData(path, node);
+                public void applyOperation(final ReadWriteTransaction transaction) {
+                    final Node node = toTopologyNode(toTopologyNodeId(notification.getId()), notification.getNodeRef());
+                    final InstanceIdentifier<Node> path = getNodePath(toTopologyNodeId(notification.getId()));
+                    transaction.put(LogicalDatastoreType.OPERATIONAL, path, node);
                 }
             });
         }
@@ -83,15 +99,22 @@ class FlowCapableTopologyExporter implements FlowTopologyDiscoveryListener, Open
 
     @Override
     public void onNodeConnectorRemoved(final NodeConnectorRemoved notification) {
+
+        final InstanceIdentifier<TerminationPoint> tpInstance = toTerminationPointIdentifier(notification
+                .getNodeConnectorRef());
+
         processor.enqueueOperation(new TopologyOperation() {
             @Override
-            public void applyOperation(final DataModificationTransaction transaction) {
-                InstanceIdentifier<TerminationPoint> tpInstance = toTerminationPointIdentifier(notification
-                        .getNodeConnectorRef());
-                TpId tpId = toTerminationPointId(getNodeConnectorKey(notification.getNodeConnectorRef()).getId());
+            public void applyOperation(final ReadWriteTransaction transaction) {
+                final TpId tpId = toTerminationPointId(getNodeConnectorKey(notification.getNodeConnectorRef()).getId());
+                removeAffectedLinks(tpId);
+            }
+        });
 
-                transaction.removeOperationalData(tpInstance);
-                removeAffectedLinks(transaction, tpId);
+        processor.enqueueOperation(new TopologyOperation() {
+            @Override
+            public void applyOperation(ReadWriteTransaction transaction) {
+                transaction.delete(LogicalDatastoreType.OPERATIONAL, tpInstance);
             }
         });
     }
@@ -102,16 +125,15 @@ class FlowCapableTopologyExporter implements FlowTopologyDiscoveryListener, Open
         if (fcncu != null) {
             processor.enqueueOperation(new TopologyOperation() {
                 @Override
-                public void applyOperation(final DataModificationTransaction transaction) {
-                    NodeId nodeId = toTopologyNodeId(getNodeKey(notification.getNodeConnectorRef()).getId());
+                public void applyOperation(final ReadWriteTransaction transaction) {
+                    final NodeId nodeId = toTopologyNodeId(getNodeKey(notification.getNodeConnectorRef()).getId());
                     TerminationPoint point = toTerminationPoint(toTerminationPointId(notification.getId()),
                             notification.getNodeConnectorRef());
-                    InstanceIdentifier<TerminationPoint> path = tpPath(nodeId, point.getKey().getTpId());
-
-                    transaction.putOperationalData(path, point);
+                    final InstanceIdentifier<TerminationPoint> path = tpPath(nodeId, point.getKey().getTpId());
+                    transaction.put(LogicalDatastoreType.OPERATIONAL, path, point);
                     if ((fcncu.getState() != null && fcncu.getState().isLinkDown())
                             || (fcncu.getConfiguration() != null && fcncu.getConfiguration().isPORTDOWN())) {
-                        removeAffectedLinks(transaction, point.getTpId());
+                        removeAffectedLinks(point.getTpId());
                     }
                 }
             });
@@ -122,10 +144,10 @@ class FlowCapableTopologyExporter implements FlowTopologyDiscoveryListener, Open
     public void onLinkDiscovered(final LinkDiscovered notification) {
         processor.enqueueOperation(new TopologyOperation() {
             @Override
-            public void applyOperation(final DataModificationTransaction transaction) {
-                Link link = toTopologyLink(notification);
-                InstanceIdentifier<Link> path = linkPath(link);
-                transaction.putOperationalData(path, link);
+            public void applyOperation(final ReadWriteTransaction transaction) {
+                final Link link = toTopologyLink(notification);
+                final InstanceIdentifier<Link> path = linkPath(link);
+                transaction.put(LogicalDatastoreType.OPERATIONAL, path, link);
             }
         });
     }
@@ -139,8 +161,8 @@ class FlowCapableTopologyExporter implements FlowTopologyDiscoveryListener, Open
     public void onLinkRemoved(final LinkRemoved notification) {
         processor.enqueueOperation(new TopologyOperation() {
             @Override
-            public void applyOperation(final DataModificationTransaction transaction) {
-                transaction.removeOperationalData(linkPath(toTopologyLink(notification)));
+            public void applyOperation(final ReadWriteTransaction transaction) {
+                transaction.delete(LogicalDatastoreType.OPERATIONAL, linkPath(toTopologyLink(notification)));
             }
         });
     }
@@ -162,28 +184,58 @@ class FlowCapableTopologyExporter implements FlowTopologyDiscoveryListener, Open
         return tpPath(toTopologyNodeId(invNodeKey.getId()), toTerminationPointId(invNodeConnectorKey.getId()));
     }
 
-    private void removeAffectedLinks(final DataModificationTransaction transaction, final NodeId id) {
-        TypeSafeDataReader reader = TypeSafeDataReader.forReader(transaction);
-        Topology topologyData = reader.readOperationalData(topology);
-        if (topologyData != null) {
-            for (Link link : topologyData.getLink()) {
-                if (id.equals(link.getSource().getSourceNode()) || id.equals(link.getDestination().getDestNode())) {
-                    transaction.removeOperationalData(linkPath(link));
-                }
+    private void removeAffectedLinks(final NodeId id) {
+        processor.enqueueOperation(new TopologyOperation() {
+            @Override
+            public void applyOperation(final ReadWriteTransaction transaction) {
+                CheckedFuture<Optional<Topology>, ReadFailedException> topologyDataFuture = transaction.read(LogicalDatastoreType.OPERATIONAL, topology);
+                Futures.addCallback(topologyDataFuture, new FutureCallback<Optional<Topology>>() {
+                    @Override
+                    public void onSuccess(Optional<Topology> topologyOptional) {
+                        if (topologyOptional.isPresent()) {
+                            Topology topologyData = topologyOptional.get();
+                            for (Link link : topologyData.getLink()) {
+                                if (id.equals(link.getSource().getSourceNode()) || id.equals(link.getDestination().getDestNode())) {
+                                    transaction.delete(LogicalDatastoreType.OPERATIONAL, linkPath(link));
+                                }
+                            }
+                        }
+                    }
+
+                    @Override
+                    public void onFailure(Throwable throwable) {
+                        LOG.error("Error reading topology data for topology {}", topology, throwable);
+                    }
+                });
             }
-        }
+        });
     }
 
-    private void removeAffectedLinks(final DataModificationTransaction transaction, final TpId id) {
-        TypeSafeDataReader reader = TypeSafeDataReader.forReader(transaction);
-        Topology topologyData = reader.readOperationalData(topology);
-        if (topologyData != null) {
-            for (Link link : topologyData.getLink()) {
-                if (id.equals(link.getSource().getSourceTp()) || id.equals(link.getDestination().getDestTp())) {
-                    transaction.removeOperationalData(linkPath(link));
-                }
+    private void removeAffectedLinks(final TpId id) {
+        processor.enqueueOperation(new TopologyOperation() {
+            @Override
+            public void applyOperation(final ReadWriteTransaction transaction) {
+                CheckedFuture<Optional<Topology>, ReadFailedException> topologyDataFuture = transaction.read(LogicalDatastoreType.OPERATIONAL, topology);
+                Futures.addCallback(topologyDataFuture, new FutureCallback<Optional<Topology>>() {
+                    @Override
+                    public void onSuccess(Optional<Topology> topologyOptional) {
+                        if (topologyOptional.isPresent()) {
+                            Topology topologyData = topologyOptional.get();
+                            for (Link link : topologyData.getLink()) {
+                                if (id.equals(link.getSource().getSourceTp()) || id.equals(link.getDestination().getDestTp())) {
+                                    transaction.delete(LogicalDatastoreType.OPERATIONAL, linkPath(link));
+                                }
+                            }
+                        }
+                    }
+
+                    @Override
+                    public void onFailure(Throwable throwable) {
+                        LOG.error("Error reading topology data for topology {}", topology, throwable);
+                    }
+                });
             }
-        }
+        });
     }
 
     private InstanceIdentifier<Node> getNodePath(final NodeId nodeId) {
index a87971bc6bc0e1d6a294c30a08dfb73cf81484be..0a3b9f6a6b7c53c193cd3fd523504d4e729df180 100644 (file)
@@ -8,12 +8,12 @@
 package org.opendaylight.md.controller.topology.manager;
 
 import java.util.concurrent.ExecutionException;
-
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
-import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
@@ -38,7 +38,7 @@ public class FlowCapableTopologyProvider extends AbstractBindingAwareProvider im
      */
     @Override
     public synchronized void onSessionInitiated(final ProviderContext session) {
-        final DataProviderService dataService = session.getSALService(DataProviderService.class);
+        final DataBroker dataBroker = session.getSALService(DataBroker.class);
         final NotificationProviderService notificationService = session.getSALService(NotificationProviderService.class);
 
         final String name = "flow:1";
@@ -48,14 +48,14 @@ public class FlowCapableTopologyProvider extends AbstractBindingAwareProvider im
                 .child(Topology.class, key)
                 .build();
 
-        final OperationProcessor processor = new OperationProcessor(dataService);
+        final OperationProcessor processor = new OperationProcessor(dataBroker);
         final FlowCapableTopologyExporter listener = new FlowCapableTopologyExporter(processor, path);
         this.listenerRegistration = notificationService.registerNotificationListener(listener);
 
-        final DataModificationTransaction tx = dataService.beginTransaction();
-        tx.putOperationalData(path, new TopologyBuilder().setKey(key).build());
+        final ReadWriteTransaction tx = dataBroker.newReadWriteTransaction();
+        tx.put(LogicalDatastoreType.OPERATIONAL, path, new TopologyBuilder().setKey(key).build());
         try {
-            tx.commit().get();
+            tx.submit().get();
         } catch (InterruptedException | ExecutionException e) {
             LOG.warn("Initial topology export failed, continuing anyway", e);
         }
@@ -87,8 +87,7 @@ public class FlowCapableTopologyProvider extends AbstractBindingAwareProvider im
     /**
      * Gets called during stop bundle
      *
-     * @param context
-     *            The execution context of the bundle being stopped.
+     * @param context The execution context of the bundle being stopped.
      */
     @Override
     public void stopImpl(final BundleContext context) {
index d60c88032dbcc7015fc064a791ca9a16921d7332..3800413eb1b9964d00207f526177862eb69c5885 100644 (file)
@@ -7,30 +7,27 @@
  */
 package org.opendaylight.md.controller.topology.manager;
 
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
 import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.ExecutionException;
 import java.util.concurrent.LinkedBlockingQueue;
-
-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.yangtools.yang.common.RpcResult;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Preconditions;
-
 final class OperationProcessor implements Runnable {
     private static final Logger LOG = LoggerFactory.getLogger(OperationProcessor.class);
     private static final int MAX_TRANSACTION_OPERATIONS = 100;
     private static final int OPERATION_QUEUE_DEPTH = 500;
 
     private final BlockingQueue<TopologyOperation> queue = new LinkedBlockingQueue<>(OPERATION_QUEUE_DEPTH);
-    // FIXME: Flow capable topology exporter should use transaction chaining API
-    private final DataProviderService dataService;
+    private final DataBroker dataBroker;
 
-    OperationProcessor(final DataProviderService dataService) {
-        this.dataService = Preconditions.checkNotNull(dataService);
+    OperationProcessor(final DataBroker dataBroker) {
+        this.dataBroker = Preconditions.checkNotNull(dataBroker);
     }
 
     void enqueueOperation(final TopologyOperation task) {
@@ -44,11 +41,11 @@ final class OperationProcessor implements Runnable {
     @Override
     public void run() {
         try {
-            for (;;) {
+            for (; ; ) {
                 TopologyOperation op = queue.take();
 
                 LOG.debug("New operations available, starting transaction");
-                final DataModificationTransaction tx = dataService.beginTransaction();
+                final ReadWriteTransaction tx = dataBroker.newReadWriteTransaction();
 
                 int ops = 0;
                 do {
@@ -64,14 +61,18 @@ final class OperationProcessor implements Runnable {
 
                 LOG.debug("Processed {} operations, submitting transaction", ops);
 
-                try {
-                    final RpcResult<TransactionStatus> s = tx.commit().get();
-                    if (!s.isSuccessful()) {
-                        LOG.error("Topology export failed for Tx:{}", tx.getIdentifier());
+                final CheckedFuture txResultFuture = tx.submit();
+                Futures.addCallback(txResultFuture, new FutureCallback() {
+                    @Override
+                    public void onSuccess(Object o) {
+                        LOG.debug("Topology export successful for tx :{}", tx.getIdentifier());
+                    }
+
+                    @Override
+                    public void onFailure(Throwable throwable) {
+                        LOG.error("Topology export transaction {} failed", tx.getIdentifier(), throwable.getCause());
                     }
-                } catch (ExecutionException e) {
-                    LOG.error("Topology export transaction {} failed", tx.getIdentifier(), e.getCause());
-                }
+                });
             }
         } catch (InterruptedException e) {
             LOG.info("Interrupted processing, terminating", e);
index 29d06beade946a1a0bf341917a3741097b5ce980..bbb8a74b03ce4a8701c301bd74fafcd14437465e 100644 (file)
@@ -7,7 +7,7 @@
  */
 package org.opendaylight.md.controller.topology.manager;
 
-import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 
 /**
  * Internal interface for submitted operations. Implementations of this
@@ -19,5 +19,5 @@ interface TopologyOperation {
      *
      * @param transaction Datastore transaction
      */
-    void applyOperation(DataModificationTransaction transaction);
+    void applyOperation(ReadWriteTransaction transaction);
 }
\ No newline at end of file
index 2c10cca0c0e4d0819f91d2f7d5543897d216cd65..ae5aa0f7fbb0c4ccb55d8d389ae4709afe1df4a5 100644 (file)
@@ -43,9 +43,18 @@ public class NeutronRouter extends ConfigurationObject implements Serializable,
     @XmlElement (name="tenant_id")
     String tenantID;
 
-    @XmlElement (name="external_gateway_info")
+    @XmlElement (name="external_gateway_info", nillable=true)
     NeutronRouter_NetworkReference externalGatewayInfo;
 
+    @XmlElement (name="distributed")
+    Boolean distributed;
+
+    @XmlElement (name="gw_port_id", nillable=true)
+    String gatewayPortId;
+
+    @XmlElement (name="routes")
+    List<String> routes;
+
     /* Holds a map of OpenStackRouterInterfaces by subnet UUID
      * used for internal mapping to DOVE
      */
@@ -112,6 +121,30 @@ public class NeutronRouter extends ConfigurationObject implements Serializable,
         this.externalGatewayInfo = externalGatewayInfo;
     }
 
+    public Boolean getDistributed() {
+        return distributed;
+    }
+
+    public void setDistributed(Boolean distributed) {
+        this.distributed = distributed;
+    }
+
+    public String getGatewayPortId() {
+        return gatewayPortId;
+    }
+
+    public void setGatewayPortId(String gatewayPortId) {
+        this.gatewayPortId = gatewayPortId;
+    }
+
+    public List<String> getRoutes() {
+        return routes;
+    }
+
+    public void setRoutes(List<String> routes) {
+        this.routes = routes;
+    }
+
     /**
      * This method copies selected fields from the object and returns them
      * as a new object, suitable for marshaling.
@@ -121,7 +154,6 @@ public class NeutronRouter extends ConfigurationObject implements Serializable,
      * @return an OpenStackRouters object with only the selected fields
      * populated
      */
-
     public NeutronRouter extractFields(List<String> fields) {
         NeutronRouter ans = new NeutronRouter();
         Iterator<String> i = fields.iterator();
@@ -145,6 +177,15 @@ public class NeutronRouter extends ConfigurationObject implements Serializable,
             if (s.equals("external_gateway_info")) {
                 ans.setExternalGatewayInfo(this.getExternalGatewayInfo());
             }
+            if (s.equals("distributed")) {
+                ans.setDistributed(this.getDistributed());
+            }
+            if (s.equals("gw_port_id")) {
+                ans.setGatewayPortId(this.getGatewayPortId());
+            }
+            if (s.equals("routes")){
+                ans.setRoutes(this.getRoutes());
+            }
         }
         return ans;
     }