Merge "Optimize NetconfMonitoringServiceImpl getSchemaForCapability"
authorTomas Cere <tcere@cisco.com>
Tue, 29 Mar 2016 14:32:06 +0000 (14:32 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Tue, 29 Mar 2016 14:32:06 +0000 (14:32 +0000)
75 files changed:
netconf/aaa-authn-odl-plugin/src/main/java/org/opendaylight/aaa/odl/CredentialServiceAuthProvider.java
netconf/aaa-authn-odl-plugin/src/main/java/org/opendaylight/aaa/odl/PasswordCredentialAuth.java [deleted file]
netconf/aaa-authn-odl-plugin/src/test/java/org/opendaylight/aaa/odl/CredentialServiceAuthProviderTest.java
netconf/abstract-topology/src/main/java/org/opendaylight/netconf/topology/util/BaseTopologyManager.java
netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/netconf/mdsal/connector/TransactionProvider.java
netconf/mdsal-netconf-monitoring/src/main/java/org/opendaylight/controller/config/yang/netconf/mdsal/monitoring/MonitoringToMdsalWriter.java
netconf/netconf-api/src/main/java/org/opendaylight/netconf/api/xml/XmlNetconfConstants.java
netconf/netconf-client/src/test/java/org/opendaylight/netconf/client/TestingNetconfClient.java
netconf/netconf-impl/src/main/java/org/opendaylight/netconf/impl/NetconfServerSessionListener.java
netconf/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/ssh/client/AsyncSshHandler.java
netconf/netconf-notifications-api/src/main/java/org/opendaylight/netconf/notifications/NetconfNotification.java
netconf/netconf-notifications-api/src/main/yang/netconf-northbound-notification.yang
netconf/netconf-notifications-impl/src/main/java/org/opendaylight/netconf/notifications/impl/ops/CreateSubscription.java
netconf/netconf-notifications-impl/src/main/yang/netconf-northbound-notification-impl.yang
netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/AbstractNetconfTopology.java
netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/NetconfTopology.java
netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/impl/ClusteredNetconfTopology.java
netconf/netconf-util/src/main/java/org/opendaylight/netconf/util/messages/SubtreeFilter.java [moved from netconf/netconf-impl/src/main/java/org/opendaylight/netconf/impl/SubtreeFilter.java with 73% similarity]
netconf/netconf-util/src/test/java/org/opendaylight/netconf/util/messages/SubtreeFilterNotificationTest.java [new file with mode: 0644]
netconf/netconf-util/src/test/java/org/opendaylight/netconf/util/messages/SubtreeFilterRpcTest.java [moved from netconf/netconf-impl/src/test/java/org/opendaylight/netconf/impl/SubtreeFilterTest.java with 86% similarity]
netconf/netconf-util/src/test/resources/subtree/notification/0/filter.xml [new file with mode: 0644]
netconf/netconf-util/src/test/resources/subtree/notification/0/post-filter.xml [new file with mode: 0644]
netconf/netconf-util/src/test/resources/subtree/notification/0/pre-filter.xml [new file with mode: 0644]
netconf/netconf-util/src/test/resources/subtree/notification/1/filter.xml [new file with mode: 0644]
netconf/netconf-util/src/test/resources/subtree/notification/1/post-filter.xml [new file with mode: 0644]
netconf/netconf-util/src/test/resources/subtree/notification/1/pre-filter.xml [new file with mode: 0644]
netconf/netconf-util/src/test/resources/subtree/notification/2/filter.xml [new file with mode: 0644]
netconf/netconf-util/src/test/resources/subtree/notification/2/post-filter.xml [new file with mode: 0644]
netconf/netconf-util/src/test/resources/subtree/notification/2/pre-filter.xml [new file with mode: 0644]
netconf/netconf-util/src/test/resources/subtree/notification/3/filter.xml [new file with mode: 0644]
netconf/netconf-util/src/test/resources/subtree/notification/3/post-filter.xml [new file with mode: 0644]
netconf/netconf-util/src/test/resources/subtree/notification/3/pre-filter.xml [new file with mode: 0644]
netconf/netconf-util/src/test/resources/subtree/notification/4/filter.xml [new file with mode: 0644]
netconf/netconf-util/src/test/resources/subtree/notification/4/post-filter.xml [new file with mode: 0644]
netconf/netconf-util/src/test/resources/subtree/notification/4/pre-filter.xml [new file with mode: 0644]
netconf/netconf-util/src/test/resources/subtree/rpc/0/post-filter.xml [moved from netconf/netconf-impl/src/test/resources/subtree/0/post-filter.xml with 100% similarity]
netconf/netconf-util/src/test/resources/subtree/rpc/0/pre-filter.xml [moved from netconf/netconf-impl/src/test/resources/subtree/0/pre-filter.xml with 100% similarity]
netconf/netconf-util/src/test/resources/subtree/rpc/0/request.xml [moved from netconf/netconf-impl/src/test/resources/subtree/0/request.xml with 100% similarity]
netconf/netconf-util/src/test/resources/subtree/rpc/1/post-filter.xml [moved from netconf/netconf-impl/src/test/resources/subtree/1/post-filter.xml with 100% similarity]
netconf/netconf-util/src/test/resources/subtree/rpc/1/pre-filter.xml [moved from netconf/netconf-impl/src/test/resources/subtree/1/pre-filter.xml with 100% similarity]
netconf/netconf-util/src/test/resources/subtree/rpc/1/request.xml [moved from netconf/netconf-impl/src/test/resources/subtree/1/request.xml with 100% similarity]
netconf/netconf-util/src/test/resources/subtree/rpc/10/post-filter.xml [moved from netconf/netconf-impl/src/test/resources/subtree/10/post-filter.xml with 100% similarity]
netconf/netconf-util/src/test/resources/subtree/rpc/10/pre-filter.xml [moved from netconf/netconf-impl/src/test/resources/subtree/10/pre-filter.xml with 100% similarity]
netconf/netconf-util/src/test/resources/subtree/rpc/10/request.xml [moved from netconf/netconf-impl/src/test/resources/subtree/10/request.xml with 100% similarity]
netconf/netconf-util/src/test/resources/subtree/rpc/2/post-filter.xml [moved from netconf/netconf-impl/src/test/resources/subtree/2/post-filter.xml with 100% similarity]
netconf/netconf-util/src/test/resources/subtree/rpc/2/pre-filter.xml [moved from netconf/netconf-impl/src/test/resources/subtree/2/pre-filter.xml with 100% similarity]
netconf/netconf-util/src/test/resources/subtree/rpc/2/request.xml [moved from netconf/netconf-impl/src/test/resources/subtree/2/request.xml with 100% similarity]
netconf/netconf-util/src/test/resources/subtree/rpc/3/post-filter.xml [moved from netconf/netconf-impl/src/test/resources/subtree/3/post-filter.xml with 100% similarity]
netconf/netconf-util/src/test/resources/subtree/rpc/3/pre-filter.xml [moved from netconf/netconf-impl/src/test/resources/subtree/3/pre-filter.xml with 100% similarity]
netconf/netconf-util/src/test/resources/subtree/rpc/3/request.xml [moved from netconf/netconf-impl/src/test/resources/subtree/3/request.xml with 100% similarity]
netconf/netconf-util/src/test/resources/subtree/rpc/4/post-filter.xml [moved from netconf/netconf-impl/src/test/resources/subtree/4/post-filter.xml with 100% similarity]
netconf/netconf-util/src/test/resources/subtree/rpc/4/pre-filter.xml [moved from netconf/netconf-impl/src/test/resources/subtree/4/pre-filter.xml with 100% similarity]
netconf/netconf-util/src/test/resources/subtree/rpc/4/request.xml [moved from netconf/netconf-impl/src/test/resources/subtree/4/request.xml with 100% similarity]
netconf/netconf-util/src/test/resources/subtree/rpc/5/post-filter.xml [moved from netconf/netconf-impl/src/test/resources/subtree/5/post-filter.xml with 100% similarity]
netconf/netconf-util/src/test/resources/subtree/rpc/5/pre-filter.xml [moved from netconf/netconf-impl/src/test/resources/subtree/5/pre-filter.xml with 100% similarity]
netconf/netconf-util/src/test/resources/subtree/rpc/5/request.xml [moved from netconf/netconf-impl/src/test/resources/subtree/5/request.xml with 100% similarity]
netconf/netconf-util/src/test/resources/subtree/rpc/6/post-filter.xml [moved from netconf/netconf-impl/src/test/resources/subtree/6/post-filter.xml with 100% similarity]
netconf/netconf-util/src/test/resources/subtree/rpc/6/pre-filter.xml [moved from netconf/netconf-impl/src/test/resources/subtree/6/pre-filter.xml with 100% similarity]
netconf/netconf-util/src/test/resources/subtree/rpc/6/request.xml [moved from netconf/netconf-impl/src/test/resources/subtree/6/request.xml with 100% similarity]
netconf/netconf-util/src/test/resources/subtree/rpc/7/post-filter.xml [moved from netconf/netconf-impl/src/test/resources/subtree/7/post-filter.xml with 100% similarity]
netconf/netconf-util/src/test/resources/subtree/rpc/7/pre-filter.xml [moved from netconf/netconf-impl/src/test/resources/subtree/7/pre-filter.xml with 100% similarity]
netconf/netconf-util/src/test/resources/subtree/rpc/7/request.xml [moved from netconf/netconf-impl/src/test/resources/subtree/7/request.xml with 100% similarity]
netconf/netconf-util/src/test/resources/subtree/rpc/8/post-filter.xml [moved from netconf/netconf-impl/src/test/resources/subtree/8/post-filter.xml with 100% similarity]
netconf/netconf-util/src/test/resources/subtree/rpc/8/pre-filter.xml [moved from netconf/netconf-impl/src/test/resources/subtree/8/pre-filter.xml with 100% similarity]
netconf/netconf-util/src/test/resources/subtree/rpc/8/request.xml [moved from netconf/netconf-impl/src/test/resources/subtree/8/request.xml with 100% similarity]
netconf/netconf-util/src/test/resources/subtree/rpc/9/post-filter.xml [moved from netconf/netconf-impl/src/test/resources/subtree/9/post-filter.xml with 100% similarity]
netconf/netconf-util/src/test/resources/subtree/rpc/9/pre-filter.xml [moved from netconf/netconf-impl/src/test/resources/subtree/9/pre-filter.xml with 100% similarity]
netconf/netconf-util/src/test/resources/subtree/rpc/9/request.xml [moved from netconf/netconf-impl/src/test/resources/subtree/9/request.xml with 100% similarity]
netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/NetconfDevice.java
netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/listener/NetconfDeviceCommunicator.java
netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/KeepaliveSalFacade.java
netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceRpc.java
netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/util/NetconfBaseOps.java
restconf/sal-rest-connector/pom.xml
restconf/sal-rest-connector/src/main/resources/WEB-INF/web.xml

index 2fb22dbe56b9586aacfae67c007961514fa808eb..fe1f21c064e6cdc6a94463302cccb174ad072f7c 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.aaa.odl;
 import java.util.Map;
 import org.opendaylight.aaa.api.AuthenticationException;
 import org.opendaylight.aaa.api.Claim;
+import org.opendaylight.aaa.api.CredentialAuth;
 import org.opendaylight.aaa.api.PasswordCredentials;
 import org.opendaylight.netconf.auth.AuthProvider;
 import org.osgi.framework.BundleContext;
@@ -31,34 +32,36 @@ public final class CredentialServiceAuthProvider implements AuthProvider, AutoCl
      */
     public static volatile Map.Entry<BundleContext, CredentialServiceAuthProvider> INSTANCE;
 
-    private volatile PasswordCredentialAuth nullableCredService;
-    private final ServiceTracker<PasswordCredentialAuth, PasswordCredentialAuth> listenerTracker;
+    // FIXME CredentialAuth is generic and it causes warnings during compilation
+    // Maybe there should be a PasswordCredentialAuth implements CredentialAuth<PasswordCredentials>
+    private volatile CredentialAuth<PasswordCredentials> nullableCredService;
+    private final ServiceTracker<CredentialAuth, CredentialAuth> listenerTracker;
 
     public CredentialServiceAuthProvider(final BundleContext bundleContext) {
 
-        final ServiceTrackerCustomizer<PasswordCredentialAuth, PasswordCredentialAuth> customizer = new ServiceTrackerCustomizer<PasswordCredentialAuth, PasswordCredentialAuth>() {
+        final ServiceTrackerCustomizer<CredentialAuth, CredentialAuth> customizer = new ServiceTrackerCustomizer<CredentialAuth, CredentialAuth>() {
             @Override
-            public PasswordCredentialAuth addingService(final ServiceReference<PasswordCredentialAuth> reference) {
+            public CredentialAuth addingService(final ServiceReference<CredentialAuth> reference) {
                 logger.trace("Credential service {} added", reference);
-                nullableCredService =  bundleContext.getService(reference);
+                nullableCredService = bundleContext.getService(reference);
                 return nullableCredService;
             }
 
             @Override
-            public void modifiedService(final ServiceReference<PasswordCredentialAuth> reference, final PasswordCredentialAuth service) {
+            public void modifiedService(final ServiceReference<CredentialAuth> reference, final CredentialAuth service) {
                 logger.trace("Replacing modified Credential service {}", reference);
                 nullableCredService = service;
             }
 
             @Override
-            public void removedService(final ServiceReference<PasswordCredentialAuth> reference, final PasswordCredentialAuth service) {
+            public void removedService(final ServiceReference<CredentialAuth> reference, final CredentialAuth service) {
                 logger.trace("Removing Credential service {}. This AuthProvider will fail to authenticate every time", reference);
                 synchronized (CredentialServiceAuthProvider.this) {
                     nullableCredService = null;
                 }
             }
         };
-        listenerTracker = new ServiceTracker<>(bundleContext, PasswordCredentialAuth.class, customizer);
+        listenerTracker = new ServiceTracker<>(bundleContext, CredentialAuth.class, customizer);
         listenerTracker.open();
     }
 
diff --git a/netconf/aaa-authn-odl-plugin/src/main/java/org/opendaylight/aaa/odl/PasswordCredentialAuth.java b/netconf/aaa-authn-odl-plugin/src/main/java/org/opendaylight/aaa/odl/PasswordCredentialAuth.java
deleted file mode 100644 (file)
index 0fc2024..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Copyright (c) 2016 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.aaa.odl;
-
-import org.opendaylight.aaa.api.CredentialAuth;
-import org.opendaylight.aaa.api.PasswordCredentials;
-
-public interface PasswordCredentialAuth extends CredentialAuth<PasswordCredentials> {
-}
index 0a025e32b17a0d095f97761f231ba6b774469e09..4962256717fb3bc0b7b59fb3a377a4051a465e5f 100644 (file)
@@ -26,6 +26,7 @@ import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 import org.opendaylight.aaa.api.AuthenticationException;
 import org.opendaylight.aaa.api.Claim;
+import org.opendaylight.aaa.api.CredentialAuth;
 import org.opendaylight.aaa.api.PasswordCredentials;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Filter;
@@ -36,7 +37,7 @@ import org.osgi.framework.ServiceReference;
 public class CredentialServiceAuthProviderTest {
 
     @Mock
-    private PasswordCredentialAuth credAuth;
+    private CredentialAuth<PasswordCredentials> credAuth;
     @Mock
     private BundleContext ctx;
 
index df45d9ae714f876ef2864d2cea89a7b4117077f3..75eb91e1c0cc3e3c4f7f6ece4dffcc22c236d352 100644 (file)
@@ -210,8 +210,6 @@ public final class BaseTopologyManager
                     // If the combined connection attempt failed, set the node to connection failed
                     LOG.debug("Futures aggregation failed");
                     naSalNodeWriter.update(nodeId, delegateTopologyHandler.getFailedState(nodeId, node));
-                    // FIXME disconnect those which succeeded
-                    // just issue a delete on delegateTopologyHandler that gets handled on lower level
                 }
             }, TypedActor.context().dispatcher());
 
@@ -299,7 +297,7 @@ public final class BaseTopologyManager
 
                 @Override
                 public void onFailure(final Throwable t) {
-                    // FIXME unable to disconnect all the connections, what do we do now ?
+
                 }
             });
 
@@ -373,8 +371,6 @@ public final class BaseTopologyManager
                     // If the combined connection attempt failed, set the node to connection failed
                     LOG.debug("Futures aggregation failed");
                     naSalNodeWriter.update(nodeId, delegateTopologyHandler.getFailedState(nodeId, null));
-                    // FIXME disconnect those which succeeded
-                    // just issue a delete on delegateTopologyHandler that gets handled on lower level
                 }
             });
             return;
index 0bcd7370fc58f4f9dde85a9250b599004826fa58..f5e303ebd660fb745335f20b1bd9bee09ad8caef 100644 (file)
@@ -23,7 +23,6 @@ import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-//TODO make a global TransactionProvider for all Netconf sessions instead of each session having one.
 public class TransactionProvider implements AutoCloseable{
 
     private static final Logger LOG = LoggerFactory.getLogger(TransactionProvider.class);
index 3424ae7e1551f7940cf985e30cd3702b5a0ad3bc..84322786de099748053d8b936c260d39ad524a08 100644 (file)
@@ -59,8 +59,6 @@ final class MonitoringToMdsalWriter implements AutoCloseable, NetconfMonitoringS
         Preconditions.checkState(dataBroker != null);
         final WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
         tx.put(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(NetconfState.class), state);
-        // FIXME first attempt (right after we register to binding broker) always fails
-        // Is it due to the fact that we are writing from the onSessionInitiated callback ?
         try {
             tx.submit().checkedGet();
             LOG.debug("Netconf state updated successfully");
index 7cac46a013e0626474ff88233785884c36008029..33bbef5cd5523cba29567db02e56d5c59b5a7033 100644 (file)
@@ -24,6 +24,7 @@ public final class XmlNetconfConstants {
     public static final String SOURCE_KEY = "source";
     public static final String RPC_KEY = "rpc";
     public static final String NOTIFICATION_ELEMENT_NAME = "notification";
+    public static final String EVENT_TIME = "eventTime";
 
     public static final String MESSAGE_ID = "message-id";
     public static final String SESSION_ID = "session-id";
@@ -35,6 +36,7 @@ public final class XmlNetconfConstants {
     public static final String URN_IETF_PARAMS_NETCONF_BASE_1_0 = "urn:ietf:params:netconf:base:1.0";
     public static final String URN_IETF_PARAMS_NETCONF_BASE_1_1 = "urn:ietf:params:netconf:base:1.1";
     public static final String URN_IETF_PARAMS_XML_NS_NETCONF_EXI_1_0 = "urn:ietf:params:xml:ns:netconf:exi:1.0";
+    public static final String URN_IETF_PARAMS_NETCONF_CAPABILITY_NOTIFICATION_1_0 = "urn:ietf:params:netconf:capability:notification:1.0";
 
     public static final String URN_IETF_PARAMS_NETCONF_CAPABILITY_EXI_1_0 = "urn:ietf:params:netconf:capability:exi:1.0";
     public static final String URN_IETF_PARAMS_XML_NS_YANG_IETF_NETCONF_MONITORING = "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring";
index 131bea96716334d744e4be6b335f02dcee03fa38..dabe11a3ed9606b42daf45cbde69075cd0787437 100644 (file)
@@ -25,12 +25,12 @@ import java.util.concurrent.CancellationException;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
-import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
-import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.LoginPassword;
 import org.opendaylight.netconf.api.NetconfMessage;
 import org.opendaylight.netconf.client.conf.NetconfClientConfiguration;
 import org.opendaylight.netconf.client.conf.NetconfClientConfiguration.NetconfClientProtocol;
 import org.opendaylight.netconf.client.conf.NetconfClientConfigurationBuilder;
+import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
+import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.LoginPassword;
 import org.opendaylight.protocol.framework.NeverReconnectStrategy;
 
 
@@ -47,21 +47,21 @@ public class TestingNetconfClient implements Closeable {
     private final long sessionId;
 
     public TestingNetconfClient(String clientLabel,
-                                 NetconfClientDispatcher netconfClientDispatcher, final NetconfClientConfiguration config) throws InterruptedException {
+                                NetconfClientDispatcher netconfClientDispatcher, final NetconfClientConfiguration config) throws InterruptedException {
         this.label = clientLabel;
         sessionListener = config.getSessionListener();
         Future<NetconfClientSession> clientFuture = netconfClientDispatcher.createClient(config);
-        clientSession = get(clientFuture);//TODO: make static
+        clientSession = get(clientFuture);
         this.sessionId = clientSession.getSessionId();
     }
 
-    private NetconfClientSession get(Future<NetconfClientSession> clientFuture) throws InterruptedException {
+    private static NetconfClientSession get(Future<NetconfClientSession> clientFuture) throws InterruptedException {
         try {
             return clientFuture.get();
         } catch (CancellationException e) {
-            throw new RuntimeException("Cancelling " + this, e);
+            throw new RuntimeException("Cancelling " + TestingNetconfClient.class.getSimpleName(), e);
         } catch (ExecutionException e) {
-            throw new IllegalStateException("Unable to create " + this, e);
+            throw new IllegalStateException("Unable to create " + TestingNetconfClient.class.getSimpleName(), e);
         }
     }
 
index a1a16f426c17c7316a2f6c082644b071bbef8d99..ca61311cdcbd48f046d2be71644be9432e2296ad 100644 (file)
@@ -20,6 +20,7 @@ import org.opendaylight.netconf.api.NetconfTerminationReason;
 import org.opendaylight.netconf.api.monitoring.NetconfMonitoringService;
 import org.opendaylight.netconf.api.xml.XmlNetconfConstants;
 import org.opendaylight.netconf.impl.osgi.NetconfOperationRouter;
+import org.opendaylight.netconf.util.messages.SubtreeFilter;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
@@ -112,7 +113,7 @@ public class NetconfServerSessionListener implements NetconfSessionListener<Netc
 
             Document rpcReply = operationRouter.onNetconfMessage(incomingDocument, session);
 
-            rpcReply = SubtreeFilter.applySubtreeFilter(incomingDocument, rpcReply);
+            rpcReply = SubtreeFilter.applyRpcSubtreeFilter(incomingDocument, rpcReply);
 
             session.onIncommingRpcSuccess();
 
index de507488736a05f6998babd70321dde7ad6a7b64..cb642c1a9954cba715cbb381431f9467c3c731c3 100644 (file)
@@ -85,8 +85,6 @@ public class AsyncSshHandler extends ChannelOutboundHandlerAdapter {
     public AsyncSshHandler(final AuthenticationHandler authenticationHandler, final SshClient sshClient) throws IOException {
         this.authenticationHandler = Preconditions.checkNotNull(authenticationHandler);
         this.sshClient = Preconditions.checkNotNull(sshClient);
-        // Start just in case
-        sshClient.start();
     }
 
     public static AsyncSshHandler createForNetconfSubsystem(final AuthenticationHandler authenticationHandler) throws IOException {
index 7111a6cbb3bbd523b035be98dea348650c958748..852682a15e2abc7024cc10b869f0b017ce39d961 100644 (file)
@@ -34,6 +34,8 @@ public final class NetconfNotification extends NetconfMessage {
      */
     public static final Date UNKNOWN_EVENT_TIME = new Date(0);
 
+    private final Date eventTime;
+
     /**
      * Create new notification and capture the timestamp in the constructor
      */
@@ -46,6 +48,14 @@ public final class NetconfNotification extends NetconfMessage {
      */
     public NetconfNotification(final Document notificationContent, final Date eventTime) {
         super(wrapNotification(notificationContent, eventTime));
+        this.eventTime = eventTime;
+    }
+
+    /**
+     * @return notification event time
+     */
+    public Date getEventTime() {
+        return eventTime;
     }
 
     private static Document wrapNotification(final Document notificationContent, final Date eventTime) {
index a770a6e6f8c31ca4182dce1daf3735d556be8e9b..fe0e09e8a787d6ca27777eec0c3d790dc3034bd3 100644 (file)
@@ -5,7 +5,9 @@ module netconf-northbound-notification {
 
     import config { prefix config; revision-date 2013-04-05; }
 
-    description "TODO";
+    description
+        "This module contains the base YANG definitions for
+         netconf northbound notifications API";
 
     revision "2015-08-06" {
             description "Initial revision.";
index 3e5a0a8c71ef7c4553f1f6e7959cb2e5d8b5457c..d1a46a67bd7086cdab56c4ac38819932b69e2e5b 100644 (file)
@@ -11,6 +11,7 @@ package org.opendaylight.netconf.notifications.impl.ops;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
+import java.util.Date;
 import java.util.List;
 import org.opendaylight.controller.config.util.xml.DocumentedException;
 import org.opendaylight.controller.config.util.xml.XmlElement;
@@ -24,6 +25,7 @@ import org.opendaylight.netconf.notifications.NetconfNotificationRegistry;
 import org.opendaylight.netconf.notifications.NotificationListenerRegistration;
 import org.opendaylight.netconf.notifications.impl.NetconfNotificationManager;
 import org.opendaylight.netconf.util.mapping.AbstractSingletonNetconfOperation;
+import org.opendaylight.netconf.util.messages.SubtreeFilter;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.CreateSubscriptionInput;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.StreamNameType;
 import org.slf4j.Logger;
@@ -55,11 +57,10 @@ public class CreateSubscription extends AbstractSingletonNetconfOperation implem
         operationElement.checkName(CREATE_SUBSCRIPTION);
         operationElement.checkNamespace(CreateSubscriptionInput.QNAME.getNamespace().toString());
         // FIXME reimplement using CODEC_REGISTRY and parse everything into generated class instance
-        // Waiting ofr https://git.opendaylight.org/gerrit/#/c/13763/
+        // Binding doesn't support anyxml nodes yet, so filter could not be retrieved
+        // xml -> normalized node -> CreateSubscriptionInput conversion could be slower than current approach
 
-        // FIXME filter could be supported same way as netconf server filters get and get-config results
         final Optional<XmlElement> filter = operationElement.getOnlyChildElementWithSameNamespaceOptionally("filter");
-        Preconditions.checkArgument(filter.isPresent() == false, "Filter element not yet supported");
 
         // Replay not supported
         final Optional<XmlElement> startTime = operationElement.getOnlyChildElementWithSameNamespaceOptionally("startTime");
@@ -78,7 +79,7 @@ public class CreateSubscription extends AbstractSingletonNetconfOperation implem
         }
 
         final NotificationListenerRegistration notificationListenerRegistration =
-                notifications.registerNotificationListener(streamNameType, new NotificationSubscription(netconfSession));
+                notifications.registerNotificationListener(streamNameType, new NotificationSubscription(netconfSession, filter));
         subscriptions.add(notificationListenerRegistration);
 
         return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.<String>absent());
@@ -115,14 +116,29 @@ public class CreateSubscription extends AbstractSingletonNetconfOperation implem
 
     private static class NotificationSubscription implements NetconfNotificationListener {
         private final NetconfSession currentSession;
+        private final Optional<XmlElement> filter;
 
-        public NotificationSubscription(final NetconfSession currentSession) {
+        public NotificationSubscription(final NetconfSession currentSession, final Optional<XmlElement> filter) {
             this.currentSession = currentSession;
+            this.filter = filter;
         }
 
         @Override
         public void onNotification(final StreamNameType stream, final NetconfNotification notification) {
-            currentSession.sendMessage(notification);
+            if (filter.isPresent()) {
+                try {
+                    final Optional<Document> filtered = SubtreeFilter.applySubtreeNotificationFilter(this.filter.get(), notification.getDocument());
+                    if (filtered.isPresent()) {
+                        final Date eventTime = notification.getEventTime();
+                        currentSession.sendMessage(new NetconfNotification(filtered.get(), eventTime));
+                    }
+                } catch (DocumentedException e) {
+                    LOG.warn(e.toString());
+                    currentSession.sendMessage(notification);
+                }
+            } else {
+                currentSession.sendMessage(notification);
+            }
         }
     }
 }
index cd5ca4641663063a107c0fa31f05e13f6f9858bc..4b5fb35b8ddc6c563fe83fd4576fd3abd1b2f73c 100644 (file)
@@ -6,7 +6,9 @@ module netconf-northbound-notification-impl {
     import config { prefix config; revision-date 2013-04-05; }
     import netconf-northbound-notification { prefix nnn; revision-date 2015-08-06; }
 
-    description "TODO";
+    description
+        "This module contains the base YANG definitions for
+         netconf northbound notifications implementation";
 
     revision "2015-08-07"{
         description "Initial revision.";
index 777adcf405f6fe8fd73ff2f1fd0f7d86e3364175..bfc919e5955d81740f0c8090387fa50164e76906 100644 (file)
@@ -254,8 +254,7 @@ public abstract class AbstractNetconfTopology implements NetconfTopology, Bindin
 
     protected NetconfConnectorDTO createDeviceCommunicator(final NodeId nodeId,
                                                          final NetconfNode node) {
-        //setup default values since default value is not supported yet in mdsal
-        // TODO remove this when mdsal starts supporting default values
+        //setup default values since default value is not supported in mdsal
         final Long defaultRequestTimeoutMillis = node.getDefaultRequestTimeoutMillis() == null ? DEFAULT_REQUEST_TIMEOUT_MILLIS : node.getDefaultRequestTimeoutMillis();
         final Long keepaliveDelay = node.getKeepaliveDelay() == null ? DEFAULT_KEEPALIVE_DELAY : node.getKeepaliveDelay();
         final Boolean reconnectOnChangedSchema = node.isReconnectOnChangedSchema() == null ? DEFAULT_RECONNECT_ON_CHANGED_SCHEMA : node.isReconnectOnChangedSchema();
@@ -359,8 +358,7 @@ public abstract class AbstractNetconfTopology implements NetconfTopology, Bindin
 
     public NetconfReconnectingClientConfiguration getClientConfig(final NetconfClientSessionListener listener, NetconfNode node) {
 
-        //setup default values since default value is not supported yet in mdsal
-        // TODO remove this when mdsal starts supporting default values
+        //setup default values since default value is not supported in mdsal
         final long clientConnectionTimeoutMillis = node.getConnectionTimeoutMillis() == null ? DEFAULT_CONNECTION_TIMEOUT_MILLIS : node.getConnectionTimeoutMillis();
         final long maxConnectionAttempts = node.getMaxConnectionAttempts() == null ? DEFAULT_MAX_CONNECTION_ATTEMPTS : node.getMaxConnectionAttempts();
         final int betweenAttemptsTimeoutMillis = node.getBetweenAttemptsTimeoutMillis() == null ? DEFAULT_BETWEEN_ATTEMPTS_TIMEOUT_MILLIS : node.getBetweenAttemptsTimeoutMillis();
index a8743ec56dbcbe37123e57732197cc48f531fbaf..7c3b83617b7ff2ef1e70210ea9f22428d63f22c4 100644 (file)
@@ -19,7 +19,6 @@ import org.opendaylight.netconf.topology.pipeline.TopologyMountPointFacade.Conne
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
 
-// TODO maybe rename to NetconfTopologyDispatcher?
 public interface NetconfTopology {
 
     String getTopologyId();
index 1d440cc125f69d45016585673e630be2ae9437da..04c95b49aaf49e0074858f10b5d3cd8adcb5ef4b 100644 (file)
@@ -137,8 +137,7 @@ public class ClusteredNetconfTopology extends AbstractNetconfTopology implements
     @Override
     protected NetconfConnectorDTO createDeviceCommunicator(final NodeId nodeId,
                                                            final NetconfNode node) {
-        //setup default values since default value is not supported yet in mdsal
-        // TODO remove this when mdsal starts supporting default values
+        //setup default values since default value is not supported in mdsal
         final Long defaultRequestTimeoutMillis = node.getDefaultRequestTimeoutMillis() == null ? DEFAULT_REQUEST_TIMEOUT_MILLIS : node.getDefaultRequestTimeoutMillis();
         final Long keepaliveDelay = node.getKeepaliveDelay() == null ? DEFAULT_KEEPALIVE_DELAY : node.getKeepaliveDelay();
         final Boolean reconnectOnChangedSchema = node.isReconnectOnChangedSchema() == null ? DEFAULT_RECONNECT_ON_CHANGED_SCHEMA : node.isReconnectOnChangedSchema();
similarity index 73%
rename from netconf/netconf-impl/src/main/java/org/opendaylight/netconf/impl/SubtreeFilter.java
rename to netconf/netconf-util/src/main/java/org/opendaylight/netconf/util/messages/SubtreeFilter.java
index d1466dcdd5a72cc6dfdbdd0739c5bd5ad75457bc..949e63d661a1deea9d1692c50ec997ccd683f1bb 100644 (file)
@@ -6,7 +6,7 @@
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
 
-package org.opendaylight.netconf.impl;
+package org.opendaylight.netconf.util.messages;
 
 import com.google.common.base.Optional;
 import java.io.IOException;
@@ -14,8 +14,8 @@ import java.util.Map;
 import org.opendaylight.controller.config.util.xml.DocumentedException;
 import org.opendaylight.controller.config.util.xml.XmlElement;
 import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.netconf.util.mapping.AbstractNetconfOperation.OperationNameAndNamespace;
 import org.opendaylight.netconf.api.xml.XmlNetconfConstants;
+import org.opendaylight.netconf.util.mapping.AbstractNetconfOperation.OperationNameAndNamespace;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Attr;
@@ -30,7 +30,7 @@ import org.xml.sax.SAXException;
 public class SubtreeFilter {
     private static final Logger LOG = LoggerFactory.getLogger(SubtreeFilter.class);
 
-    static Document applySubtreeFilter(Document requestDocument, Document rpcReply) throws DocumentedException {
+    public static Document applyRpcSubtreeFilter(Document requestDocument, Document rpcReply) throws DocumentedException {
         OperationNameAndNamespace operationNameAndNamespace = new OperationNameAndNamespace(requestDocument);
         if (XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0.equals(operationNameAndNamespace.getNamespace()) &&
                 XmlNetconfConstants.GET.equals(operationNameAndNamespace.getOperationName()) ||
@@ -43,16 +43,9 @@ public class SubtreeFilter {
                 return rpcReply;
             }
 
-            // FIXME: rpcReply document must be reread otherwise some nodes do not inherit namespaces. (services/service)
-            try {
-                rpcReply = XmlUtil.readXmlToDocument(XmlUtil.toString(rpcReply, true));
-            } catch (SAXException | IOException e) {
-                LOG.error("Cannot transform document", e);
-                throw new DocumentedException("Cannot transform document" + e);
-            }
+            rpcReply = reReadDocument(rpcReply);
             XmlElement filter = maybeFilter.get();
-            if ("subtree".equals(filter.getAttribute("type"))||
-                    "subtree".equals(filter.getAttribute("type", XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0))) {
+            if (isSupported(filter)) {
 
                 // do
                 return filtered(maybeFilter.get(), rpcReply);
@@ -62,6 +55,68 @@ public class SubtreeFilter {
         return rpcReply; // return identical document
     }
 
+    /**
+     * Filters notification content. If filter type isn't of type "subtree", returns unchanged notification content.
+     * If no match is found, absent is returned.
+     * @param filter filter
+     * @param notification notification
+     * @return document containing filtered notification content
+     * @throws DocumentedException
+     */
+    public static Optional<Document> applySubtreeNotificationFilter(XmlElement filter, Document notification) throws DocumentedException {
+        notification = reReadDocument(notification);
+        removeEventTimeNode(notification);
+        if (isSupported(filter)) {
+            return Optional.fromNullable(filteredNotification(filter, notification));
+        }
+        return Optional.of(extractNotificationContent(notification));
+    }
+
+    private static Document reReadDocument(Document notification) throws DocumentedException {
+        // FIXME: rpcReply document must be reread otherwise some nodes do not inherit namespaces. (services/service)
+        try {
+            notification = XmlUtil.readXmlToDocument(XmlUtil.toString(notification, true));
+        } catch (SAXException | IOException e) {
+            LOG.error("Cannot transform document", e);
+            throw new DocumentedException("Cannot transform document" + e);
+        }
+        return notification;
+    }
+
+    private static void removeEventTimeNode(Document document) {
+        final Node eventTimeNode = document.getDocumentElement().getElementsByTagNameNS(
+                XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_CAPABILITY_NOTIFICATION_1_0, XmlNetconfConstants.EVENT_TIME).item(0);
+        document.getDocumentElement().removeChild(eventTimeNode);
+    }
+
+    private static boolean isSupported(XmlElement filter) {
+        return "subtree".equals(filter.getAttribute("type"))||
+                "subtree".equals(filter.getAttribute("type", XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0));
+    }
+
+    private static Document extractNotificationContent(Document notification) throws DocumentedException {
+        XmlElement root = XmlElement.fromDomElement(notification.getDocumentElement());
+        XmlElement content = root.getOnlyChildElement();
+        notification.removeChild(root.getDomElement());
+        notification.appendChild(content.getDomElement());
+        return notification;
+    }
+
+    private static Document filteredNotification(XmlElement filter, Document originalNotification) throws DocumentedException {
+        Document result = XmlUtil.newDocument();
+        XmlElement dataSrc = XmlElement.fromDomDocument(originalNotification);
+        Element dataDst = (Element) result.importNode(dataSrc.getDomElement(), false);
+        for (XmlElement filterChild : filter.getChildElements()) {
+            addSubtree2(filterChild, dataSrc.getOnlyChildElement(), XmlElement.fromDomElement(dataDst));
+        }
+        if(dataDst.getFirstChild() != null) {
+            result.appendChild(dataDst.getFirstChild());
+            return result;
+        } else {
+            return null;
+        }
+    }
+
     private static Document filtered(XmlElement filter, Document originalReplyDocument) throws DocumentedException {
         Document result = XmlUtil.newDocument();
         // even if filter is empty, copy /rpc/data
diff --git a/netconf/netconf-util/src/test/java/org/opendaylight/netconf/util/messages/SubtreeFilterNotificationTest.java b/netconf/netconf-util/src/test/java/org/opendaylight/netconf/util/messages/SubtreeFilterNotificationTest.java
new file mode 100644 (file)
index 0000000..ac7d83c
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2016 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.netconf.util.messages;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import com.google.common.base.Optional;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import org.custommonkey.xmlunit.Diff;
+import org.custommonkey.xmlunit.XMLUnit;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+@RunWith(value = Parameterized.class)
+public class SubtreeFilterNotificationTest {
+    private static final Logger LOG = LoggerFactory.getLogger(SubtreeFilterRpcTest.class);
+
+    private final int directoryIndex;
+
+    @Parameters
+    public static Collection<Object[]> data() {
+        List<Object[]> result = new ArrayList<>();
+        for (int i = 0; i < 5; i++) {
+            result.add(new Object[]{i});
+        }
+        return result;
+    }
+
+    public SubtreeFilterNotificationTest(int directoryIndex) {
+        this.directoryIndex = directoryIndex;
+    }
+
+    @Before
+    public void setUp(){
+        XMLUnit.setIgnoreWhitespace(true);
+    }
+
+    @Test
+    public void testFilterNotification() throws Exception {
+        XmlElement filter = XmlElement.fromDomDocument(getDocument("filter.xml"));
+        Document preFilterDocument = getDocument("pre-filter.xml");
+        Document postFilterDocument = getDocument("post-filter.xml");
+        Optional<Document> actualPostFilterDocumentOpt = SubtreeFilter.applySubtreeNotificationFilter(filter, preFilterDocument);
+        if(actualPostFilterDocumentOpt.isPresent()) {
+            Document actualPostFilterDocument = actualPostFilterDocumentOpt.get();
+            LOG.info("Actual document: {}", XmlUtil.toString(actualPostFilterDocument));
+            Diff diff = XMLUnit.compareXML(postFilterDocument, actualPostFilterDocument);
+            assertTrue(diff.toString(), diff.similar());
+        } else {
+            assertEquals("empty", XmlElement.fromDomDocument(postFilterDocument).getName());
+        }
+    }
+
+    public Document getDocument(String fileName) throws SAXException, IOException {
+        return XmlUtil.readXmlToDocument(getClass().getResourceAsStream("/subtree/notification/" + directoryIndex + "/" +
+                fileName));
+    }
+}
similarity index 86%
rename from netconf/netconf-impl/src/test/java/org/opendaylight/netconf/impl/SubtreeFilterTest.java
rename to netconf/netconf-util/src/test/java/org/opendaylight/netconf/util/messages/SubtreeFilterRpcTest.java
index 45ca8c3c36ba48bd31032d180c6fd151b73b2708..e486c75f2e0d8d6abc8f3e29ec4f420c212de433 100644 (file)
@@ -6,7 +6,7 @@
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
 
-package org.opendaylight.netconf.impl;
+package org.opendaylight.netconf.util.messages;
 
 import static org.junit.Assert.assertTrue;
 
@@ -28,8 +28,8 @@ import org.w3c.dom.Document;
 import org.xml.sax.SAXException;
 
 @RunWith(value = Parameterized.class)
-public class SubtreeFilterTest {
-    private static final Logger LOG = LoggerFactory.getLogger(SubtreeFilterTest.class);
+public class SubtreeFilterRpcTest {
+    private static final Logger LOG = LoggerFactory.getLogger(SubtreeFilterRpcTest.class);
 
     private final int directoryIndex;
 
@@ -42,7 +42,7 @@ public class SubtreeFilterTest {
         return result;
     }
 
-    public SubtreeFilterTest(int directoryIndex) {
+    public SubtreeFilterRpcTest(int directoryIndex) {
         this.directoryIndex = directoryIndex;
     }
 
@@ -56,7 +56,7 @@ public class SubtreeFilterTest {
         Document requestDocument = getDocument("request.xml");
         Document preFilterDocument = getDocument("pre-filter.xml");
         Document postFilterDocument = getDocument("post-filter.xml");
-        Document actualPostFilterDocument = SubtreeFilter.applySubtreeFilter(requestDocument, preFilterDocument);
+        Document actualPostFilterDocument = SubtreeFilter.applyRpcSubtreeFilter(requestDocument, preFilterDocument);
         LOG.info("Actual document: {}", XmlUtil.toString(actualPostFilterDocument));
         Diff diff = XMLUnit.compareXML(postFilterDocument, actualPostFilterDocument);
         assertTrue(diff.toString(), diff.similar());
@@ -64,7 +64,7 @@ public class SubtreeFilterTest {
     }
 
     public Document getDocument(String fileName) throws SAXException, IOException {
-        return XmlUtil.readXmlToDocument(getClass().getResourceAsStream("/subtree/" + directoryIndex + "/" +
+        return XmlUtil.readXmlToDocument(getClass().getResourceAsStream("/subtree/rpc/" + directoryIndex + "/" +
                 fileName));
     }
 }
diff --git a/netconf/netconf-util/src/test/resources/subtree/notification/0/filter.xml b/netconf/netconf-util/src/test/resources/subtree/notification/0/filter.xml
new file mode 100644 (file)
index 0000000..83b3fcb
--- /dev/null
@@ -0,0 +1,13 @@
+<!--
+  ~ Copyright (c) 2016 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
+  -->
+<filter xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0" type="subtree">
+    <netconf-session-end xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-notifications">
+        <username/>
+        <session-id/>
+    </netconf-session-end>
+</filter>
\ No newline at end of file
diff --git a/netconf/netconf-util/src/test/resources/subtree/notification/0/post-filter.xml b/netconf/netconf-util/src/test/resources/subtree/notification/0/post-filter.xml
new file mode 100644 (file)
index 0000000..9f1667a
--- /dev/null
@@ -0,0 +1,14 @@
+<!--
+  ~ Copyright (c) 2016 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
+  -->
+<netconf-session-end xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-notifications">
+    <username>admin</username>
+    <session-id>2</session-id>
+</netconf-session-end>
+
+
+
diff --git a/netconf/netconf-util/src/test/resources/subtree/notification/0/pre-filter.xml b/netconf/netconf-util/src/test/resources/subtree/notification/0/pre-filter.xml
new file mode 100644 (file)
index 0000000..af5368e
--- /dev/null
@@ -0,0 +1,15 @@
+<!--
+  ~ Copyright (c) 2016 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
+  -->
+<notification xmlns="urn:ietf:params:netconf:capability:notification:1.0">
+    <netconf-session-end xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-notifications">
+        <username>admin</username>
+        <session-id>2</session-id>
+        <source-host>127.0.0.1</source-host>
+    </netconf-session-end>
+    <eventTime>2016-03-17T13:15:12+01:00</eventTime>
+</notification>
diff --git a/netconf/netconf-util/src/test/resources/subtree/notification/1/filter.xml b/netconf/netconf-util/src/test/resources/subtree/notification/1/filter.xml
new file mode 100644 (file)
index 0000000..ca976c8
--- /dev/null
@@ -0,0 +1,13 @@
+<!--
+  ~ Copyright (c) 2016 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
+  -->
+<filter xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0" type="unsupported">
+    <netconf-session-end xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-notifications">
+        <username/>
+        <session-id/>
+    </netconf-session-end>
+</filter>
\ No newline at end of file
diff --git a/netconf/netconf-util/src/test/resources/subtree/notification/1/post-filter.xml b/netconf/netconf-util/src/test/resources/subtree/notification/1/post-filter.xml
new file mode 100644 (file)
index 0000000..92c9db8
--- /dev/null
@@ -0,0 +1,12 @@
+<!--
+  ~ Copyright (c) 2016 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
+  -->
+<netconf-session-end xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-notifications">
+    <username>admin</username>
+    <session-id>2</session-id>
+    <source-host>127.0.0.1</source-host>
+</netconf-session-end>
diff --git a/netconf/netconf-util/src/test/resources/subtree/notification/1/pre-filter.xml b/netconf/netconf-util/src/test/resources/subtree/notification/1/pre-filter.xml
new file mode 100644 (file)
index 0000000..af5368e
--- /dev/null
@@ -0,0 +1,15 @@
+<!--
+  ~ Copyright (c) 2016 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
+  -->
+<notification xmlns="urn:ietf:params:netconf:capability:notification:1.0">
+    <netconf-session-end xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-notifications">
+        <username>admin</username>
+        <session-id>2</session-id>
+        <source-host>127.0.0.1</source-host>
+    </netconf-session-end>
+    <eventTime>2016-03-17T13:15:12+01:00</eventTime>
+</notification>
diff --git a/netconf/netconf-util/src/test/resources/subtree/notification/2/filter.xml b/netconf/netconf-util/src/test/resources/subtree/notification/2/filter.xml
new file mode 100644 (file)
index 0000000..ca976c8
--- /dev/null
@@ -0,0 +1,13 @@
+<!--
+  ~ Copyright (c) 2016 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
+  -->
+<filter xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0" type="unsupported">
+    <netconf-session-end xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-notifications">
+        <username/>
+        <session-id/>
+    </netconf-session-end>
+</filter>
\ No newline at end of file
diff --git a/netconf/netconf-util/src/test/resources/subtree/notification/2/post-filter.xml b/netconf/netconf-util/src/test/resources/subtree/notification/2/post-filter.xml
new file mode 100644 (file)
index 0000000..3755dd4
--- /dev/null
@@ -0,0 +1,12 @@
+<!--
+  ~ Copyright (c) 2016 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
+  -->
+<netconf-session-start xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-notifications">
+    <username>admin</username>
+    <session-id>2</session-id>
+    <source-host>127.0.0.1</source-host>
+</netconf-session-start>
\ No newline at end of file
diff --git a/netconf/netconf-util/src/test/resources/subtree/notification/2/pre-filter.xml b/netconf/netconf-util/src/test/resources/subtree/notification/2/pre-filter.xml
new file mode 100644 (file)
index 0000000..66e7b56
--- /dev/null
@@ -0,0 +1,15 @@
+<!--
+  ~ Copyright (c) 2016 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
+  -->
+<notification xmlns="urn:ietf:params:netconf:capability:notification:1.0">
+    <netconf-session-start xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-notifications">
+        <username>admin</username>
+        <session-id>2</session-id>
+        <source-host>127.0.0.1</source-host>
+    </netconf-session-start>
+    <eventTime>2016-03-17T13:15:04+01:00</eventTime>
+</notification>
diff --git a/netconf/netconf-util/src/test/resources/subtree/notification/3/filter.xml b/netconf/netconf-util/src/test/resources/subtree/notification/3/filter.xml
new file mode 100644 (file)
index 0000000..83b3fcb
--- /dev/null
@@ -0,0 +1,13 @@
+<!--
+  ~ Copyright (c) 2016 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
+  -->
+<filter xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0" type="subtree">
+    <netconf-session-end xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-notifications">
+        <username/>
+        <session-id/>
+    </netconf-session-end>
+</filter>
\ No newline at end of file
diff --git a/netconf/netconf-util/src/test/resources/subtree/notification/3/post-filter.xml b/netconf/netconf-util/src/test/resources/subtree/notification/3/post-filter.xml
new file mode 100644 (file)
index 0000000..4c9b412
--- /dev/null
@@ -0,0 +1,8 @@
+<!--
+  ~ Copyright (c) 2016 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
+  -->
+<empty/>
\ No newline at end of file
diff --git a/netconf/netconf-util/src/test/resources/subtree/notification/3/pre-filter.xml b/netconf/netconf-util/src/test/resources/subtree/notification/3/pre-filter.xml
new file mode 100644 (file)
index 0000000..66e7b56
--- /dev/null
@@ -0,0 +1,15 @@
+<!--
+  ~ Copyright (c) 2016 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
+  -->
+<notification xmlns="urn:ietf:params:netconf:capability:notification:1.0">
+    <netconf-session-start xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-notifications">
+        <username>admin</username>
+        <session-id>2</session-id>
+        <source-host>127.0.0.1</source-host>
+    </netconf-session-start>
+    <eventTime>2016-03-17T13:15:04+01:00</eventTime>
+</notification>
diff --git a/netconf/netconf-util/src/test/resources/subtree/notification/4/filter.xml b/netconf/netconf-util/src/test/resources/subtree/notification/4/filter.xml
new file mode 100644 (file)
index 0000000..d8c908c
--- /dev/null
@@ -0,0 +1,10 @@
+<!--
+  ~ Copyright (c) 2016 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
+  -->
+<filter xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0" type="subtree">
+    <netconf-session-end xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-notifications"/>
+</filter>
\ No newline at end of file
diff --git a/netconf/netconf-util/src/test/resources/subtree/notification/4/post-filter.xml b/netconf/netconf-util/src/test/resources/subtree/notification/4/post-filter.xml
new file mode 100644 (file)
index 0000000..026f797
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<netconf-session-end xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-notifications">
+    <username>admin</username>
+    <session-id>2</session-id>
+    <source-host>127.0.0.1</source-host>
+</netconf-session-end>
\ No newline at end of file
diff --git a/netconf/netconf-util/src/test/resources/subtree/notification/4/pre-filter.xml b/netconf/netconf-util/src/test/resources/subtree/notification/4/pre-filter.xml
new file mode 100644 (file)
index 0000000..10f229d
--- /dev/null
@@ -0,0 +1,15 @@
+<!--
+  ~ Copyright (c) 2016 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
+  -->
+<notification xmlns="urn:ietf:params:netconf:capability:notification:1.0">
+    <netconf-session-end xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-notifications">
+        <username>admin</username>
+        <session-id>2</session-id>
+        <source-host>127.0.0.1</source-host>
+    </netconf-session-end>
+    <eventTime>2016-03-17T13:15:12+01:00</eventTime>
+</notification>
\ No newline at end of file
index bb63554d5491d356cc13a5072a8563b1fb75a2ea..1b8a820f4f04abd31673343b6a224179c0c37817 100644 (file)
@@ -143,7 +143,7 @@ public class NetconfDevice implements RemoteDevice<NetconfSessionPreferences, Ne
             }
 
             private void setUpSchema(final DeviceSources result) {
-                processingExecutor.submit(new RecursiveSchemaSetup(result, remoteSessionCapabilities, listener));
+                processingExecutor.submit(new SchemaSetup(result, remoteSessionCapabilities, listener));
             }
 
             @Override
@@ -372,13 +372,13 @@ public class NetconfDevice implements RemoteDevice<NetconfSessionPreferences, Ne
     /**
      * Schema builder that tries to build schema context from provided sources or biggest subset of it.
      */
-    private final class RecursiveSchemaSetup implements Runnable {
+    private final class SchemaSetup implements Runnable {
         private final DeviceSources deviceSources;
         private final NetconfSessionPreferences remoteSessionCapabilities;
         private final RemoteDeviceCommunicator<NetconfMessage> listener;
         private final NetconfDeviceCapabilities capabilities;
 
-        public RecursiveSchemaSetup(final DeviceSources deviceSources, final NetconfSessionPreferences remoteSessionCapabilities, final RemoteDeviceCommunicator<NetconfMessage> listener) {
+        public SchemaSetup(final DeviceSources deviceSources, final NetconfSessionPreferences remoteSessionCapabilities, final RemoteDeviceCommunicator<NetconfMessage> listener) {
             this.deviceSources = deviceSources;
             this.remoteSessionCapabilities = remoteSessionCapabilities;
             this.listener = listener;
@@ -391,37 +391,23 @@ public class NetconfDevice implements RemoteDevice<NetconfSessionPreferences, Ne
         }
 
         /**
-         * Recursively build schema context, in case of success or final failure notify device
+         * Build schema context, in case of success or final failure notify device
          */
-        // FIXME reimplement without recursion
-        private void setUpSchema(final Collection<SourceIdentifier> requiredSources) {
-            LOG.trace("{}: Trying to build schema context from {}", id, requiredSources);
-
-            // If no more sources, fail
-            if(requiredSources.isEmpty()) {
-                final IllegalStateException cause = new IllegalStateException(id + ": No more sources for schema context");
-                handleSalInitializationFailure(cause, listener);
-                salFacade.onDeviceFailed(cause);
-                return;
-            }
-
-            final CheckedFuture<SchemaContext, SchemaResolutionException> schemaBuilderFuture = schemaContextFactory.createSchemaContext(requiredSources);
-
-            final FutureCallback<SchemaContext> RecursiveSchemaBuilderCallback = new FutureCallback<SchemaContext>() {
-
-                @Override
-                public void onSuccess(final SchemaContext result) {
+        private void setUpSchema(Collection<SourceIdentifier> requiredSources) {
+            while (!requiredSources.isEmpty()) {
+                LOG.trace("{}: Trying to build schema context from {}", id, requiredSources);
+                try {
+                    final CheckedFuture<SchemaContext, SchemaResolutionException> schemaBuilderFuture = schemaContextFactory.createSchemaContext(requiredSources);
+                    final SchemaContext result = schemaBuilderFuture.checkedGet();
                     LOG.debug("{}: Schema context built successfully from {}", id, requiredSources);
                     final Collection<QName> filteredQNames = Sets.difference(deviceSources.getRequiredSourcesQName(), capabilities.getUnresolvedCapabilites().keySet());
                     capabilities.addCapabilities(filteredQNames);
                     capabilities.addNonModuleBasedCapabilities(remoteSessionCapabilities.getNonModuleCaps());
                     handleSalInitializationSuccess(result, remoteSessionCapabilities, getDeviceSpecificRpc(result));
-                }
-
-                @Override
-                public void onFailure(final Throwable t) {
-                    // In case source missing, try without it
-                    if (t instanceof MissingSchemaSourceException) {
+                    return;
+                } catch (Throwable t) {
+                    if (t instanceof MissingSchemaSourceException){
+                        // In case source missing, try without it
                         final SourceIdentifier missingSource = ((MissingSchemaSourceException) t).getSourceId();
                         LOG.warn("{}: Unable to build schema context, missing source {}, will reattempt without it", id, missingSource);
                         LOG.debug("{}: Unable to build schema context, missing source {}, will reattempt without it", t);
@@ -429,27 +415,29 @@ public class NetconfDevice implements RemoteDevice<NetconfSessionPreferences, Ne
                         if (!qNameOfMissingSource.isEmpty()) {
                             capabilities.addUnresolvedCapabilities(qNameOfMissingSource, UnavailableCapability.FailureReason.MissingSource);
                         }
-                        setUpSchema(stripMissingSource(requiredSources, missingSource));
-
-                    // In case resolution error, try only with resolved sources
+                        requiredSources = stripMissingSource(requiredSources, missingSource);
                     } else if (t instanceof SchemaResolutionException) {
-                        // TODO check for infinite loop
-                        final SchemaResolutionException resolutionException = (SchemaResolutionException) t;
+                        // In case resolution error, try only with resolved sources
+                        SchemaResolutionException resolutionException = (SchemaResolutionException) t;
                         final Set<SourceIdentifier> unresolvedSources = resolutionException.getUnsatisfiedImports().keySet();
                         capabilities.addUnresolvedCapabilities(getQNameFromSourceIdentifiers(unresolvedSources), UnavailableCapability.FailureReason.UnableToResolve);
                         LOG.warn("{}: Unable to build schema context, unsatisfied imports {}, will reattempt with resolved only", id, resolutionException.getUnsatisfiedImports());
                         LOG.debug("{}: Unable to build schema context, unsatisfied imports {}, will reattempt with resolved only", resolutionException);
-                        setUpSchema(resolutionException.getResolvedSources());
-                    // unknown error, fail
+                        requiredSources = resolutionException.getResolvedSources();
                     } else {
+                        // unknown error, fail
                         handleSalInitializationFailure(t, listener);
+                        return;
                     }
                 }
-            };
-
-            Futures.addCallback(schemaBuilderFuture, RecursiveSchemaBuilderCallback);
+            }
+            // No more sources, fail
+            final IllegalStateException cause = new IllegalStateException(id + ": No more sources for schema context");
+            handleSalInitializationFailure(cause, listener);
+            salFacade.onDeviceFailed(cause);
         }
 
+
         protected NetconfDeviceRpc getDeviceSpecificRpc(final SchemaContext result) {
             return new NetconfDeviceRpc(result, listener, new NetconfMessageTransformer(result, true));
         }
index 276ccd6b2b6ad97fa4ba1b26e919d047c524a2f6..e979071d873f3c7c2770c545cfa9cbfc65480cc9 100644 (file)
@@ -118,7 +118,6 @@ public class NetconfDeviceCommunicator implements NetconfClientSessionListener,
      * reconnecting strategy runs out of reconnection attempts
      */
     public ListenableFuture<NetconfDeviceCapabilities> initializeRemoteConnection(final NetconfClientDispatcher dispatcher, final NetconfClientConfiguration config) {
-        // TODO 2313 extract listener from configuration
         if(config instanceof NetconfReconnectingClientConfiguration) {
             initFuture = dispatcher.createReconnectingClient((NetconfReconnectingClientConfiguration) config);
         } else {
index 569f642130208795016994cd67f233b7b56f0c60..dc2b5dff427f3b40c12ebd5624b1a33151cabff3 100644 (file)
@@ -223,7 +223,7 @@ public final class KeepaliveSalFacade implements RemoteDeviceHandler<NetconfSess
 
         @Override
         public void onFailure(@Nonnull final Throwable t) {
-            // User/Application RPC failed (The RPC did not reach the remote device or .. TODO what other reasons could cause this ?)
+            // User/Application RPC failed (The RPC did not reach the remote device.
             // There is no point in keeping this session. Reconnect.
             LOG.warn("{}: Rpc failure detected. Reconnecting netconf session", id, t);
             reconnect();
index 27750c76eff4ad4b5011c70d6a52feee107ab824..d1282d09b45c58c82785e391a11059705c2c25da 100644 (file)
@@ -40,7 +40,6 @@ public final class NetconfDeviceRpc implements DOMRpcService {
     private static final Function<RpcDefinition, DOMRpcIdentifier> RPC_TO_RPC_IDENTIFIER = new Function<RpcDefinition, DOMRpcIdentifier>() {
         @Override
         public DOMRpcIdentifier apply(final RpcDefinition input) {
-            // TODO add support for routed rpcs ... is it necessary in this case ?
             return DOMRpcIdentifier.create(input.getPath());
         }
     };
index 02d1eebc9e95aff34be58ecb317caeebfc68dd09..3362f0607fd1ef1df21ea61c74f1d0e9cda868ba 100644 (file)
@@ -157,7 +157,6 @@ public final class NetconfBaseOps {
 
         final ListenableFuture<DOMRpcResult> future;
         if (isFilterPresent(filterPath)) {
-            // FIXME the source node has to be wrapped in a choice
             final DataContainerChild<?, ?> node = toFilterStructure(filterPath.get(), schemaContext);
             future = rpc.invokeRpc(toPath(NETCONF_GET_CONFIG_QNAME),
                             NetconfMessageTransformUtil.wrap(NETCONF_GET_CONFIG_QNAME, getSourceNode(datastore), node));
index 31b614766f58f187499ccaf7c674de1205a2181b..aee9c961ebf4082e3d24dfbb9936410d4c1ffac2 100644 (file)
               org.opendaylight.aaa.shiro.filters,
               org.opendaylight.aaa.shiro.realm,
               org.opendaylight.aaa.shiro.web.env,
+              org.opendaylight.aaa.filterchain.filters,
               org.apache.shiro.web.env
             </Import-Package>
             <Embed-Dependency>stax-utils</Embed-Dependency>
index 493572952598594c7cb32d0e80b3cab03c8ad461..6b801d7321307adc5cf70ea2f62c662933dc17a4 100644 (file)
         <url-pattern>/*</url-pattern>
     </filter-mapping>
 
+    <filter>
+        <filter-name>DynamicFilterChain</filter-name>
+        <filter-class>org.opendaylight.aaa.filterchain.filters.CustomFilterAdapter</filter-class>
+    </filter>
+
+    <filter-mapping>
+        <filter-name>DynamicFilterChain</filter-name>
+        <url-pattern>/*</url-pattern>
+    </filter-mapping>
+
+
     <servlet-mapping>
         <servlet-name>JAXRSRestconf</servlet-name>
         <url-pattern>/*</url-pattern>