Merge "BUG 2593 : Fix flakiness in ShardManager ActorNotInitialized tests"
authorTom Pantelis <tpanteli@brocade.com>
Sat, 17 Jan 2015 19:01:19 +0000 (19:01 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Sat, 17 Jan 2015 19:01:20 +0000 (19:01 +0000)
19 files changed:
opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntryBuilder.java
opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/RuntimeBeanEntry.java
opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntryTest.java
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftActor.java
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/NotificationPublishService.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/NotificationService.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/Shard.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ShardTest.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/DomBrokerImplModule.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/PingPongTransactionChain.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/DataStoreStatsWrapper.java [deleted file]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/SchemaAwareDataStoreAdapter.java [deleted file]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/SchemaContextProvider.java [deleted file]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/util/YangDataOperations.java [deleted file]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/util/YangDataUtils.java [deleted file]
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceSalFacade.java
opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPusherImpl.java
opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterActivator.java
opendaylight/netconf/netconf-netty-util/pom.xml

index ed727c9a13590733178d84e66b64cae71f23b058..0199e8cd1792a6d714d4968796b1ed4eca45811c 100644 (file)
@@ -11,7 +11,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.base.Preconditions.checkState;
 import static java.lang.String.format;
 import static org.opendaylight.controller.config.yangjmxgenerator.ConfigConstants.createConfigQName;
-
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Function;
 import com.google.common.base.Optional;
@@ -250,15 +249,10 @@ final class ModuleMXBeanEntryBuilder {
         String moduleLocalNameFromXPath = matcher.group(1);
         IdentitySchemaNode moduleIdentity = moduleIdentities.get(moduleLocalNameFromXPath);
         unaugmentedModuleIdentities.remove(moduleLocalNameFromXPath);
-        checkState(moduleIdentity != null, "Cannot find identity " + moduleLocalNameFromXPath
-                + " matching augmentation " + augmentation);
+        checkState(moduleIdentity != null, "Cannot find identity %s matching augmentation %s", moduleLocalNameFromXPath, augmentation);
         Map<String, QName> providedServices = findProvidedServices(moduleIdentity, currentModule, qNamesToSIEs,
                 schemaContext);
 
-        if (moduleIdentity == null) {
-            throw new IllegalStateException("Cannot find identity specified by augmentation xpath constraint: "
-                    + moduleLocalNameFromXPath + " of " + augmentation);
-        }
         String javaNamePrefix = TypeProviderWrapper.findJavaNamePrefix(moduleIdentity);
 
         Map<String, AttributeIfc> yangToAttributes = null;
@@ -346,7 +340,7 @@ final class ModuleMXBeanEntryBuilder {
         }
     }
 
-    private void checkUniqueAttributesWithGeneratedClass(final Map<String, QName> uniqueGeneratedClassNames,
+    private static void checkUniqueAttributesWithGeneratedClass(final Map<String, QName> uniqueGeneratedClassNames,
             final QName parentQName, final Map<String, AttributeIfc> yangToAttributes) {
         for (Map.Entry<String, AttributeIfc> attr : yangToAttributes.entrySet()) {
             if (attr.getValue() instanceof TOAttribute) {
@@ -359,7 +353,7 @@ final class ModuleMXBeanEntryBuilder {
         }
     }
 
-    private void checkUniqueTOAttr(final Map<String, QName> uniqueGeneratedClassNames, final QName parentQName, final TOAttribute attr) {
+    private static void checkUniqueTOAttr(final Map<String, QName> uniqueGeneratedClassNames, final QName parentQName, final TOAttribute attr) {
         final String upperCaseCamelCase = attr.getUpperCaseCammelCase();
         if (uniqueGeneratedClassNames.containsKey(upperCaseCamelCase)) {
             QName firstDefinedQName = uniqueGeneratedClassNames.get(upperCaseCamelCase);
index 74981a95827d7aafd4cf767599d363575e6a4a99..34e3c2e07183e40b88d238a1a9feb2d1f009a95f 100644 (file)
@@ -9,7 +9,6 @@ package org.opendaylight.controller.config.yangjmxgenerator;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkState;
-
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Function;
 import com.google.common.base.Optional;
@@ -95,7 +94,7 @@ public class RuntimeBeanEntry {
             final List<RuntimeBeanEntry> children, final Set<Rpc> rpcs) {
 
         checkArgument(isRoot == false || keyYangName.isPresent() == false,
-                "Root RuntimeBeanEntry must not have key " + "set");
+                "Root RuntimeBeanEntry must not have key set");
         this.packageName = packageName;
         this.isRoot = isRoot;
         this.yangName = yangName;
@@ -108,16 +107,14 @@ public class RuntimeBeanEntry {
 
         for (AttributeIfc a : attributes) {
             checkState(map.containsKey(a.getAttributeYangName()) == false,
-                    "Attribute already defined: " + a.getAttributeYangName()
-                    + " in " + nodeForReporting);
+                    "Attribute already defined: %s in %s", a.getAttributeYangName(), nodeForReporting);
             map.put(a.getAttributeYangName(), a);
         }
 
         if (keyYangName.isPresent()) {
             AttributeIfc keyJavaName = map.get(keyYangName.get());
-            checkArgument(keyJavaName != null, "Key " + keyYangName.get()
-                    + " not found in attribute " + "list " + attributes
-                    + " in " + nodeForReporting);
+            checkArgument(keyJavaName != null, "Key %s not found in attribute list %s in %s", keyYangName.get(),
+                    attributes, nodeForReporting);
             this.keyJavaName = Optional
                     .of(keyJavaName.getUpperCaseCammelCase());
         } else {
index 17d4d9a5245297a3a54eb55bb19e7c414675e77b..e116f480c52a9aad07a23231fff2bca8e1a2f002 100644 (file)
@@ -8,6 +8,7 @@
 package org.opendaylight.controller.config.yangjmxgenerator;
 
 import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.isA;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
@@ -16,7 +17,6 @@ import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
-
 import com.google.common.collect.Sets;
 import java.net.URI;
 import java.net.URISyntaxException;
@@ -113,7 +113,7 @@ public class ModuleMXBeanEntryTest extends AbstractYangTest {
                 is("threadFactory"));
         assertThat(threadFactoryAttribute.getUpperCaseCammelCase(),
                 is("ThreadFactory"));
-        assertThat(threadFactoryAttribute.getOpenType(), is(SimpleType.class));
+        assertThat(threadFactoryAttribute.getOpenType(), isA(SimpleType.class));
         assertNull(threadFactoryAttribute.getNullableDefault());
         assertNull(threadFactoryAttribute.getNullableDescription());
         assertThat(threadFactoryAttribute.getType().getName(), is("ObjectName"));
@@ -261,7 +261,7 @@ public class ModuleMXBeanEntryTest extends AbstractYangTest {
                 assertThat(toAttr.getAttributeYangName(), is("peer"));
                 assertThat(toAttr.getLowerCaseCammelCase(), is("peer"));
                 assertThat(toAttr.getUpperCaseCammelCase(), is("Peer"));
-                assertThat(toAttr.getOpenType(), is(CompositeType.class));
+                assertThat(toAttr.getOpenType(), isA(CompositeType.class));
                 Set<String> propsExpected = new HashSet<String>(2);
                 propsExpected.add("port");
                 propsExpected.add("core-size");
@@ -296,7 +296,7 @@ public class ModuleMXBeanEntryTest extends AbstractYangTest {
                         is("innerStreamList"));
                 assertThat(innerStream.getUpperCaseCammelCase(),
                         is("InnerStreamList"));
-                assertThat(innerStream.getOpenType(), is(ArrayType.class));
+                assertThat(innerStream.getOpenType(), isA(ArrayType.class));
 
             }
 
index 3b8469207798952298a6f304a2b07e18153e4ea2..a7c3db4fc246bcce77d23e8d324a4301d930568e 100644 (file)
@@ -113,6 +113,8 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor {
 
     private int currentRecoveryBatchCount;
 
+
+
     public RaftActor(String id, Map<String, String> peerAddresses) {
         this(id, peerAddresses, Optional.<ConfigParams>absent());
     }
@@ -397,8 +399,8 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor {
      * @param identifier
      * @param data
      */
-    protected void persistData(ActorRef clientActor, String identifier,
-        Payload data) {
+    protected void persistData(final ActorRef clientActor, final String identifier,
+        final Payload data) {
 
         ReplicatedLogEntry replicatedLogEntry = new ReplicatedLogImplEntry(
             context.getReplicatedLog().lastIndex() + 1,
@@ -408,9 +410,42 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor {
             LOG.debug("Persist data {}", replicatedLogEntry);
         }
 
+        final RaftActorContext raftContext = getRaftActorContext();
+
         replicatedLog
-            .appendAndPersist(clientActor, identifier, replicatedLogEntry);
-    }
+                .appendAndPersist(replicatedLogEntry, new Procedure<ReplicatedLogEntry>() {
+                    @Override
+                    public void apply(ReplicatedLogEntry replicatedLogEntry) throws Exception {
+                        if(!hasFollowers()){
+                            // Increment the Commit Index and the Last Applied values
+                            raftContext.setCommitIndex(replicatedLogEntry.getIndex());
+                            raftContext.setLastApplied(replicatedLogEntry.getIndex());
+
+                            // Apply the state immediately
+                            applyState(clientActor, identifier, data);
+
+                            // Send a ApplyLogEntries message so that we write the fact that we applied
+                            // the state to durable storage
+                            self().tell(new ApplyLogEntries((int) replicatedLogEntry.getIndex()), self());
+
+                            // Check if the "real" snapshot capture has been initiated. If no then do the fake snapshot
+                            if(!hasSnapshotCaptureInitiated){
+                                raftContext.getReplicatedLog().snapshotPreCommit(raftContext.getLastApplied(),
+                                        raftContext.getTermInformation().getCurrentTerm());
+                                raftContext.getReplicatedLog().snapshotCommit();
+                            } else {
+                                LOG.debug("Skipping fake snapshotting for {} because real snapshotting is in progress", getId());
+                            }
+                        } else if (clientActor != null) {
+                            // Send message for replication
+                            currentBehavior.handleMessage(getSelf(),
+                                    new Replicate(clientActor, identifier,
+                                            replicatedLogEntry)
+                            );
+                        }
+
+                    }
+                });    }
 
     protected String getId() {
         return context.getId();
@@ -650,8 +685,15 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor {
         hasSnapshotCaptureInitiated = false;
     }
 
+    protected boolean hasFollowers(){
+        return getRaftActorContext().getPeerAddresses().keySet().size() > 0;
+    }
+
     private class ReplicatedLogImpl extends AbstractReplicatedLogImpl {
 
+        private static final int DATA_SIZE_DIVIDER = 5;
+        private long dataSizeSinceLastSnapshot = 0;
+
         public ReplicatedLogImpl(Snapshot snapshot) {
             super(snapshot.getLastAppliedIndex(), snapshot.getLastAppliedTerm(),
                 snapshot.getUnAppliedEntries());
@@ -686,7 +728,7 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor {
 
         @Override public void appendAndPersist(
             final ReplicatedLogEntry replicatedLogEntry) {
-            appendAndPersist(null, null, replicatedLogEntry);
+            appendAndPersist(replicatedLogEntry, null);
         }
 
         @Override
@@ -694,9 +736,9 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor {
             return dataSize;
         }
 
-        public void appendAndPersist(final ActorRef clientActor,
-            final String identifier,
-            final ReplicatedLogEntry replicatedLogEntry) {
+        public void appendAndPersist(
+            final ReplicatedLogEntry replicatedLogEntry,
+            final Procedure<ReplicatedLogEntry> callback)  {
 
             if(LOG.isDebugEnabled()) {
                 LOG.debug("Append log entry and persist {} ", replicatedLogEntry);
@@ -714,22 +756,48 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor {
                 new Procedure<ReplicatedLogEntry>() {
                     @Override
                     public void apply(ReplicatedLogEntry evt) throws Exception {
-                        dataSize += replicatedLogEntry.size();
+                        int logEntrySize = replicatedLogEntry.size();
+
+                        dataSize += logEntrySize;
+                        long dataSizeForCheck = dataSize;
+
+                        dataSizeSinceLastSnapshot += logEntrySize;
+                        long journalSize = lastIndex()+1;
+
+                        if(!hasFollowers()) {
+                            // When we do not have followers we do not maintain an in-memory log
+                            // due to this the journalSize will never become anything close to the
+                            // snapshot batch count. In fact will mostly be 1.
+                            // Similarly since the journal's dataSize depends on the entries in the
+                            // journal the journal's dataSize will never reach a value close to the
+                            // memory threshold.
+                            // By maintaining the dataSize outside the journal we are tracking essentially
+                            // what we have written to the disk however since we no longer are in
+                            // need of doing a snapshot just for the sake of freeing up memory we adjust
+                            // the real size of data by the DATA_SIZE_DIVIDER so that we do not snapshot as often
+                            // as if we were maintaining a real snapshot
+                            dataSizeForCheck = dataSizeSinceLastSnapshot / DATA_SIZE_DIVIDER;
+                        }
 
                         long dataThreshold = Runtime.getRuntime().totalMemory() *
                                 getRaftActorContext().getConfigParams().getSnapshotDataThresholdPercentage() / 100;
 
                         // when a snaphsot is being taken, captureSnapshot != null
                         if (hasSnapshotCaptureInitiated == false &&
-                                ( journal.size() % context.getConfigParams().getSnapshotBatchCount() == 0 ||
-                                        dataSize > dataThreshold)) {
+                                ( journalSize % context.getConfigParams().getSnapshotBatchCount() == 0 ||
+                                        dataSizeForCheck > dataThreshold)) {
+
+                            dataSizeSinceLastSnapshot = 0;
 
                             LOG.info("Initiating Snapshot Capture..");
                             long lastAppliedIndex = -1;
                             long lastAppliedTerm = -1;
 
                             ReplicatedLogEntry lastAppliedEntry = get(context.getLastApplied());
-                            if (lastAppliedEntry != null) {
+                            if (!hasFollowers()) {
+                                lastAppliedIndex = replicatedLogEntry.getIndex();
+                                lastAppliedTerm = replicatedLogEntry.getTerm();
+                            } else if (lastAppliedEntry != null) {
                                 lastAppliedIndex = lastAppliedEntry.getIndex();
                                 lastAppliedTerm = lastAppliedEntry.getTerm();
                             }
@@ -748,12 +816,8 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor {
                                 null);
                             hasSnapshotCaptureInitiated = true;
                         }
-                        // Send message for replication
-                        if (clientActor != null) {
-                            currentBehavior.handleMessage(getSelf(),
-                                new Replicate(clientActor, identifier,
-                                    replicatedLogEntry)
-                            );
+                        if(callback != null){
+                            callback.apply(replicatedLogEntry);
                         }
                     }
                 }
diff --git a/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/NotificationPublishService.java b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/NotificationPublishService.java
new file mode 100644 (file)
index 0000000..87e37ff
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * 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.md.sal.binding.api;
+
+import java.util.concurrent.TimeUnit;
+import org.opendaylight.yangtools.yang.binding.Notification;
+
+/**
+ * A {@link NotificationService} which also allows its users to
+ * submit YANG-modeled notifications for delivery. There are three
+ * methods of submission, following the patters from {@link java.util.concurrent.BlockingQueue}:
+ * - {@link #putNotification(Notification)}, which may block indefinitely
+ *   if the implementation cannot allocate resources to accept the notification,
+ * - {@link #offerNotification(Notification)}, which does not block if face
+ *   of resource starvation,
+ * - {@link #offerNotification(Notification, int, TimeUnit)}, which may block
+ *   for specified time if resources are thin.
+ *
+ * The actual delivery to listeners is asynchronous and implementation-specific.
+ * Users of this interface should not make any assumptions as to whether the
+ * notification has or has not been seen.
+ */
+public interface NotificationPublishService extends BindingService {
+    /**
+     * Publishes a notification to subscribed listeners. This initiates
+     * the process of sending the notification, but delivery to the
+     * listeners can happen asynchronously, potentially after a call to
+     * this method returns.
+     *
+     * <b>Note:</b> This call will block when the notification queue is full.
+     *
+     * @param notification
+     *            the notification to publish.
+     * @throws InterruptedException if interrupted while waiting
+     * @throws NullPointerException if the notification is null
+     */
+    void putNotification(Notification notification) throws InterruptedException;
+
+    /**
+     * Publishes a notification to subscribed listeners. This initiates
+     * the process of sending the notification, but delivery to the
+     * listeners can happen asynchronously, potentially after a call to
+     * this method returns.
+     *
+     * This method is guaranteed not to block.
+     *
+     * @param notification
+     *            the notification to publish.
+     * @return true if the notification was accepted for processing, false otherwise
+     * @throws NullPointerException if the notification is null
+     */
+    boolean offerNotification(Notification notification);
+
+    /**
+     * Publishes a notification to subscribed listeners. This initiates
+     * the process of sending the notification, but delivery to the
+     * listeners can happen asynchronously, potentially after a call to
+     * this method returns. This method is guaranteed not to block more
+     * than the specified timeout.
+     *
+     * @param notification
+     *            the notification to publish.
+     * @param timeout how long to wait before giving up, in units of unit
+     * @param unit a TimeUnit determining how to interpret the
+     *             timeout parameter
+     * @return true if the notification was accepted for processing, false otherwise
+     * @throws InterruptedException if interrupted while waiting
+     * @throws NullPointerException if the notification or unit is null
+     * @throws IllegalArgumentException if timeout is negative.
+     */
+    boolean offerNotification(Notification notification, int timeout, TimeUnit unit)
+        throws InterruptedException;
+}
diff --git a/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/NotificationService.java b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/NotificationService.java
new file mode 100644 (file)
index 0000000..ba35235
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * 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.md.sal.binding.api;
+
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.NotificationListener;
+
+/**
+ * Notification broker which allows clients to subscribe for and publish YANG-modeled notifications.
+ *
+ * Each YANG module which defines notifications results in a generated interface <code>{ModuleName}Listener</code>
+ * which handles all the notifications defined in the YANG model. Each notification type translates to
+ * a specific method of the form <code>on{NotificationType}</code> on the generated interface.
+ * The generated interface also extends the
+ * {@link org.opendaylight.yangtools.yang.binding.NotificationListener} interface and implementations
+ * are registered using {@link #registerNotificationListener(org.opendaylight.yangtools.yang.binding.NotificationListener)}
+ * method.
+ *
+ * <h5>Dispatch Listener Example</h5>
+ * <p>
+ * Lets assume we have following YANG model:
+ *
+ * <pre>
+ * module example {
+ *      ...
+ *
+ *      notification start {
+ *          ...
+ *      }
+ *
+ *      notification stop {
+ *           ...
+ *      }
+ * }
+ * </pre>
+ *
+ * The generated interface will be:
+ * <pre>
+ *  public interface ExampleListener extends NotificationListener {
+ *      void onStart(Start notification);
+ *      void onStop(Stop notification);
+ *  }
+ * </pre>
+ * The following defines an implementation of the generated interface:
+ * <pre>
+ *  public class MyExampleListener implements ExampleListener {
+ *      public void onStart(Start notification) {
+ *          // do something
+ *      }
+ *
+ *      public void onStop(Stop notification) {
+ *          // do something
+ *      }
+ *  }
+ * </pre>
+ * The implementation is registered as follows:
+ * <pre>
+ *  MyExampleListener listener = new MyExampleListener();
+ *  ListenerRegistration<NotificationListener> reg = service.registerNotificationListener( listener );
+ * </pre>
+ * The <code>onStart</code> method will be invoked when someone publishes a <code>Start</code> notification and
+ * the <code>onStop</code> method will be invoked when someone publishes a <code>Stop</code> notification.
+ */
+public interface NotificationService extends BindingService {
+    /**
+     * Registers a listener which implements a YANG-generated notification interface derived from
+     * {@link NotificationListener}. The listener is registered for all notifications present in
+     * the implemented interface.
+     *
+     * @param listener the listener implementation that will receive notifications.
+     * @return a {@link ListenerRegistration} instance that should be used to unregister the listener
+     *         by invoking the {@link ListenerRegistration#close()} method when no longer needed.
+     */
+    <T extends NotificationListener> ListenerRegistration<T> registerNotificationListener(T listener);
+}
index 7d6dde9c8af296df1b82f331f431daaa0d431832..cf4bd1db43b59f1af750bb81ec7a588da9f97d83 100644 (file)
@@ -321,8 +321,14 @@ public class Shard extends RaftActor {
             // currently uses a same thread executor anyway.
             cohortEntry.getCohort().preCommit().get();
 
-            Shard.this.persistData(getSender(), transactionID,
-                    new CompositeModificationByteStringPayload(cohortEntry.getModification().toSerializable()));
+            // If we do not have any followers and we are not using persistence we can
+            // apply modification to the state immediately
+            if(!hasFollowers() && !persistence().isRecoveryApplicable()){
+                applyModificationToState(getSender(), transactionID, cohortEntry.getModification());
+            } else {
+                Shard.this.persistData(getSender(), transactionID,
+                        new CompositeModificationByteStringPayload(cohortEntry.getModification().toSerializable()));
+            }
         } catch (InterruptedException | ExecutionException e) {
             LOG.error(e, "An exception occurred while preCommitting transaction {}",
                     cohortEntry.getTransactionID());
index 2792342ab2f3921f451999651477edca5664397b..2c526288b5ff9353145d4db6dd51d581783111d9 100644 (file)
@@ -39,6 +39,7 @@ import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicReference;
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.mockito.InOrder;
 import org.mockito.invocation.InvocationOnMock;
@@ -945,6 +946,7 @@ public class ShardTest extends AbstractActorTest {
     }
 
     @Test
+    @Ignore("This test will work only if replication is turned on. Needs modification due to optimizations added to Shard/RaftActor.")
     public void testAbortBeforeFinishCommit() throws Throwable {
         new ShardTestKit(getSystem()) {{
             final TestActorRef<Shard> shard = TestActorRef.create(getSystem(),
index d299afa05771bf533c06a9c6ead7cfb11d44f257..b8861b3465aa963647bec8b138204218288b189a 100644 (file)
@@ -17,18 +17,14 @@ import org.opendaylight.controller.sal.core.api.BrokerService;
 import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
 import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
 import org.opendaylight.controller.sal.core.api.data.DataProviderService;
-import org.opendaylight.controller.sal.core.api.data.DataStore;
 import org.opendaylight.controller.sal.core.api.model.SchemaService;
 import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
 import org.opendaylight.controller.sal.core.api.mount.MountService;
 import org.opendaylight.controller.sal.dom.broker.BackwardsCompatibleMountPointManager;
 import org.opendaylight.controller.sal.dom.broker.BrokerImpl;
-import org.opendaylight.controller.sal.dom.broker.DataBrokerImpl;
 import org.opendaylight.controller.sal.dom.broker.GlobalBundleScanningSchemaServiceImpl;
-import org.opendaylight.controller.sal.dom.broker.impl.SchemaAwareDataStoreAdapter;
 import org.opendaylight.controller.sal.dom.broker.impl.SchemaAwareRpcBroker;
 import org.opendaylight.controller.sal.dom.broker.impl.SchemaContextProviders;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 
 /**
 *
@@ -51,25 +47,19 @@ public final class DomBrokerImplModule extends org.opendaylight.controller.confi
 
     @Override
     public java.lang.AutoCloseable createInstance() {
-        final DataStore legacyStore = getDataStoreDependency();
         final DOMDataBroker asyncBroker= getAsyncDataBrokerDependency();
 
-        ClassToInstanceMap<BrokerService> services = MutableClassToInstanceMap.create();
+        final ClassToInstanceMap<BrokerService> services = MutableClassToInstanceMap.create();
 
 
-        SchemaService schemaService = getSchemaServiceImpl();
+        final SchemaService schemaService = getSchemaServiceImpl();
         services.putInstance(SchemaService.class, schemaService);
-        SchemaAwareRpcBroker router = new SchemaAwareRpcBroker("/", SchemaContextProviders
+        final SchemaAwareRpcBroker router = new SchemaAwareRpcBroker("/", SchemaContextProviders
                 .fromSchemaService(schemaService));
         services.putInstance(RpcProvisionRegistry.class, router);
 
-        final DataProviderService legacyData;
-        if(asyncBroker != null) {
-            services.putInstance(DOMDataBroker.class, asyncBroker);
-            legacyData = new BackwardsCompatibleDataBroker(asyncBroker,schemaService);
-        } else {
-            legacyData = createLegacyDataService(legacyStore,schemaService);
-        }
+        services.putInstance(DOMDataBroker.class, asyncBroker);
+        final DataProviderService legacyData = new BackwardsCompatibleDataBroker(asyncBroker,schemaService);
         services.putInstance(DataProviderService.class,legacyData);
         services.putInstance(DataBrokerService.class, legacyData);
 
@@ -84,22 +74,6 @@ public final class DomBrokerImplModule extends org.opendaylight.controller.confi
         return new BrokerImpl(router, services);
     }
 
-    @Deprecated
-    private DataProviderService createLegacyDataService(final DataStore legacyStore, final SchemaService schemaService) {
-        YangInstanceIdentifier rootPath = YangInstanceIdentifier.builder().toInstance();
-        DataBrokerImpl dataService = new DataBrokerImpl();
-        SchemaAwareDataStoreAdapter wrappedStore = new SchemaAwareDataStoreAdapter();
-        wrappedStore.changeDelegate(legacyStore);
-        wrappedStore.setValidationEnabled(false);
-
-        schemaService.registerSchemaContextListener(wrappedStore);
-
-        dataService.registerConfigurationReader(rootPath, wrappedStore);
-        dataService.registerCommitHandler(rootPath, wrappedStore);
-        dataService.registerOperationalReader(rootPath, wrappedStore);
-        return dataService;
-    }
-
     private SchemaService getSchemaServiceImpl() {
         final SchemaService schemaService;
         if(getRootSchemaService() != null) {
index abd348a9c73404b79f0866160f336bdee30aab59..c3a56ed454024b3cb316c1e5bec9d7184c897edc 100644 (file)
@@ -64,7 +64,6 @@ public final class PingPongTransactionChain implements DOMTransactionChain {
      */
     private static final AtomicReferenceFieldUpdater<PingPongTransactionChain, PingPongTransaction> READY_UPDATER =
             AtomicReferenceFieldUpdater.newUpdater(PingPongTransactionChain.class, PingPongTransaction.class, "readyTx");
-    @SuppressWarnings("unused") // Accessed via READY_UPDATER
     private volatile PingPongTransaction readyTx;
 
     /**
@@ -157,7 +156,10 @@ public final class PingPongTransactionChain implements DOMTransactionChain {
         return oldTx;
     }
 
-    // This forces allocateTransaction() on a slow path
+    /*
+     * This forces allocateTransaction() on a slow path, which has to happen after
+     * this method has completed executing.
+     */
     @GuardedBy("this")
     private void processIfReady() {
         final PingPongTransaction tx = READY_UPDATER.getAndSet(this, null);
@@ -222,14 +224,28 @@ public final class PingPongTransactionChain implements DOMTransactionChain {
     }
 
     private void readyTransaction(final @Nonnull PingPongTransaction tx) {
+        // First mark the transaction as not locked.
         final boolean lockedMatch = LOCKED_UPDATER.compareAndSet(this, tx, null);
         Preconditions.checkState(lockedMatch, "Attempted to submit transaction %s while we have %s", tx, lockedTx);
-
         LOG.debug("Transaction {} unlocked", tx);
 
+        /*
+         * The transaction is ready. It will then be picked up by either next allocation,
+         * or a background transaction completion callback.
+         */
+        final boolean success = READY_UPDATER.compareAndSet(this, null, tx);
+        Preconditions.checkState(success, "Transaction %s collided on ready state", tx, readyTx);
+        LOG.debug("Transaction {} readied");
+
+        /*
+         * We do not see a transaction being in-flight, so we need to take care of dispatching
+         * the transaction to the backend. We are in the ready case, we cannot short-cut
+         * the checking of readyTx, as an in-flight transaction may have completed between us
+         * setting the field above and us checking.
+         */
         if (inflightTx == null) {
             synchronized (this) {
-                processTransaction(tx);
+                processIfReady();
             }
         }
     }
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/DataStoreStatsWrapper.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/DataStoreStatsWrapper.java
deleted file mode 100644 (file)
index bc86581..0000000
+++ /dev/null
@@ -1,145 +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.dom.broker.impl;
-
-import java.util.concurrent.atomic.AtomicLong;
-
-import org.opendaylight.controller.md.sal.common.api.data.DataModification;
-import org.opendaylight.controller.sal.core.api.data.DataStore;
-import org.opendaylight.yangtools.concepts.Delegator;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-
-@Deprecated
-public class DataStoreStatsWrapper implements Delegator<DataStore>, DataStore {
-
-    private final DataStore delegate;
-
-    private AtomicLong cfgReadCount = new AtomicLong();
-    private AtomicLong cfgReadTimeTotal = new AtomicLong();
-
-    private AtomicLong operReadCount = new AtomicLong();
-    private AtomicLong operReadTimeTotal = new AtomicLong();
-
-    private AtomicLong requestCommitCount = new AtomicLong();
-    private AtomicLong requestCommitTimeTotal = new AtomicLong();
-
-    public DataStoreStatsWrapper(DataStore store) {
-        delegate = store;
-    }
-
-    @Override
-    public DataStore getDelegate() {
-        return delegate;
-    }
-
-    @Override
-    public CompositeNode readConfigurationData(YangInstanceIdentifier path) {
-        cfgReadCount.incrementAndGet();
-        final long startTime = System.nanoTime();
-        try {
-            return delegate.readConfigurationData(path);
-        } finally {
-            final long endTime = System.nanoTime();
-            final long runTime = endTime - startTime;
-            cfgReadTimeTotal.addAndGet(runTime);
-        }
-    }
-
-    @Override
-    public CompositeNode readOperationalData(YangInstanceIdentifier path) {
-        operReadCount.incrementAndGet();
-        final long startTime = System.nanoTime();
-        try {
-            return delegate.readOperationalData(path);
-        } finally {
-            final long endTime = System.nanoTime();
-            final long runTime = endTime - startTime;
-            operReadTimeTotal.addAndGet(runTime);
-        }
-    }
-
-    public DataCommitTransaction<YangInstanceIdentifier, CompositeNode> requestCommit(
-            DataModification<YangInstanceIdentifier, CompositeNode> modification) {
-        requestCommitCount.incrementAndGet();
-        final long startTime = System.nanoTime();
-        try {
-            return delegate.requestCommit(modification);
-        } finally {
-            final long endTime = System.nanoTime();
-            final long runTime = endTime - startTime;
-            requestCommitTimeTotal.addAndGet(runTime);
-        }
-    };
-
-    @Override
-    public boolean containsConfigurationPath(YangInstanceIdentifier path) {
-        return delegate.containsConfigurationPath(path);
-    }
-
-    public Iterable<YangInstanceIdentifier> getStoredConfigurationPaths() {
-        return delegate.getStoredConfigurationPaths();
-    }
-
-    public Iterable<YangInstanceIdentifier> getStoredOperationalPaths() {
-        return delegate.getStoredOperationalPaths();
-    }
-
-    public boolean containsOperationalPath(YangInstanceIdentifier path) {
-        return delegate.containsOperationalPath(path);
-    }
-
-    public final long getConfigurationReadCount() {
-        return cfgReadCount.get();
-    }
-
-    public final long getOperationalReadCount() {
-        return operReadCount.get();
-    }
-
-    public final long getRequestCommitCount() {
-        return requestCommitCount.get();
-    }
-
-    public final double getConfigurationReadTotalTime() {
-        return cfgReadTimeTotal.get() / 1000.0d;
-    }
-
-    public final double getOperationalReadTotalTime() {
-        return operReadTimeTotal.get() / 1000.0d;
-    }
-
-    public final double getRequestCommitTotalTime() {
-        return requestCommitTimeTotal.get() / 1000.0d;
-    }
-
-    public final double getConfigurationReadAverageTime() {
-        long readCount = cfgReadCount.get();
-        if(readCount == 0) {
-            return 0;
-        }
-        return getConfigurationReadTotalTime() / readCount;
-    }
-
-    public final double getOperationalReadAverageTime() {
-        long readCount = operReadCount.get();
-        if(readCount == 0) {
-            return 0;
-        }
-        return getOperationalReadTotalTime() / readCount;
-    }
-
-    public final double getRequestCommitAverageTime() {
-        long count = requestCommitCount.get();
-        if(count == 0) {
-            return 0;
-        }
-        return getRequestCommitTotalTime() / count;
-    }
-
-}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/SchemaAwareDataStoreAdapter.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/SchemaAwareDataStoreAdapter.java
deleted file mode 100644 (file)
index 6a456ba..0000000
+++ /dev/null
@@ -1,456 +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.dom.broker.impl;
-
-import static com.google.common.base.Preconditions.checkState;
-import com.google.common.base.Predicate;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.concurrent.Future;
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
-import org.opendaylight.controller.md.sal.common.api.data.DataModification;
-import org.opendaylight.controller.md.sal.common.api.data.DataReader;
-import org.opendaylight.controller.md.sal.common.impl.AbstractDataModification;
-import org.opendaylight.controller.md.sal.common.impl.util.AbstractLockableDelegator;
-import org.opendaylight.controller.sal.core.api.data.DataStore;
-import org.opendaylight.controller.sal.dom.broker.util.YangDataOperations;
-import org.opendaylight.controller.sal.dom.broker.util.YangSchemaUtils;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.Node;
-import org.opendaylight.yangtools.yang.data.api.SimpleNode;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@Deprecated
-public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator<DataStore> implements DataStore, SchemaContextListener, AutoCloseable {
-
-    private final static Logger LOG = LoggerFactory.getLogger(SchemaAwareDataStoreAdapter.class);
-
-    private SchemaContext schema = null;
-    private boolean validationEnabled = false;
-    private final DataReader<YangInstanceIdentifier, CompositeNode> reader = new MergeFirstLevelReader();
-
-    @Override
-    public boolean containsConfigurationPath(final YangInstanceIdentifier path) {
-        try {
-            getDelegateReadLock().lock();
-            return getDelegate().containsConfigurationPath(path);
-
-        } finally {
-            getDelegateReadLock().unlock();
-        }
-    }
-
-    @Override
-    public boolean containsOperationalPath(final YangInstanceIdentifier path) {
-        try {
-            getDelegateReadLock().lock();
-            return getDelegate().containsOperationalPath(path);
-
-        } finally {
-            getDelegateReadLock().unlock();
-        }
-    }
-
-    @Override
-    public Iterable<YangInstanceIdentifier> getStoredConfigurationPaths() {
-        try {
-            getDelegateReadLock().lock();
-            return getDelegate().getStoredConfigurationPaths();
-
-        } finally {
-            getDelegateReadLock().unlock();
-        }
-    }
-
-    @Override
-    public Iterable<YangInstanceIdentifier> getStoredOperationalPaths() {
-        try {
-            getDelegateReadLock().lock();
-            return getDelegate().getStoredOperationalPaths();
-
-        } finally {
-            getDelegateReadLock().unlock();
-        }
-    }
-
-    @Override
-    public CompositeNode readConfigurationData(final YangInstanceIdentifier path) {
-        return reader.readConfigurationData(path);
-    }
-
-    @Override
-    public CompositeNode readOperationalData(final YangInstanceIdentifier path) {
-        return reader.readOperationalData(path);
-    }
-
-    @Override
-    public org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction<YangInstanceIdentifier, CompositeNode> requestCommit(
-            final DataModification<YangInstanceIdentifier, CompositeNode> modification) {
-        validateAgainstSchema(modification);
-        NormalizedDataModification cleanedUp = prepareMergedTransaction(modification);
-        cleanedUp.status = TransactionStatus.SUBMITED;
-        return retrieveDelegate().requestCommit(cleanedUp);
-    }
-
-    public boolean isValidationEnabled() {
-        return validationEnabled;
-    }
-
-    public void setValidationEnabled(final boolean validationEnabled) {
-        this.validationEnabled = validationEnabled;
-    }
-
-    private void validateAgainstSchema(final DataModification<YangInstanceIdentifier, CompositeNode> modification) {
-        if (!validationEnabled) {
-            return;
-        }
-
-        if (schema == null) {
-            LOG.warn("Validation not performed for {}. Reason: YANG Schema not present.", modification.getIdentifier());
-            return;
-        }
-    }
-
-    @Override
-    protected void onDelegateChanged(final DataStore oldDelegate, final DataStore newDelegate) {
-        // NOOP
-    }
-
-    @Override
-    public void onGlobalContextUpdated(final SchemaContext context) {
-        this.schema = context;
-    }
-
-    @Override
-    public void close() throws Exception {
-        this.schema = null;
-    }
-
-    protected CompositeNode mergeData(final YangInstanceIdentifier path, final CompositeNode stored, final CompositeNode modified,
-            final boolean config) {
-        // long startTime = System.nanoTime();
-        try {
-            DataSchemaNode node = schemaNodeFor(path);
-            return YangDataOperations.merge(node, stored, modified, config);
-        } finally {
-            // System.out.println("Merge time: " + ((System.nanoTime() -
-            // startTime) / 1000.0d));
-        }
-    }
-
-    private DataSchemaNode schemaNodeFor(final YangInstanceIdentifier path) {
-        checkState(schema != null, "YANG Schema is not available");
-        return YangSchemaUtils.getSchemaNode(schema, path);
-    }
-
-    private NormalizedDataModification prepareMergedTransaction(
-            final DataModification<YangInstanceIdentifier, CompositeNode> original) {
-        NormalizedDataModification normalized = new NormalizedDataModification(original);
-        LOG.trace("Transaction: {} Removed Configuration {}, Removed Operational {}", original.getIdentifier(),
-                original.getRemovedConfigurationData(), original.getRemovedConfigurationData());
-        LOG.trace("Transaction: {} Created Configuration {}, Created Operational {}", original.getIdentifier(),
-                original.getCreatedConfigurationData().entrySet(), original.getCreatedOperationalData().entrySet());
-        LOG.trace("Transaction: {} Updated Configuration {}, Updated Operational {}", original.getIdentifier(),
-                original.getUpdatedConfigurationData().entrySet(), original.getUpdatedOperationalData().entrySet());
-
-        for (YangInstanceIdentifier entry : original.getRemovedConfigurationData()) {
-            normalized.deepRemoveConfigurationData(entry);
-        }
-        for (YangInstanceIdentifier entry : original.getRemovedOperationalData()) {
-            normalized.deepRemoveOperationalData(entry);
-        }
-        for (Entry<YangInstanceIdentifier, CompositeNode> entry : original.getUpdatedConfigurationData().entrySet()) {
-            normalized.putDeepConfigurationData(entry.getKey(), entry.getValue());
-        }
-        for (Entry<YangInstanceIdentifier, CompositeNode> entry : original.getUpdatedOperationalData().entrySet()) {
-            normalized.putDeepOperationalData(entry.getKey(), entry.getValue());
-        }
-        return normalized;
-    }
-
-    private Iterable<YangInstanceIdentifier> getConfigurationSubpaths(final YangInstanceIdentifier entry) {
-        // FIXME: This should be replaced by index
-        Iterable<YangInstanceIdentifier> paths = getStoredConfigurationPaths();
-
-        return getChildrenPaths(entry, paths);
-
-    }
-
-    public Iterable<YangInstanceIdentifier> getOperationalSubpaths(final YangInstanceIdentifier entry) {
-        // FIXME: This should be indexed
-        Iterable<YangInstanceIdentifier> paths = getStoredOperationalPaths();
-
-        return getChildrenPaths(entry, paths);
-    }
-
-    private static final Iterable<YangInstanceIdentifier> getChildrenPaths(final YangInstanceIdentifier entry,
-            final Iterable<YangInstanceIdentifier> paths) {
-        ImmutableSet.Builder<YangInstanceIdentifier> children = ImmutableSet.builder();
-        for (YangInstanceIdentifier potential : paths) {
-            if (entry.contains(potential)) {
-                children.add(entry);
-            }
-        }
-        return children.build();
-    }
-
-    private final Comparator<Entry<YangInstanceIdentifier, CompositeNode>> preparationComparator = new Comparator<Entry<YangInstanceIdentifier, CompositeNode>>() {
-        @Override
-        public int compare(final Entry<YangInstanceIdentifier, CompositeNode> o1, final Entry<YangInstanceIdentifier, CompositeNode> o2) {
-            YangInstanceIdentifier o1Key = o1.getKey();
-            YangInstanceIdentifier o2Key = o2.getKey();
-            return Integer.compare(Iterables.size(o1Key.getPathArguments()), Iterables.size(o2Key.getPathArguments()));
-        }
-    };
-
-    private class MergeFirstLevelReader implements DataReader<YangInstanceIdentifier, CompositeNode> {
-
-        @Override
-        public CompositeNode readConfigurationData(final YangInstanceIdentifier path) {
-            getDelegateReadLock().lock();
-            try {
-                if (Iterables.isEmpty(path.getPathArguments())) {
-                    return null;
-                }
-                QName qname = null;
-                CompositeNode original = getDelegate().readConfigurationData(path);
-                ArrayList<Node<?>> childNodes = new ArrayList<Node<?>>();
-                if (original != null) {
-                    childNodes.addAll(original.getValue());
-                    qname = original.getNodeType();
-                } else {
-                    qname = path.getLastPathArgument().getNodeType();
-                }
-
-                FluentIterable<YangInstanceIdentifier> directChildren = FluentIterable.from(getStoredConfigurationPaths())
-                        .filter(new Predicate<YangInstanceIdentifier>() {
-                            @Override
-                            public boolean apply(final YangInstanceIdentifier input) {
-                                if (path.contains(input)) {
-                                    int nesting = Iterables.size(input.getPathArguments()) - Iterables.size(path.getPathArguments());
-                                    if (nesting == 1) {
-                                        return true;
-                                    }
-                                }
-                                return false;
-                            }
-                        });
-                for (YangInstanceIdentifier instanceIdentifier : directChildren) {
-                    childNodes.add(getDelegate().readConfigurationData(instanceIdentifier));
-                }
-                if (original == null && childNodes.isEmpty()) {
-                    return null;
-                }
-
-                return new CompositeNodeTOImpl(qname, null, childNodes);
-            } finally {
-                getDelegateReadLock().unlock();
-            }
-        }
-
-        @Override
-        public CompositeNode readOperationalData(final YangInstanceIdentifier path) {
-            getDelegateReadLock().lock();
-            try {
-                if (Iterables.isEmpty(path.getPathArguments())) {
-                    return null;
-                }
-                QName qname = null;
-                CompositeNode original = getDelegate().readOperationalData(path);
-                ArrayList<Node<?>> childNodes = new ArrayList<Node<?>>();
-                if (original != null) {
-                    childNodes.addAll(original.getValue());
-                    qname = original.getNodeType();
-                } else {
-                    qname = path.getLastPathArgument().getNodeType();
-                }
-
-                FluentIterable<YangInstanceIdentifier> directChildren = FluentIterable.from(getStoredOperationalPaths())
-                        .filter(new Predicate<YangInstanceIdentifier>() {
-                            @Override
-                            public boolean apply(final YangInstanceIdentifier input) {
-                                if (path.contains(input)) {
-                                    int nesting = Iterables.size(input.getPathArguments()) - Iterables.size(path.getPathArguments());
-                                    if (nesting == 1) {
-                                        return true;
-                                    }
-                                }
-                                return false;
-                            }
-                        });
-
-                for (YangInstanceIdentifier instanceIdentifier : directChildren) {
-                    childNodes.add(getDelegate().readOperationalData(instanceIdentifier));
-                }
-                if (original == null && childNodes.isEmpty()) {
-                    return null;
-                }
-
-                return new CompositeNodeTOImpl(qname, null, childNodes);
-            } finally {
-                getDelegateReadLock().unlock();
-            }
-        }
-    }
-
-    private class NormalizedDataModification extends AbstractDataModification<YangInstanceIdentifier, CompositeNode> {
-
-        private final String CONFIGURATIONAL_DATA_STORE_MARKER = "configurational";
-        private final String OPERATIONAL_DATA_STORE_MARKER = "operational";
-        private final Object identifier;
-        private TransactionStatus status;
-
-        public NormalizedDataModification(final DataModification<YangInstanceIdentifier, CompositeNode> original) {
-            super(getDelegate());
-            identifier = original;
-            status = TransactionStatus.NEW;
-        }
-
-        /**
-         *
-         * Ensures all subpaths are removed - this currently does slow lookup in
-         * all keys.
-         *
-         * @param entry
-         */
-        public void deepRemoveOperationalData(final YangInstanceIdentifier entry) {
-            Iterable<YangInstanceIdentifier> paths = getOperationalSubpaths(entry);
-            removeOperationalData(entry);
-            for (YangInstanceIdentifier potential : paths) {
-                removeOperationalData(potential);
-            }
-        }
-
-        public void deepRemoveConfigurationData(final YangInstanceIdentifier entry) {
-            Iterable<YangInstanceIdentifier> paths = getConfigurationSubpaths(entry);
-            removeConfigurationData(entry);
-            for (YangInstanceIdentifier potential : paths) {
-                removeConfigurationData(potential);
-            }
-        }
-
-        public void putDeepConfigurationData(final YangInstanceIdentifier entryKey, final CompositeNode entryData) {
-            this.putCompositeNodeData(entryKey, entryData, CONFIGURATIONAL_DATA_STORE_MARKER);
-        }
-
-        public void putDeepOperationalData(final YangInstanceIdentifier entryKey, final CompositeNode entryData) {
-            this.putCompositeNodeData(entryKey, entryData, OPERATIONAL_DATA_STORE_MARKER);
-        }
-
-        @Override
-        public Object getIdentifier() {
-            return this.identifier;
-        }
-
-        @Override
-        public TransactionStatus getStatus() {
-            return status;
-        }
-
-        @Override
-        public Future<RpcResult<TransactionStatus>> commit() {
-            throw new UnsupportedOperationException("Commit should not be invoked on this");
-        }
-
-        @Override
-        protected CompositeNode mergeConfigurationData(final YangInstanceIdentifier path, final CompositeNode stored,
-                final CompositeNode modified) {
-            return mergeData(path, stored, modified, true);
-        }
-
-        @Override
-        protected CompositeNode mergeOperationalData(final YangInstanceIdentifier path, final CompositeNode stored,
-                final CompositeNode modified) {
-            return mergeData(path, stored, modified, false);
-        }
-
-        private void putData(final YangInstanceIdentifier entryKey, final CompositeNode entryData, final String dataStoreIdentifier) {
-            if (dataStoreIdentifier != null && entryKey != null && entryData != null) {
-                switch (dataStoreIdentifier) {
-                case (CONFIGURATIONAL_DATA_STORE_MARKER):
-                    this.putConfigurationData(entryKey, entryData);
-                break;
-                case (OPERATIONAL_DATA_STORE_MARKER):
-                    this.putOperationalData(entryKey, entryData);
-                break;
-
-                default:
-                    LOG.error(dataStoreIdentifier + " is NOT valid DataStore switch marker");
-                    throw new RuntimeException(dataStoreIdentifier + " is NOT valid DataStore switch marker");
-                }
-            }
-        }
-
-        private void putCompositeNodeData(final YangInstanceIdentifier entryKey, final CompositeNode entryData,
-                final String dataStoreIdentifier) {
-            this.putData(entryKey, entryData, dataStoreIdentifier);
-
-            for (Node<?> child : entryData.getValue()) {
-                YangInstanceIdentifier subEntryId = YangInstanceIdentifier.builder(entryKey).node(child.getNodeType())
-                        .toInstance();
-                if (child instanceof CompositeNode) {
-                    DataSchemaNode subSchema = schemaNodeFor(subEntryId);
-                    CompositeNode compNode = (CompositeNode) child;
-                    YangInstanceIdentifier instanceId = null;
-
-                    if (subSchema instanceof ListSchemaNode) {
-                        ListSchemaNode listSubSchema = (ListSchemaNode) subSchema;
-                        Map<QName, Object> mapOfSubValues = this.getValuesFromListSchema(listSubSchema,
-                                (CompositeNode) child);
-                        if (mapOfSubValues != null) {
-                            instanceId = YangInstanceIdentifier.builder(entryKey)
-                                    .nodeWithKey(listSubSchema.getQName(), mapOfSubValues).toInstance();
-                        }
-                    } else if (subSchema instanceof ContainerSchemaNode) {
-                        ContainerSchemaNode containerSchema = (ContainerSchemaNode) subSchema;
-                        instanceId = YangInstanceIdentifier.builder(entryKey).node(subSchema.getQName()).toInstance();
-                    }
-                    if (instanceId != null) {
-                        this.putCompositeNodeData(instanceId, compNode, dataStoreIdentifier);
-                    }
-                }
-            }
-        }
-
-        private Map<QName, Object> getValuesFromListSchema(final ListSchemaNode listSchema, final CompositeNode entryData) {
-            List<QName> keyDef = listSchema.getKeyDefinition();
-            if (keyDef != null && !keyDef.isEmpty()) {
-                Map<QName, Object> map = new HashMap<QName, Object>();
-                for (QName key : keyDef) {
-                    List<Node<?>> data = entryData.get(key);
-                    if (data != null && !data.isEmpty()) {
-                        for (Node<?> nodeData : data) {
-                            if (nodeData instanceof SimpleNode<?>) {
-                                map.put(key, data.get(0).getValue());
-                            }
-                        }
-                    }
-                }
-                return map;
-            }
-            return null;
-        }
-    }
-}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/SchemaContextProvider.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/SchemaContextProvider.java
deleted file mode 100644 (file)
index e49a28d..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * Copyright (c) 2013 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.dom.broker.impl;
-
-/**
- * @deprecated Use org.opendaylight.yangtools.yang.model.api.SchemaContextProvider instead
- */
-@Deprecated
-public interface SchemaContextProvider extends org.opendaylight.yangtools.yang.model.api.SchemaContextProvider{
-
-}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/util/YangDataOperations.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/util/YangDataOperations.java
deleted file mode 100644 (file)
index 41fcd08..0000000
+++ /dev/null
@@ -1,170 +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.dom.broker.util;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Iterables;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.Node;
-import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-
-@Deprecated
-public class YangDataOperations {
-
-    public static CompositeNode merge(final DataSchemaNode schema,
-            final CompositeNode stored, final CompositeNode modified,
-            final boolean config) {
-        if (stored == null) {
-            return modified;
-        }
-
-        Preconditions.checkArgument(schema instanceof ListSchemaNode
-                || schema instanceof ContainerSchemaNode,
-                "Supplied node is not data node container.");
-
-        return YangDataOperations.mergeContainer((DataNodeContainer) schema,
-                stored, modified, config);
-    }
-
-    private static Iterable<? extends Node<?>> _mergeMultiple(
-            final LeafSchemaNode node, final List<Node<?>> original,
-            final List<Node<?>> modified, final boolean configurational) {
-        checkArgument(original.size() == 1);
-        checkArgument(modified.size() == 1);
-
-        return modified;
-    }
-
-    private static Iterable<? extends Node<?>> _mergeMultiple(
-            final LeafListSchemaNode node, final List<Node<?>> original,
-            final List<Node<?>> modified, final boolean configurational) {
-        return modified;
-    }
-
-    private static Iterable<? extends Node<?>> _mergeMultiple(
-            final ContainerSchemaNode node, final List<Node<?>> original,
-            final List<Node<?>> modified, final boolean configurational) {
-        checkArgument(original.size() == 1);
-        checkArgument(modified.size() == 1);
-        return Collections.singletonList(merge(node,
-                (CompositeNode) original.get(0),
-                (CompositeNode) modified.get(0), configurational));
-    }
-
-    private static Iterable<? extends Node<?>> _mergeMultiple(
-            final ListSchemaNode node, final List<Node<?>> original,
-            final List<Node<?>> modified, final boolean configurational) {
-
-        if (node.getKeyDefinition() == null
-                || node.getKeyDefinition().isEmpty()) {
-            return modified;
-        }
-        @SuppressWarnings({ "unchecked", "rawtypes" })
-        final Map<Map<QName, Object>, CompositeNode> originalMap = YangDataUtils
-        .toIndexMap((List) original, node.getKeyDefinition());
-        @SuppressWarnings({ "unchecked", "rawtypes" })
-        final Map<Map<QName, Object>, CompositeNode> modifiedMap = YangDataUtils
-        .toIndexMap((List) modified, node.getKeyDefinition());
-
-        final List<Node<?>> mergedNodes = new ArrayList<Node<?>>(
-                original.size() + modified.size());
-        for (final Map.Entry<Map<QName, Object>, CompositeNode> entry : modifiedMap
-                .entrySet()) {
-            final CompositeNode originalEntry = originalMap.get(entry.getKey());
-            if (originalEntry != null) {
-                originalMap.remove(entry.getKey());
-                mergedNodes.add(merge(node, originalEntry, entry.getValue(),
-                        configurational));
-            } else {
-                mergedNodes.add(entry.getValue());
-            }
-        }
-        mergedNodes.addAll(originalMap.values());
-        return mergedNodes;
-    }
-
-    private static Iterable<? extends Node<?>> mergeMultiple(
-            final DataSchemaNode node, final List<Node<?>> original,
-            final List<Node<?>> modified, final boolean configurational) {
-        if (node instanceof ContainerSchemaNode) {
-            return _mergeMultiple((ContainerSchemaNode) node, original,
-                    modified, configurational);
-        } else if (node instanceof LeafListSchemaNode) {
-            return _mergeMultiple((LeafListSchemaNode) node, original,
-                    modified, configurational);
-        } else if (node instanceof LeafSchemaNode) {
-            return _mergeMultiple((LeafSchemaNode) node, original, modified,
-                    configurational);
-        } else if (node instanceof ListSchemaNode) {
-            return _mergeMultiple((ListSchemaNode) node, original, modified,
-                    configurational);
-        } else {
-            throw new IllegalArgumentException("Unhandled parameter types: "
-                    + Arrays.<Object> asList(node, original, modified,
-                            configurational).toString());
-        }
-    }
-
-    private static CompositeNode mergeContainer(final DataNodeContainer schema,
-            final CompositeNode stored, final CompositeNode modified,
-            final boolean config) {
-        if (stored == null) {
-            return modified;
-        }
-        Preconditions.checkNotNull(stored);
-        Preconditions.checkNotNull(modified);
-        Preconditions.checkArgument(Objects.equals(stored.getNodeType(),
-                modified.getNodeType()));
-
-        final List<Node<?>> mergedChildNodes = new ArrayList<Node<?>>(stored
-                .getValue().size() + modified.getValue().size());
-        final Set<QName> toProcess = new HashSet<QName>(stored.keySet());
-        toProcess.addAll(modified.keySet());
-
-        for (QName qname : toProcess) {
-            final DataSchemaNode schemaChild = schema.getDataChildByName(qname);
-            final List<Node<?>> storedChildren = stored.get(qname);
-            final List<Node<?>> modifiedChildren = modified.get(qname);
-
-            if (modifiedChildren != null && !modifiedChildren.isEmpty()) {
-                if (storedChildren == null || storedChildren.isEmpty()
-                        || schemaChild == null) {
-                    mergedChildNodes.addAll(modifiedChildren);
-                } else {
-                    final Iterable<? extends Node<?>> _mergeMultiple = mergeMultiple(
-                            schemaChild, storedChildren, modifiedChildren,
-                            config);
-                    Iterables.addAll(mergedChildNodes, _mergeMultiple);
-                }
-            } else if (storedChildren != null && !storedChildren.isEmpty()) {
-                mergedChildNodes.addAll(storedChildren);
-            }
-        }
-        return new CompositeNodeTOImpl(stored.getNodeType(), null,
-                mergedChildNodes);
-    }
-}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/util/YangDataUtils.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/util/YangDataUtils.java
deleted file mode 100644 (file)
index bdd3e8d..0000000
+++ /dev/null
@@ -1,48 +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.dom.broker.util;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.SimpleNode;
-
-@Deprecated
-public final class YangDataUtils {
-
-    private YangDataUtils() {
-        throw new UnsupportedOperationException("Utility class");
-    }
-
-    public static Map<Map<QName,Object>,CompositeNode> toIndexMap(final List<CompositeNode> nodes,final List<QName> keys) {
-        ConcurrentHashMap<Map<QName,Object>,CompositeNode> ret = new ConcurrentHashMap<>();
-        for(CompositeNode node : nodes) {
-            Map<QName, Object> key = getKeyMap(node,keys);
-            ret.put(key, node);
-        }
-        return ret;
-    }
-
-    public static Map<QName,Object> getKeyMap(final CompositeNode node, final List<QName> keys) {
-        Map<QName,Object> map = new HashMap<>();
-        for(QName key : keys) {
-            SimpleNode<?> keyNode = node.getFirstSimpleByName(QName.create(node.getNodeType(), key.getLocalName()));
-            checkArgument(keyNode != null,"Node must contains all keys.");
-            Object value = keyNode.getValue();
-            map.put(key, value);
-
-        }
-        return map;
-    }
-}
index 2000e11a35db1f26b330cc5f6df732aa1df058a4..bdeb129d55aec1346b7ae3bdb9dd0cd7eb57a715 100644 (file)
@@ -31,6 +31,7 @@ import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
 import org.osgi.framework.BundleContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -65,7 +66,7 @@ public final class NetconfDeviceSalFacade implements AutoCloseable, RemoteDevice
                                                final NetconfSessionCapabilities netconfSessionPreferences, final RpcImplementation deviceRpc) {
 
         // TODO move SchemaAwareRpcBroker from sal-broker-impl, now we have depend on the whole sal-broker-impl
-        final RpcProvisionRegistry rpcRegistry = new SchemaAwareRpcBroker(id.getPath().toString(), new org.opendaylight.controller.sal.dom.broker.impl.SchemaContextProvider() {
+        final RpcProvisionRegistry rpcRegistry = new SchemaAwareRpcBroker(id.getPath().toString(), new SchemaContextProvider() {
             @Override
             public SchemaContext getSchemaContext() {
                 return schemaContext;
index c20007d397b704b130d0ff7f281c5465588b44ff..cf9958e7f8abf44303aeb18f79a77d01b62d7a9b 100644 (file)
@@ -115,17 +115,20 @@ public class ConfigPusherImpl implements ConfigPusher {
      */
     private synchronized EditAndCommitResponse pushConfigWithConflictingVersionRetries(ConfigSnapshotHolder configSnapshotHolder) throws NetconfDocumentedException {
         ConflictingVersionException lastException;
-        Stopwatch stopwatch = new Stopwatch().start();
+        Stopwatch stopwatch = new Stopwatch();
         do {
             String idForReporting = configSnapshotHolder.toString();
             SortedSet<String> expectedCapabilities = checkNotNull(configSnapshotHolder.getCapabilities(),
                     "Expected capabilities must not be null - %s, check %s", idForReporting,
                     configSnapshotHolder.getClass().getName());
             try (NetconfOperationService operationService = getOperationServiceWithRetries(expectedCapabilities, idForReporting)) {
+                if(!stopwatch.isRunning()) {
+                    stopwatch.start();
+                }
                 return pushConfig(configSnapshotHolder, operationService);
             } catch (ConflictingVersionException e) {
                 lastException = e;
-                LOG.debug("Conflicting version detected, will retry after timeout");
+                LOG.info("Conflicting version detected, will retry after timeout");
                 sleep();
             }
         } while (stopwatch.elapsed(TimeUnit.MILLISECONDS) < conflictingVersionTimeoutMillis);
index 135d5ff9be8c765d4e52432e9f69a14179b0a51d..787f8b10b077612c544a6efcaad813c304ce0c9f 100644 (file)
@@ -41,7 +41,7 @@ public class ConfigPersisterActivator implements BundleActivator {
     public static final String MAX_WAIT_FOR_CAPABILITIES_MILLIS_PROPERTY = "maxWaitForCapabilitiesMillis";
     private static final long MAX_WAIT_FOR_CAPABILITIES_MILLIS_DEFAULT = TimeUnit.MINUTES.toMillis(2);
     public static final String CONFLICTING_VERSION_TIMEOUT_MILLIS_PROPERTY = "conflictingVersionTimeoutMillis";
-    private static final long CONFLICTING_VERSION_TIMEOUT_MILLIS_DEFAULT = TimeUnit.SECONDS.toMillis(30);
+    private static final long CONFLICTING_VERSION_TIMEOUT_MILLIS_DEFAULT = TimeUnit.MINUTES.toMillis(1);
 
     public static final String NETCONF_CONFIG_PERSISTER = "netconf.config.persister";
 
index f1f7375f0a16901fffa09a810cc052761e979c72..45088f60867d36cfe6602b6285315dcc8d4b9a24 100644 (file)
         <artifactId>maven-bundle-plugin</artifactId>
         <configuration>
           <instructions>
-            <Import-Package>org.apache.sshd.*, com.google.common.base, com.google.common.collect, io.netty.buffer,
-              io.netty.channel, io.netty.channel.socket, io.netty.handler.codec, io.netty.handler.ssl, io.netty.util,
-              io.netty.util.concurrent, javax.xml.transform, javax.xml.transform.dom, javax.xml.transform.sax,
-              javax.xml.transform.stream, org.opendaylight.controller.netconf.api,
-              org.opendaylight.controller.netconf.util.messages, org.opendaylight.controller.netconf.util.xml,
-              org.opendaylight.protocol.framework, org.openexi.proc, org.openexi.proc.common, org.openexi.proc.grammars,
-              org.openexi.sax, org.openexi.schema, org.slf4j, org.w3c.dom, org.xml.sax</Import-Package>
+            <Import-Package>*</Import-Package>
             <Export-Package>org.opendaylight.controller.netconf.nettyutil,
               org.opendaylight.controller.netconf.nettyutil.handler,
               org.opendaylight.controller.netconf.nettyutil.handler.exi,