Merge "Bug 3866: Support for Restconf HTTP Patch"
authorTomas Cere <tcere@cisco.com>
Mon, 11 Apr 2016 11:21:02 +0000 (11:21 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Mon, 11 Apr 2016 11:21:02 +0000 (11:21 +0000)
92 files changed:
features/netconf-connector/pom.xml
features/netconf/pom.xml
features/netconf/src/main/features/features.xml
netconf/mdsal-netconf-notification/src/main/java/org/opendaylight/netconf/mdsal/notification/NetconfNotificationOperationService.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-impl/src/main/java/org/opendaylight/netconf/impl/osgi/NetconfMonitoringServiceImpl.java
netconf/netconf-impl/src/test/java/org/opendaylight/netconf/impl/MessageHeaderTest.java [deleted file]
netconf/netconf-impl/src/test/java/org/opendaylight/netconf/impl/MessageParserTest.java
netconf/netconf-impl/src/test/java/org/opendaylight/netconf/impl/osgi/NetconfMonitoringServiceImplTest.java
netconf/netconf-notifications-api/src/main/java/org/opendaylight/netconf/notifications/NetconfNotification.java
netconf/netconf-notifications-impl/src/main/java/org/opendaylight/netconf/notifications/impl/ops/CreateSubscription.java
netconf/netconf-topology/pom.xml
netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/AbstractNetconfTopology.java
netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/impl/ClusteredNetconfTopology.java
netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/impl/NetconfTopologyImpl.java
netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/NetconfDeviceMasterDataBroker.java
netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/pipeline/TopologyMountPointFacade.java
netconf/netconf-topology/src/test/java/org/opendaylight/netconf/topology/AbstractNetconfTopologyTest.java
netconf/netconf-topology/src/test/java/org/opendaylight/netconf/topology/pipeline/TopologyMountPointFacadeTest.java
netconf/netconf-util/src/main/java/org/opendaylight/netconf/util/messages/NetconfMessageHeader.java [deleted file]
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/NetconfMessageHeaderTest.java [deleted file]
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/pom.xml
netconf/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModule.java
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/sal/KeepaliveSalFacade.java
netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceDataBroker.java
netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceSalFacade.java
netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/tx/AbstractWriteTx.java
netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/tx/ReadOnlyTx.java
netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/tx/WriteCandidateRunningTx.java
netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/tx/WriteCandidateTx.java
netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/tx/WriteRunningTx.java
netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/KeepaliveSalFacadeTest.java
netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceDataBrokerTest.java
netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/tx/NetconfDeviceWriteOnlyTxTest.java
netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/tx/ReadOnlyTxTest.java
netconf/tools/netconf-testtool/src/main/java/org/opendaylight/netconf/test/tool/client/http/perf/RestPerfClient.java
restconf/sal-rest-connector/pom.xml
restconf/sal-rest-connector/src/main/resources/WEB-INF/web.xml

index 9190706595d6bcb1316fa8d2eb77d8827ab16268..07ecb6137a62bfd9b78b2372c51eb9395a32d98b 100644 (file)
@@ -21,7 +21,6 @@
   <packaging>jar</packaging>
 
   <properties>
-    <aaa.version>0.4.0-SNAPSHOT</aaa.version>
     <commons.opendaylight.version>1.7.0-SNAPSHOT</commons.opendaylight.version>
     <controller.mdsal.version>1.4.0-SNAPSHOT</controller.mdsal.version>
     <config.version>0.5.0-SNAPSHOT</config.version>
       <classifier>features</classifier>
       <type>xml</type>
     </dependency>
-    <dependency>
-      <groupId>org.opendaylight.aaa</groupId>
-      <artifactId>features-aaa</artifactId>
-      <version>${aaa.version}</version>
-      <classifier>features</classifier>
-      <type>xml</type>
-    </dependency>
     <dependency>
       <groupId>${project.groupId}</groupId>
       <artifactId>sal-netconf-connector</artifactId>
index c8dbc730d4bc58082e1d1b6cfe0a7c6a38035a48..c82dc1c23a602530d8632f164a58a2cdfa38155c 100644 (file)
       <classifier>features</classifier>
       <type>xml</type>
     </dependency>
-    <dependency>
-      <groupId>org.opendaylight.aaa</groupId>
-      <artifactId>features-aaa</artifactId>
-      <classifier>features</classifier>
-      <type>xml</type>
-    </dependency>
     <dependency>
       <groupId>org.opendaylight.aaa</groupId>
       <artifactId>features-aaa-shiro</artifactId>
index e547e7572f68b48c52972af0e3dffd423143f13e..82920bcba169b4fba6542dcc8b78c13dca269413 100644 (file)
@@ -8,7 +8,7 @@
   <repository>mvn:org.opendaylight.controller/features-config/{{VERSION}}/xml/features</repository>
   <repository>mvn:org.opendaylight.controller/features-config-persister/{{VERSION}}/xml/features</repository>
   <repository>mvn:org.opendaylight.controller/features-config-netty/{{VERSION}}/xml/features</repository>
-  <repository>mvn:org.opendaylight.aaa/features-aaa/${aaa.version}/xml/features</repository>
+  <repository>mvn:org.opendaylight.aaa/features-aaa-shiro/${aaa.version}/xml/features</repository>
 
   <feature name='odl-netconf-all' version='${project.version}' description="OpenDaylight :: Netconf :: All">
     <feature version='${project.version}'>odl-netconf-api</feature>
            version='${project.version}'>
     <feature version='${config.version}'>odl-config-api</feature>
     <bundle>mvn:org.opendaylight.netconf/netconf-auth/{{VERSION}}</bundle>
-    <feature version='${aaa.version}'>odl-aaa-authn</feature>
+    <feature version='${aaa.version}'>odl-aaa-shiro</feature>
     <bundle>mvn:org.opendaylight.netconf/aaa-authn-odl-plugin/{{VERSION}}</bundle>
   </feature>
 
            version='${project.version}'>
     <feature version='${config.version}'>odl-config-api</feature>
     <bundle>mvn:org.opendaylight.netconf/netconf-auth/{{VERSION}}</bundle>
-    <feature version='${aaa.version}'>odl-aaa-authn-no-cluster</feature>
+    <feature version='${aaa.version}'>odl-aaa-shiro</feature>
     <bundle>mvn:org.opendaylight.netconf/aaa-authn-odl-plugin/{{VERSION}}</bundle>
   </feature>
 </features>
index 94678c9d5589158ea859fa459d4cc8aa48cdadd8..9824e1e57bd14744820119355f594ba8d51e8e6e 100644 (file)
@@ -30,6 +30,14 @@ public class NetconfNotificationOperationService implements NetconfOperationServ
 
     @Override
     public void close() {
-
+        for (NetconfOperation netconfOperation : netconfOperations) {
+            if (netconfOperation instanceof AutoCloseable) {
+                try {
+                    ((AutoCloseable) netconfOperation).close();
+                } catch (Exception e) {
+                    throw new IllegalStateException("Exception while closing " + netconfOperation, e);
+                }
+            }
+        }
     }
 }
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 f5249e4d12dcb62a563d40e454773f58fb99b2f8..27dbb67715c7e499b19f9796d4f6fb0a4572bedb 100644 (file)
@@ -73,6 +73,7 @@ public class NetconfMonitoringServiceImpl implements NetconfMonitoringService, A
     private final Set<NetconfManagementSession> sessions = new HashSet<>();
     private final NetconfOperationServiceFactory netconfOperationProvider;
     private final Map<Uri, Capability> capabilities = new HashMap<>();
+    private final Map<String, Map<String, String>> mappedModulesToRevisionToSchema = Maps.newHashMap();
 
     private final Set<MonitoringListener> listeners = Sets.newHashSet();
     private volatile BaseNotificationPublisherRegistration notificationPublisher;
@@ -117,33 +118,9 @@ public class NetconfMonitoringServiceImpl implements NetconfMonitoringService, A
     @Override
     public synchronized String getSchemaForCapability(final String moduleName, final Optional<String> revision) {
 
-        // FIXME not effective at all
-
-        Map<String, Map<String, String>> mappedModulesToRevisionToSchema = Maps.newHashMap();
-
-        final Collection<Capability> caps = capabilities.values();
-
-        for (Capability cap : caps) {
-            if (!cap.getModuleName().isPresent()
-                    || !cap.getRevision().isPresent()
-                    || !cap.getCapabilitySchema().isPresent()){
-                continue;
-            }
-
-            final String currentModuleName = cap.getModuleName().get();
-            Map<String, String> revisionMap = mappedModulesToRevisionToSchema.get(currentModuleName);
-            if (revisionMap == null) {
-                revisionMap = Maps.newHashMap();
-                mappedModulesToRevisionToSchema.put(currentModuleName, revisionMap);
-            }
-
-            String currentRevision = cap.getRevision().get();
-            revisionMap.put(currentRevision, cap.getCapabilitySchema().get());
-        }
-
         Map<String, String> revisionMapRequest = mappedModulesToRevisionToSchema.get(moduleName);
         Preconditions.checkState(revisionMapRequest != null, "Capability for module %s not present, " + ""
-                + "available modules : %s", moduleName, Collections2.transform(caps, CAPABILITY_TO_URI));
+                + "available modules : %s", moduleName, Collections2.transform(capabilities.values(), CAPABILITY_TO_URI));
 
         if (revision.isPresent()) {
             String schema = revisionMapRequest.get(revision.get());
@@ -161,6 +138,42 @@ public class NetconfMonitoringServiceImpl implements NetconfMonitoringService, A
         }
     }
 
+    private synchronized void updateCapabilityToSchemaMap(final Set<Capability> added, final Set<Capability> removed) {
+        for (final Capability cap : added) {
+            if (!isValidModuleCapability(cap)){
+                continue;
+            }
+
+            final String currentModuleName = cap.getModuleName().get();
+            Map<String, String> revisionMap = mappedModulesToRevisionToSchema.get(currentModuleName);
+            if (revisionMap == null) {
+                revisionMap = Maps.newHashMap();
+                mappedModulesToRevisionToSchema.put(currentModuleName, revisionMap);
+            }
+
+            final String currentRevision = cap.getRevision().get();
+            revisionMap.put(currentRevision, cap.getCapabilitySchema().get());
+        }
+        for (final Capability cap : removed) {
+            if (!isValidModuleCapability(cap)){
+                continue;
+            }
+            final Map<String, String> revisionMap = mappedModulesToRevisionToSchema.get(cap.getModuleName().get());
+            if (revisionMap != null) {
+                revisionMap.remove(cap.getRevision().get());
+                if (revisionMap.isEmpty()) {
+                    mappedModulesToRevisionToSchema.remove(cap.getModuleName().get());
+                }
+            }
+        }
+    }
+
+    private boolean isValidModuleCapability(Capability cap) {
+        return cap.getModuleName().isPresent()
+                && cap.getRevision().isPresent()
+                && cap.getCapabilitySchema().isPresent();
+    }
+
     @Override
     public synchronized Capabilities getCapabilities() {
         return new CapabilitiesBuilder().setCapability(Lists.newArrayList(capabilities.keySet())).build();
@@ -250,6 +263,7 @@ public class NetconfMonitoringServiceImpl implements NetconfMonitoringService, A
     public void onCapabilitiesChanged(Set<Capability> added, Set<Capability> removed) {
         onCapabilitiesAdded(added);
         onCapabilitiesRemoved(removed);
+        updateCapabilityToSchemaMap(added, removed);
         notifyListeners();
 
         // publish notification to notification collector about changed capabilities
diff --git a/netconf/netconf-impl/src/test/java/org/opendaylight/netconf/impl/MessageHeaderTest.java b/netconf/netconf-impl/src/test/java/org/opendaylight/netconf/impl/MessageHeaderTest.java
deleted file mode 100644 (file)
index 40ab00c..0000000
+++ /dev/null
@@ -1,32 +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.netconf.impl;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-
-import org.junit.Test;
-import org.opendaylight.netconf.util.messages.NetconfMessageHeader;
-
-@Deprecated
-public class MessageHeaderTest {
-    @Test
-    public void testFromBytes() {
-        final byte[] raw = new byte[] { (byte) 0x0a, (byte) 0x23, (byte) 0x35, (byte) 0x38, (byte) 0x0a };
-        NetconfMessageHeader header = NetconfMessageHeader.fromBytes(raw);
-        assertEquals(58, header.getLength());
-    }
-
-    @Test
-    public void testToBytes() {
-        NetconfMessageHeader header = new NetconfMessageHeader(123);
-        assertArrayEquals(new byte[] { (byte) 0x0a, (byte) 0x23, (byte) 0x31, (byte) 0x32, (byte) 0x33, (byte) 0x0a },
-                header.toBytes());
-    }
-}
index df34c45c5fc004f2f96b517fb1f7caaedbeff9fd..562d4a4ba993b4d307ca366e9e261a8f86f256a7 100644 (file)
@@ -15,12 +15,15 @@ import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
+import com.google.common.base.Charsets;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import io.netty.channel.embedded.EmbeddedChannel;
+import java.nio.ByteBuffer;
 import java.util.Queue;
 import org.junit.Before;
 import org.junit.Test;
+import org.opendaylight.netconf.api.NetconfMessage;
 import org.opendaylight.netconf.nettyutil.handler.ChunkedFramingMechanismEncoder;
 import org.opendaylight.netconf.nettyutil.handler.FramingMechanismHandlerFactory;
 import org.opendaylight.netconf.nettyutil.handler.NetconfChunkAggregator;
@@ -29,9 +32,7 @@ import org.opendaylight.netconf.nettyutil.handler.NetconfMessageToXMLEncoder;
 import org.opendaylight.netconf.nettyutil.handler.NetconfXMLToMessageDecoder;
 import org.opendaylight.netconf.util.messages.FramingMechanism;
 import org.opendaylight.netconf.util.messages.NetconfMessageConstants;
-import org.opendaylight.netconf.util.messages.NetconfMessageHeader;
 import org.opendaylight.netconf.util.test.XmlFileLoader;
-import org.opendaylight.netconf.api.NetconfMessage;
 
 public class MessageParserTest {
 
@@ -78,8 +79,7 @@ public class MessageParserTest {
             byte[] header = new byte[String.valueOf(exptHeaderLength).length()
                     + NetconfMessageConstants.MIN_HEADER_LENGTH - 1];
             recievedOutbound.getBytes(0, header);
-            NetconfMessageHeader messageHeader = NetconfMessageHeader.fromBytes(header);
-            assertEquals(exptHeaderLength, messageHeader.getLength());
+            assertEquals(exptHeaderLength, getHeaderLength(header));
 
             testChunkChannel.writeInbound(recievedOutbound);
         }
@@ -108,4 +108,10 @@ public class MessageParserTest {
         assertNotNull(receivedMessage);
         assertXMLEqual(this.msg.getDocument(), receivedMessage.getDocument());
     }
+
+    private static long getHeaderLength(byte[] bytes) {
+        byte[] HEADER_START = new byte[] { (byte) 0x0a, (byte) 0x23 };
+        return Long.parseLong(Charsets.US_ASCII.decode(
+                ByteBuffer.wrap(bytes, HEADER_START.length, bytes.length - HEADER_START.length - 1)).toString());
+    }
 }
index 3181030fee5e29a1ce145e44fc0a2f19edf569e2..6f1c91ceeb08c5a60f073a238b99346fe21bc164 100644 (file)
@@ -13,7 +13,7 @@ import static org.mockito.Mockito.doReturn;
 import com.google.common.base.Optional;
 import java.net.URI;
 import java.util.ArrayList;
-import java.util.Calendar;
+import java.util.Collections;
 import java.util.Date;
 import java.util.HashSet;
 import java.util.List;
@@ -21,6 +21,7 @@ import java.util.Set;
 import java.util.concurrent.atomic.AtomicInteger;
 import org.junit.Assert;
 import org.junit.Before;
+import org.junit.BeforeClass;
 import org.junit.Test;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
@@ -39,33 +40,41 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.mon
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas.Schema;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.sessions.SessionBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChange;
+import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
 import org.opendaylight.yangtools.yang.model.api.Module;
 
 public class NetconfMonitoringServiceImplTest {
 
     private static final String TEST_MODULE_CONTENT = "content";
+    private static final String TEST_MODULE_CONTENT2 = "content2";
     private static final String TEST_MODULE_REV = "1970-01-01";
+    private static final String TEST_MODULE_REV2 = "1970-01-02";
     private static final  Uri TEST_MODULE_NAMESPACE = new Uri("testModuleNamespace");
     private static final String TEST_MODULE_NAME = "testModule";
-    private static final Date TEST_MODULE_DATE;
+    private static Date TEST_MODULE_DATE;
+    private static Date TEST_MODULE_DATE2;
 
-    static {
-        Calendar calendar = Calendar.getInstance();
-        calendar.set(1970, Calendar.JANUARY, 1);
-        TEST_MODULE_DATE = calendar.getTime();
-    }
+    private YangModuleCapability moduleCapability1;
+    private YangModuleCapability moduleCapability2;
 
     private final Set<Capability> CAPABILITIES = new HashSet<>();
 
     private NetconfMonitoringServiceImpl monitoringService;
-
     @Mock
     private Module moduleMock;
     @Mock
+    private Module moduleMock2;
+    @Mock
     private NetconfOperationServiceFactory operationServiceFactoryMock;
     @Mock
     private NetconfManagementSession sessionMock;
 
+    @BeforeClass
+    public static void suiteSetUp() throws Exception {
+        TEST_MODULE_DATE = SimpleDateFormatUtil.getRevisionFormat().parse(TEST_MODULE_REV);
+        TEST_MODULE_DATE2= SimpleDateFormatUtil.getRevisionFormat().parse(TEST_MODULE_REV2);
+    }
+
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
@@ -75,14 +84,20 @@ public class NetconfMonitoringServiceImplTest {
         doReturn(new URI(TEST_MODULE_NAMESPACE.getValue())).when(moduleMock).getNamespace();
         doReturn(TEST_MODULE_NAME).when(moduleMock).getName();
         doReturn(TEST_MODULE_DATE).when(moduleMock).getRevision();
-        doReturn(TEST_MODULE_NAME).when(moduleMock).getName();
+        moduleCapability1 = new YangModuleCapability(moduleMock, TEST_MODULE_CONTENT);
+
+        CAPABILITIES.add(moduleCapability1);
+
+        doReturn(new URI(TEST_MODULE_NAMESPACE.getValue())).when(moduleMock2).getNamespace();
+        doReturn(TEST_MODULE_NAME).when(moduleMock2).getName();
+        doReturn(TEST_MODULE_DATE2).when(moduleMock2).getRevision();
+        moduleCapability2 = new YangModuleCapability(moduleMock2, TEST_MODULE_CONTENT2);
 
-        CAPABILITIES.add(new YangModuleCapability(moduleMock, TEST_MODULE_CONTENT));
         doReturn(CAPABILITIES).when(operationServiceFactoryMock).getCapabilities();
         doReturn(null).when(operationServiceFactoryMock).registerCapabilityListener(any(NetconfMonitoringServiceImpl.class));
 
         monitoringService = new NetconfMonitoringServiceImpl(operationServiceFactoryMock);
-        monitoringService.onCapabilitiesChanged(CAPABILITIES, new HashSet<Capability>());
+        monitoringService.onCapabilitiesChanged(CAPABILITIES, Collections.emptySet());
 
         doReturn(new SessionBuilder().build()).when(sessionMock).toManagementSession();
     }
@@ -115,9 +130,17 @@ public class NetconfMonitoringServiceImplTest {
 
     @Test
     public void testGetSchemaForCapability() throws Exception {
-        String schema = monitoringService.getSchemaForCapability(TEST_MODULE_NAME, Optional.of(TEST_MODULE_REV));
+        //test multiple revisions of the same capability
+        monitoringService.onCapabilitiesChanged(Collections.singleton(moduleCapability2), Collections.emptySet());
+        final String schema = monitoringService.getSchemaForCapability(TEST_MODULE_NAME, Optional.of(TEST_MODULE_REV));
         Assert.assertEquals(TEST_MODULE_CONTENT, schema);
-
+        final String schema2 = monitoringService.getSchemaForCapability(TEST_MODULE_NAME, Optional.of(TEST_MODULE_REV2));
+        Assert.assertEquals(TEST_MODULE_CONTENT2, schema2);
+        //remove one revision
+        monitoringService.onCapabilitiesChanged(Collections.emptySet(), Collections.singleton(moduleCapability1));
+        //only one revision present
+        final String schema3 = monitoringService.getSchemaForCapability(TEST_MODULE_NAME, Optional.absent());
+        Assert.assertEquals(TEST_MODULE_CONTENT2, schema3);
     }
 
     @Test
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 559dbb2492627aa705a487ca8b67017604dfae8e..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;
@@ -58,9 +60,7 @@ public class CreateSubscription extends AbstractSingletonNetconfOperation implem
         // 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");
@@ -79,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());
@@ -116,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 41184f7d090f385355c73e099a6506c0115111ab..08b0dbac789e73e428b08abf8e7614ad7dd73742 100644 (file)
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>yang-parser-impl</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.opendaylight.controller</groupId>
-            <artifactId>yang-jmx-generator-plugin</artifactId>
-        </dependency>
         <dependency>
             <groupId>org.opendaylight.netconf</groupId>
             <artifactId>sal-netconf-connector</artifactId>
index bfc919e5955d81740f0c8090387fa50164e76906..7a0d0f7dbb9527e060e304e0739b13e61d1440d4 100644 (file)
@@ -266,11 +266,11 @@ public abstract class AbstractNetconfTopology implements NetconfTopology, Bindin
         RemoteDeviceId remoteDeviceId = new RemoteDeviceId(nodeId.getValue(), address);
 
         RemoteDeviceHandler<NetconfSessionPreferences> salFacade =
-                createSalFacade(remoteDeviceId, domBroker, bindingAwareBroker, defaultRequestTimeoutMillis);
+                createSalFacade(remoteDeviceId, domBroker, bindingAwareBroker);
 
         if (keepaliveDelay > 0) {
             LOG.warn("Adding keepalive facade, for device {}", nodeId);
-            salFacade = new KeepaliveSalFacade(remoteDeviceId, salFacade, keepaliveExecutor.getExecutor(), keepaliveDelay);
+            salFacade = new KeepaliveSalFacade(remoteDeviceId, salFacade, keepaliveExecutor.getExecutor(), keepaliveDelay, defaultRequestTimeoutMillis);
         }
 
         final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO = setupSchemaCacheDTO(nodeId, node);
@@ -393,7 +393,7 @@ public abstract class AbstractNetconfTopology implements NetconfTopology, Bindin
                 .build();
     }
 
-    protected abstract RemoteDeviceHandler<NetconfSessionPreferences> createSalFacade(final RemoteDeviceId id, final Broker domBroker, final BindingAwareBroker bindingBroker, long defaultRequestTimeoutMillis);
+    protected abstract RemoteDeviceHandler<NetconfSessionPreferences> createSalFacade(final RemoteDeviceId id, final Broker domBroker, final BindingAwareBroker bindingBroker);
 
     @Override
     public abstract ConnectionStatusListenerRegistration registerConnectionStatusListener(NodeId node, RemoteDeviceHandler<NetconfSessionPreferences> listener);
index 04c95b49aaf49e0074858f10b5d3cd8adcb5ef4b..1612c7d9fccb23af2e7238145a91d232bc722772 100644 (file)
@@ -149,11 +149,11 @@ public class ClusteredNetconfTopology extends AbstractNetconfTopology implements
         RemoteDeviceId remoteDeviceId = new RemoteDeviceId(nodeId.getValue(), address);
 
         RemoteDeviceHandler<NetconfSessionPreferences> salFacade =
-                createSalFacade(remoteDeviceId, domBroker, bindingAwareBroker, defaultRequestTimeoutMillis);
+                createSalFacade(remoteDeviceId, domBroker, bindingAwareBroker);
 
         if (keepaliveDelay > 0) {
             LOG.warn("Adding keepalive facade, for device {}", nodeId);
-            salFacade = new KeepaliveSalFacade(remoteDeviceId, salFacade, keepaliveExecutor.getExecutor(), keepaliveDelay);
+            salFacade = new KeepaliveSalFacade(remoteDeviceId, salFacade, keepaliveExecutor.getExecutor(), keepaliveDelay, defaultRequestTimeoutMillis);
         }
 
         final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO = setupSchemaCacheDTO(nodeId, node);
@@ -165,8 +165,8 @@ public class ClusteredNetconfTopology extends AbstractNetconfTopology implements
     }
 
     @Override
-    protected RemoteDeviceHandler<NetconfSessionPreferences> createSalFacade(final RemoteDeviceId id, final Broker domBroker, final BindingAwareBroker bindingBroker, long defaultRequestTimeoutMillis) {
-        return new TopologyMountPointFacade(topologyId, id, domBroker, bindingBroker, defaultRequestTimeoutMillis);
+    protected RemoteDeviceHandler<NetconfSessionPreferences> createSalFacade(final RemoteDeviceId id, final Broker domBroker, final BindingAwareBroker bindingBroker) {
+        return new TopologyMountPointFacade(topologyId, id, domBroker, bindingBroker);
     }
 
     @Override
index 33b468ce2bc700edb0e70f0df076328677c66d8e..c1e41189e3353a05dac9aa010cd1ec855ef2f6c8 100644 (file)
@@ -80,8 +80,8 @@ public class NetconfTopologyImpl extends AbstractNetconfTopology implements Data
     }
 
     @Override
-    protected RemoteDeviceHandler<NetconfSessionPreferences> createSalFacade(RemoteDeviceId id, Broker domBroker, BindingAwareBroker bindingBroker, long defaultRequestTimeoutMillis) {
-        return new NetconfDeviceSalFacade(id, domBroker, bindingAwareBroker, defaultRequestTimeoutMillis);
+    protected RemoteDeviceHandler<NetconfSessionPreferences> createSalFacade(RemoteDeviceId id, Broker domBroker, BindingAwareBroker bindingBroker) {
+        return new NetconfDeviceSalFacade(id, domBroker, bindingAwareBroker);
     }
 
     @Override
index f210820ccdf71a886f0fb0203dae12e22572e254..dc292d33ebb47fe2c1a4c4a3d0b61e9ff81b7a44 100644 (file)
@@ -57,9 +57,9 @@ public class NetconfDeviceMasterDataBroker implements ProxyNetconfDeviceDataBrok
 
     public NetconfDeviceMasterDataBroker(final ActorSystem actorSystem, final RemoteDeviceId id,
                                          final SchemaContext schemaContext, final DOMRpcService rpc,
-                                         final NetconfSessionPreferences netconfSessionPreferences, final long requestTimeoutMillis) {
+                                         final NetconfSessionPreferences netconfSessionPreferences) {
         this.id = id;
-        delegateBroker = new NetconfDeviceDataBroker(id, schemaContext, rpc, netconfSessionPreferences, requestTimeoutMillis);
+        delegateBroker = new NetconfDeviceDataBroker(id, schemaContext, rpc, netconfSessionPreferences);
         this.actorSystem = actorSystem;
 
         // only ever need 1 readTx since it doesnt need to be closed
index 269db6907bc987757b3f642966434cf343bdec11..c79627be5a86ceb86d74dd5fb75e222b82c349f6 100644 (file)
@@ -43,7 +43,6 @@ public class TopologyMountPointFacade implements AutoCloseable, RemoteDeviceHand
     private final RemoteDeviceId id;
     private final Broker domBroker;
     private final BindingAwareBroker bindingBroker;
-    private final long defaultRequestTimeoutMillis;
 
     private SchemaContext remoteSchemaContext = null;
     private NetconfSessionPreferences netconfSessionPreferences = null;
@@ -58,13 +57,11 @@ public class TopologyMountPointFacade implements AutoCloseable, RemoteDeviceHand
     public TopologyMountPointFacade(final String topologyId,
                                     final RemoteDeviceId id,
                                     final Broker domBroker,
-                                    final BindingAwareBroker bindingBroker,
-                                    long defaultRequestTimeoutMillis) {
+                                    final BindingAwareBroker bindingBroker) {
         this.topologyId = topologyId;
         this.id = id;
         this.domBroker = domBroker;
         this.bindingBroker = bindingBroker;
-        this.defaultRequestTimeoutMillis = defaultRequestTimeoutMillis;
         this.salProvider = new ClusteredNetconfDeviceMountInstanceProxy(id);
         registerToSal(domBroker);
     }
@@ -124,7 +121,7 @@ public class TopologyMountPointFacade implements AutoCloseable, RemoteDeviceHand
         deviceDataBroker = TypedActor.get(context).typedActorOf(new TypedProps<>(ProxyNetconfDeviceDataBroker.class, new Creator<NetconfDeviceMasterDataBroker>() {
             @Override
             public NetconfDeviceMasterDataBroker create() throws Exception {
-                return new NetconfDeviceMasterDataBroker(actorSystem, id, remoteSchemaContext, deviceRpc, netconfSessionPreferences, defaultRequestTimeoutMillis);
+                return new NetconfDeviceMasterDataBroker(actorSystem, id, remoteSchemaContext, deviceRpc, netconfSessionPreferences);
             }
         }), MOUNT_POINT);
         LOG.debug("Master data broker registered on path {}", TypedActor.get(actorSystem).getActorRefFor(deviceDataBroker).path());
index a29d95eb1a4c7c14cc69f20a691484b29396d255..2e16cca1cb51e9b53e22b84191988e95d4782fed 100644 (file)
@@ -287,7 +287,7 @@ public class AbstractNetconfTopologyTest {
         }
 
         @Override
-        protected RemoteDeviceHandler<NetconfSessionPreferences> createSalFacade(RemoteDeviceId id, Broker domBroker, BindingAwareBroker bindingBroker, long defaultRequestTimeoutMillis) {
+        protected RemoteDeviceHandler<NetconfSessionPreferences> createSalFacade(RemoteDeviceId id, Broker domBroker, BindingAwareBroker bindingBroker) {
             return salFacade;
         }
 
index 2b4b37418a3da7b0bc698b6ad07c19378f3049d8..68342a56e5da0f028f33d73a86daef4f9a13a081 100644 (file)
@@ -48,7 +48,7 @@ public class TopologyMountPointFacadeTest {
 
         MockitoAnnotations.initMocks(this);
 
-        mountPointFacade = new TopologyMountPointFacade(TOPOLOGY_ID, REMOTE_DEVICE_ID, domBroker, bindingBroker, 1L);
+        mountPointFacade = new TopologyMountPointFacade(TOPOLOGY_ID, REMOTE_DEVICE_ID, domBroker, bindingBroker);
 
         mountPointFacade.registerConnectionStatusListener(connectionStatusListener1);
         mountPointFacade.registerConnectionStatusListener(connectionStatusListener2);
diff --git a/netconf/netconf-util/src/main/java/org/opendaylight/netconf/util/messages/NetconfMessageHeader.java b/netconf/netconf-util/src/main/java/org/opendaylight/netconf/util/messages/NetconfMessageHeader.java
deleted file mode 100644 (file)
index 8a425c2..0000000
+++ /dev/null
@@ -1,59 +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.netconf.util.messages;
-
-import com.google.common.base.Charsets;
-import com.google.common.base.Preconditions;
-import java.nio.ByteBuffer;
-
-/**
- * Netconf message header is used only when chunked framing mechanism is
- * supported. The header consists of only the length field.
- */
-@Deprecated
-public final class NetconfMessageHeader {
-    // \n#<length>\n
-    private static final byte[] HEADER_START = new byte[] { (byte) 0x0a, (byte) 0x23 };
-    private static final byte HEADER_END = (byte) 0x0a;
-    private final long length;
-
-    public NetconfMessageHeader(final long length) {
-        Preconditions.checkArgument(length < Integer.MAX_VALUE && length > 0);
-        this.length = length;
-    }
-
-    public byte[] toBytes() {
-        return toBytes(this.length);
-    }
-
-    // FIXME: improve precision to long
-    public int getLength() {
-        return (int) this.length;
-    }
-
-    public static NetconfMessageHeader fromBytes(final byte[] bytes) {
-        // the length is variable therefore bytes between headerBegin and
-        // headerEnd mark the length
-        // the length should be only numbers and therefore easily parsed with
-        // ASCII
-        long length = Long.parseLong(Charsets.US_ASCII.decode(
-                ByteBuffer.wrap(bytes, HEADER_START.length, bytes.length - HEADER_START.length - 1)).toString());
-
-        return new NetconfMessageHeader(length);
-    }
-
-    public static byte[] toBytes(final long length) {
-        final byte[] l = String.valueOf(length).getBytes(Charsets.US_ASCII);
-        final byte[] h = new byte[HEADER_START.length + l.length + 1];
-        System.arraycopy(HEADER_START, 0, h, 0, HEADER_START.length);
-        System.arraycopy(l, 0, h, HEADER_START.length, l.length);
-        System.arraycopy(new byte[] { HEADER_END }, 0, h, HEADER_START.length + l.length, 1);
-        return h;
-    }
-}
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/NetconfMessageHeaderTest.java b/netconf/netconf-util/src/test/java/org/opendaylight/netconf/util/messages/NetconfMessageHeaderTest.java
deleted file mode 100644 (file)
index 1c09b95..0000000
+++ /dev/null
@@ -1,27 +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.netconf.util.messages;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-
-import com.google.common.base.Charsets;
-import org.junit.Test;
-
-@Deprecated
-public class NetconfMessageHeaderTest {
-    @Test
-    public void testGet() throws Exception {
-        NetconfMessageHeader header = new NetconfMessageHeader(10);
-        assertEquals(header.getLength(), 10);
-
-        byte[] expectedValue = "\n#10\n".getBytes(Charsets.US_ASCII);
-        assertArrayEquals(expectedValue, header.toBytes());
-    }
-}
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 ee1640e33d0a3f904c3715b6ea06b39e6df6eeef..40fe3b2f70a17303d8138ac24e84a130ecde168f 100644 (file)
       <groupId>org.hamcrest</groupId>
       <artifactId>hamcrest-core</artifactId>
     </dependency>
-    <dependency>
-      <groupId>org.powermock</groupId>
-      <artifactId>powermock-api-mockito</artifactId>
-      <version>1.6.4</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.powermock</groupId>
-      <artifactId>powermock-module-junit4</artifactId>
-      <version>1.6.4</version>
-      <scope>test</scope>
-    </dependency>
   </dependencies>
 
   <scm>
index 785be9954d3e038b3f2cb7655180584a2b88c564..d7222c1bb26beb1ce03bb3acdded9a35d65003f8 100644 (file)
@@ -192,14 +192,14 @@ public final class NetconfConnectorModule extends org.opendaylight.controller.co
         final ExecutorService globalProcessingExecutor = processingExecutor.getExecutor();
 
         RemoteDeviceHandler<NetconfSessionPreferences> salFacade
-                = new NetconfDeviceSalFacade(id, domRegistry, bindingRegistry, getDefaultRequestTimeoutMillis());
+                = new NetconfDeviceSalFacade(id, domRegistry, bindingRegistry);
 
         final Long keepaliveDelay = getKeepaliveDelay();
         if (shouldSendKeepalive()) {
             // Keepalive executor is optional for now and a default instance is supported
             final ScheduledExecutorService executor = keepaliveExecutor == null ? DEFAULT_KEEPALIVE_EXECUTOR : keepaliveExecutor.getExecutor();
 
-            salFacade = new KeepaliveSalFacade(id, salFacade, executor, keepaliveDelay);
+            salFacade = new KeepaliveSalFacade(id, salFacade, executor, keepaliveDelay, getDefaultRequestTimeoutMillis());
         }
 
         // Setup information related to the SchemaRegistry, SchemaResourceFactory, etc.
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 dc2b5dff427f3b40c12ebd5624b1a33151cabff3..c450ac68fecd83c40d8eff6c306e30d02e6b35c1 100644 (file)
@@ -51,28 +51,33 @@ public final class KeepaliveSalFacade implements RemoteDeviceHandler<NetconfSess
     // 2 minutes keepalive delay by default
     private static final long DEFAULT_DELAY = TimeUnit.MINUTES.toSeconds(2);
 
+    // 1 minute transaction timeout by default
+    private static final long DEFAULT_TRANSACTION_TIMEOUT_MILLI = TimeUnit.MILLISECONDS.toMillis(60000);
+
     private final RemoteDeviceId id;
     private final RemoteDeviceHandler<NetconfSessionPreferences> salFacade;
     private final ScheduledExecutorService executor;
     private final long keepaliveDelaySeconds;
     private final ResetKeepalive resetKeepaliveTask;
+    private final long defaultRequestTimeoutMillis;
 
     private volatile NetconfDeviceCommunicator listener;
     private volatile ScheduledFuture<?> currentKeepalive;
     private volatile DOMRpcService currentDeviceRpc;
 
     public KeepaliveSalFacade(final RemoteDeviceId id, final RemoteDeviceHandler<NetconfSessionPreferences> salFacade,
-                              final ScheduledExecutorService executor, final long keepaliveDelaySeconds) {
+                              final ScheduledExecutorService executor, final long keepaliveDelaySeconds, final long defaultRequestTimeoutMillis) {
         this.id = id;
         this.salFacade = salFacade;
         this.executor = executor;
         this.keepaliveDelaySeconds = keepaliveDelaySeconds;
+        this.defaultRequestTimeoutMillis = defaultRequestTimeoutMillis;
         this.resetKeepaliveTask = new ResetKeepalive();
     }
 
     public KeepaliveSalFacade(final RemoteDeviceId id, final RemoteDeviceHandler<NetconfSessionPreferences> salFacade,
                               final ScheduledExecutorService executor) {
-        this(id, salFacade, executor, DEFAULT_DELAY);
+        this(id, salFacade, executor, DEFAULT_DELAY, DEFAULT_TRANSACTION_TIMEOUT_MILLI);
     }
 
     /**
@@ -118,7 +123,7 @@ public final class KeepaliveSalFacade implements RemoteDeviceHandler<NetconfSess
     @Override
     public void onDeviceConnected(final SchemaContext remoteSchemaContext, final NetconfSessionPreferences netconfSessionPreferences, final DOMRpcService deviceRpc) {
         this.currentDeviceRpc = deviceRpc;
-        final DOMRpcService deviceRpc1 = new KeepaliveDOMRpcService(deviceRpc, resetKeepaliveTask);
+        final DOMRpcService deviceRpc1 = new KeepaliveDOMRpcService(deviceRpc, resetKeepaliveTask, defaultRequestTimeoutMillis, executor);
         salFacade.onDeviceConnected(remoteSchemaContext, netconfSessionPreferences, deviceRpc1);
 
         LOG.debug("{}: Netconf session initiated, starting keepalives", id);
@@ -214,7 +219,7 @@ public final class KeepaliveSalFacade implements RemoteDeviceHandler<NetconfSess
     /**
      * Reset keepalive after each RPC response received
      */
-    private class ResetKeepalive implements com.google.common.util.concurrent.FutureCallback<DOMRpcResult> {
+    private class ResetKeepalive implements FutureCallback<DOMRpcResult> {
         @Override
         public void onSuccess(@Nullable final DOMRpcResult result) {
             // No matter what response we got, rpc-reply or rpc-error, we got it from device so the netconf session is OK
@@ -223,24 +228,51 @@ 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.
+            // User/Application RPC failed (The RPC did not reach the remote device or .. TODO what other reasons could cause this ?)
             // There is no point in keeping this session. Reconnect.
             LOG.warn("{}: Rpc failure detected. Reconnecting netconf session", id, t);
             reconnect();
         }
     }
 
+    /*
+     * Request timeout task is called once the defaultRequestTimeoutMillis is
+     * reached. At this moment, if the request is not yet finished, we cancel
+     * it.
+     */
+    private static final class RequestTimeoutTask implements Runnable {
+
+        private final CheckedFuture<DOMRpcResult, DOMRpcException> rpcResultFuture;
+
+        public RequestTimeoutTask(final CheckedFuture<DOMRpcResult, DOMRpcException> rpcResultFuture) {
+            this.rpcResultFuture = rpcResultFuture;
+        }
+
+        @Override
+        public void run() {
+            if (!rpcResultFuture.isDone()) {
+                rpcResultFuture.cancel(true);
+            }
+        }
+    }
+
     /**
-     * DOMRpcService proxy that attaches reset-keepalive-task to each RPC invocation.
+     * DOMRpcService proxy that attaches reset-keepalive-task and schedule
+     * request-timeout-task to each RPC invocation.
      */
     private static final class KeepaliveDOMRpcService implements DOMRpcService {
 
         private final DOMRpcService deviceRpc;
         private ResetKeepalive resetKeepaliveTask;
+        private final long defaultRequestTimeoutMillis;
+        private final ScheduledExecutorService executor;
 
-        public KeepaliveDOMRpcService(final DOMRpcService deviceRpc, final ResetKeepalive resetKeepaliveTask) {
+        public KeepaliveDOMRpcService(final DOMRpcService deviceRpc, final ResetKeepalive resetKeepaliveTask,
+                final long defaultRequestTimeoutMillis, final ScheduledExecutorService executor) {
             this.deviceRpc = deviceRpc;
             this.resetKeepaliveTask = resetKeepaliveTask;
+            this.defaultRequestTimeoutMillis = defaultRequestTimeoutMillis;
+            this.executor = executor;
         }
 
         @Nonnull
@@ -248,6 +280,10 @@ public final class KeepaliveSalFacade implements RemoteDeviceHandler<NetconfSess
         public CheckedFuture<DOMRpcResult, DOMRpcException> invokeRpc(@Nonnull final SchemaPath type, final NormalizedNode<?, ?> input) {
             final CheckedFuture<DOMRpcResult, DOMRpcException> domRpcResultDOMRpcExceptionCheckedFuture = deviceRpc.invokeRpc(type, input);
             Futures.addCallback(domRpcResultDOMRpcExceptionCheckedFuture, resetKeepaliveTask);
+
+            final RequestTimeoutTask timeoutTask = new RequestTimeoutTask(domRpcResultDOMRpcExceptionCheckedFuture);
+            executor.schedule(timeoutTask, defaultRequestTimeoutMillis, TimeUnit.MILLISECONDS);
+
             return domRpcResultDOMRpcExceptionCheckedFuture;
         }
 
index 7283cae9b85b9446a8e6b284e465f18ba7fb54c2..421e52da71978af327083e7f39b83aa3262015a7 100644 (file)
@@ -36,16 +36,14 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 public final class NetconfDeviceDataBroker implements DOMDataBroker {
     private final RemoteDeviceId id;
     private final NetconfBaseOps netconfOps;
-    private final long requestTimeoutMillis;
 
     private final boolean rollbackSupport;
     private boolean candidateSupported;
     private boolean runningWritable;
 
-    public NetconfDeviceDataBroker(final RemoteDeviceId id, final SchemaContext schemaContext, final DOMRpcService rpc, final NetconfSessionPreferences netconfSessionPreferences, long requestTimeoutMillis) {
+    public NetconfDeviceDataBroker(final RemoteDeviceId id, final SchemaContext schemaContext, final DOMRpcService rpc, final NetconfSessionPreferences netconfSessionPreferences) {
         this.id = id;
         this.netconfOps = new NetconfBaseOps(rpc, schemaContext);
-        this.requestTimeoutMillis = requestTimeoutMillis;
         // get specific attributes from netconf preferences and get rid of it
         // no need to keep the entire preferences object, its quite big with all the capability QNames
         candidateSupported = netconfSessionPreferences.isCandidateSupported();
@@ -57,7 +55,7 @@ public final class NetconfDeviceDataBroker implements DOMDataBroker {
 
     @Override
     public DOMDataReadOnlyTransaction newReadOnlyTransaction() {
-        return new ReadOnlyTx(netconfOps, id, requestTimeoutMillis);
+        return new ReadOnlyTx(netconfOps, id);
     }
 
     @Override
@@ -69,12 +67,12 @@ public final class NetconfDeviceDataBroker implements DOMDataBroker {
     public DOMDataWriteTransaction newWriteOnlyTransaction() {
         if(candidateSupported) {
             if(runningWritable) {
-                return new WriteCandidateRunningTx(id, netconfOps, rollbackSupport, requestTimeoutMillis);
+                return new WriteCandidateRunningTx(id, netconfOps, rollbackSupport);
             } else {
-                return new WriteCandidateTx(id, netconfOps, rollbackSupport, requestTimeoutMillis);
+                return new WriteCandidateTx(id, netconfOps, rollbackSupport);
             }
         } else {
-            return new WriteRunningTx(id, netconfOps, rollbackSupport, requestTimeoutMillis);
+            return new WriteRunningTx(id, netconfOps, rollbackSupport);
         }
     }
 
index 7bb3df08a5ef6644028be5fcd162145b361dd1db..2a817db7eca43ebfeef77ab7d57fd28f1c74ad7e 100644 (file)
@@ -30,14 +30,12 @@ public final class NetconfDeviceSalFacade implements AutoCloseable, RemoteDevice
 
     private final RemoteDeviceId id;
     private final NetconfDeviceSalProvider salProvider;
-    private final long defaultRequestTimeoutMillis;
 
     private final List<AutoCloseable> salRegistrations = Lists.newArrayList();
 
-    public NetconfDeviceSalFacade(final RemoteDeviceId id, final Broker domBroker, final BindingAwareBroker bindingBroker, long defaultRequestTimeoutMillis) {
+    public NetconfDeviceSalFacade(final RemoteDeviceId id, final Broker domBroker, final BindingAwareBroker bindingBroker) {
         this.id = id;
         this.salProvider = new NetconfDeviceSalProvider(id);
-        this.defaultRequestTimeoutMillis = defaultRequestTimeoutMillis;
         registerToSal(domBroker, bindingBroker);
     }
 
@@ -55,7 +53,7 @@ public final class NetconfDeviceSalFacade implements AutoCloseable, RemoteDevice
     public synchronized void onDeviceConnected(final SchemaContext schemaContext,
                                                final NetconfSessionPreferences netconfSessionPreferences, final DOMRpcService deviceRpc) {
 
-        final DOMDataBroker domBroker = new NetconfDeviceDataBroker(id, schemaContext, deviceRpc, netconfSessionPreferences, defaultRequestTimeoutMillis);
+        final DOMDataBroker domBroker = new NetconfDeviceDataBroker(id, schemaContext, deviceRpc, netconfSessionPreferences);
 
         final NetconfDeviceNotificationService notificationService = new NetconfDeviceNotificationService();
 
index a12ba3a02abbc5b0a920fe03af58428c8d47b3a2..3aeff93da40082c2a4405b5213a759a434890360 100644 (file)
@@ -11,11 +11,8 @@ package org.opendaylight.netconf.sal.connect.netconf.sal.tx;
 import com.google.common.base.Function;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
@@ -29,7 +26,6 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
 import org.opendaylight.yangtools.yang.data.api.schema.MixinNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -37,15 +33,13 @@ public abstract class AbstractWriteTx implements DOMDataWriteTransaction {
 
     private static final Logger LOG  = LoggerFactory.getLogger(AbstractWriteTx.class);
 
-    protected final long defaultRequestTimeoutMillis;
     protected final RemoteDeviceId id;
     protected final NetconfBaseOps netOps;
     protected final boolean rollbackSupport;
     // Allow commit to be called only once
     protected boolean finished = false;
 
-    public AbstractWriteTx(final long requestTimeoutMillis, final NetconfBaseOps netOps, final RemoteDeviceId id, final boolean rollbackSupport) {
-        this.defaultRequestTimeoutMillis = requestTimeoutMillis;
+    public AbstractWriteTx(final NetconfBaseOps netOps, final RemoteDeviceId id, final boolean rollbackSupport) {
         this.netOps = netOps;
         this.id = id;
         this.rollbackSupport = rollbackSupport;
@@ -176,18 +170,4 @@ public abstract class AbstractWriteTx implements DOMDataWriteTransaction {
     }
 
     protected abstract void editConfig(DataContainerChild<?, ?> editStructure, Optional<ModifyAction> defaultOperation) throws NetconfDocumentedException;
-
-
-    protected ListenableFuture<DOMRpcResult> perfomRequestWithTimeout(String operation, ListenableFuture<DOMRpcResult> future) {
-        try {
-            future.get(defaultRequestTimeoutMillis, TimeUnit.MILLISECONDS);
-        } catch (InterruptedException | ExecutionException e) {
-            LOG.error("{}: {} failed with error", operation, id, e);
-            return Futures.immediateFailedCheckedFuture(new RuntimeException(id + ": " + operation + " failed"));
-        } catch (TimeoutException e) {
-            LOG.warn("{}: Unable to {} after {} milliseconds", id, operation, defaultRequestTimeoutMillis, e);
-            return Futures.immediateFailedCheckedFuture(new SchemaSourceException(e.getMessage()));
-        }
-        return future;
-    }
 }
index 28d75cdaa4dd3210d9686f391e211abb4a22ad5c..dda54851094e612bf97a86c3020349427a384e8f 100644 (file)
@@ -16,9 +16,6 @@ import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
@@ -44,12 +41,9 @@ public final class ReadOnlyTx implements DOMDataReadOnlyTransaction {
     private final RemoteDeviceId id;
     private final FutureCallback<DOMRpcResult> loggingCallback;
 
-    private final long requestTimeoutMillis;
-
-    public ReadOnlyTx(final NetconfBaseOps netconfOps, final RemoteDeviceId id, final long requestTimeoutMillis) {
+    public ReadOnlyTx(final NetconfBaseOps netconfOps, final RemoteDeviceId id) {
         this.netconfOps = netconfOps;
         this.id = id;
-        this.requestTimeoutMillis = requestTimeoutMillis;
 
         // Simple logging callback to log result of read operation
         loggingCallback = new FutureCallback<DOMRpcResult>() {
@@ -84,10 +78,6 @@ public final class ReadOnlyTx implements DOMDataReadOnlyTransaction {
             }
         });
 
-        if(!readWithTimeout("readConfigurationData", configRunning)) {
-            return null;
-        }
-
         return MappingCheckedFuture.create(transformedFuture, ReadFailedException.MAPPER);
     }
 
@@ -119,10 +109,6 @@ public final class ReadOnlyTx implements DOMDataReadOnlyTransaction {
             }
         });
 
-        if(!readWithTimeout("readOperationalData", configCandidate)) {
-            return null;
-        }
-
         return MappingCheckedFuture.create(transformedFuture, ReadFailedException.MAPPER);
     }
 
@@ -161,18 +147,4 @@ public final class ReadOnlyTx implements DOMDataReadOnlyTransaction {
     public Object getIdentifier() {
         return this;
     }
-
-    private boolean readWithTimeout(String operation, ListenableFuture<DOMRpcResult> future) {
-        try {
-            future.get(requestTimeoutMillis, TimeUnit.MILLISECONDS);
-        } catch (InterruptedException | ExecutionException e) {
-            LOG.error("{}: {} failed with error", id, operation, e);
-            throw new RuntimeException(id + ": readOperationalData failed");
-        } catch (TimeoutException e) {
-            LOG.warn("{}: Unable to {} after {} milliseconds", id, operation, requestTimeoutMillis, e);
-            future.cancel(true);
-            return false;
-        }
-        return true;
-    }
 }
index 0b9bb98e9c75b7ad539313c677c418fe666f790b..c076d0b7a8fc6833d820f3abdb9ee69028f76c48 100644 (file)
@@ -29,8 +29,8 @@ public class WriteCandidateRunningTx extends WriteCandidateTx {
 
     private static final Logger LOG  = LoggerFactory.getLogger(WriteCandidateRunningTx.class);
 
-    public WriteCandidateRunningTx(final RemoteDeviceId id, final NetconfBaseOps netOps, final boolean rollbackSupport, final long requestTimeoutMillis) {
-        super(id, netOps, rollbackSupport, requestTimeoutMillis);
+    public WriteCandidateRunningTx(final RemoteDeviceId id, final NetconfBaseOps netOps, final boolean rollbackSupport) {
+        super(id, netOps, rollbackSupport);
     }
 
     @Override
@@ -46,13 +46,11 @@ public class WriteCandidateRunningTx extends WriteCandidateTx {
     }
 
     private void lockRunning() {
-        final String operation = "Lock Running";
         try {
-            invokeBlocking(operation, new Function<NetconfBaseOps, ListenableFuture<DOMRpcResult>>() {
+            invokeBlocking("Lock running", new Function<NetconfBaseOps, ListenableFuture<DOMRpcResult>>() {
                 @Override
                 public ListenableFuture<DOMRpcResult> apply(final NetconfBaseOps input) {
-                    return perfomRequestWithTimeout(operation, input.lockRunning(new NetconfRpcFutureCallback(operation, id)));
-
+                    return input.lockRunning(new NetconfRpcFutureCallback("Lock running", id));
                 }
             });
         } catch (final NetconfDocumentedException e) {
index f607089dc01b9a1881ed9d0d7fda7e9f621f5195..b143a3bf8e969fb227e70f660862131c6eb509bf 100644 (file)
@@ -71,8 +71,8 @@ public class WriteCandidateTx extends AbstractWriteTx {
         }
     };
 
-    public WriteCandidateTx(final RemoteDeviceId id, final NetconfBaseOps rpc, final boolean rollbackSupport, long requestTimeoutMillis) {
-        super(requestTimeoutMillis, rpc, id, rollbackSupport);
+    public WriteCandidateTx(final RemoteDeviceId id, final NetconfBaseOps rpc, final boolean rollbackSupport) {
+        super(rpc, id, rollbackSupport);
     }
 
     @Override
@@ -95,12 +95,11 @@ public class WriteCandidateTx extends AbstractWriteTx {
     }
 
     private void lock() throws NetconfDocumentedException {
-        final String operation = "Lock candidate";
         try {
-            invokeBlocking(operation, new Function<NetconfBaseOps, ListenableFuture<DOMRpcResult>>() {
+            invokeBlocking("Lock candidate", new Function<NetconfBaseOps, ListenableFuture<DOMRpcResult>>() {
                 @Override
                 public ListenableFuture<DOMRpcResult> apply(final NetconfBaseOps input) {
-                    return perfomRequestWithTimeout(operation, input.lockCandidate(new NetconfRpcFutureCallback(operation, id)));
+                    return input.lockCandidate(new NetconfRpcFutureCallback("Lock candidate", id));
                 }
             });
         } catch (final NetconfDocumentedException e) {
@@ -186,16 +185,14 @@ public class WriteCandidateTx extends AbstractWriteTx {
 
     @Override
     protected void editConfig(final DataContainerChild<?, ?> editStructure, final Optional<ModifyAction> defaultOperation) throws NetconfDocumentedException {
-        final String operation = "Edit candidate";
-        invokeBlocking(operation, new Function<NetconfBaseOps, ListenableFuture<DOMRpcResult>>() {
+        invokeBlocking("Edit candidate", new Function<NetconfBaseOps, ListenableFuture<DOMRpcResult>>() {
             @Override
             public ListenableFuture<DOMRpcResult> apply(final NetconfBaseOps input) {
-
-                        return perfomRequestWithTimeout(operation, defaultOperation.isPresent()
-                                ? input.editConfigCandidate(new NetconfRpcFutureCallback(operation, id), editStructure, defaultOperation.get(),
-                                rollbackSupport)
-                                : input.editConfigCandidate(new NetconfRpcFutureCallback(operation, id), editStructure,
-                                rollbackSupport));
+                    return defaultOperation.isPresent()
+                            ? input.editConfigCandidate(new NetconfRpcFutureCallback("Edit candidate", id), editStructure, defaultOperation.get(),
+                            rollbackSupport)
+                            : input.editConfigCandidate(new NetconfRpcFutureCallback("Edit candidate", id), editStructure,
+                            rollbackSupport);
             }
         });
     }
index 1d0ff653ef0d85abf515da0c409ab0a861c35636..cf7594a7bcf0b9dbdadb9dc7a6aa6ef500d88a19 100644 (file)
@@ -51,8 +51,8 @@ public class WriteRunningTx extends AbstractWriteTx {
     private static final Logger LOG  = LoggerFactory.getLogger(WriteRunningTx.class);
 
     public WriteRunningTx(final RemoteDeviceId id, final NetconfBaseOps netOps,
-                          final boolean rollbackSupport, long requestTimeoutMillis) {
-        super(requestTimeoutMillis, netOps, id, rollbackSupport);
+                          final boolean rollbackSupport) {
+        super(netOps, id, rollbackSupport);
     }
 
     @Override
@@ -61,12 +61,11 @@ public class WriteRunningTx extends AbstractWriteTx {
     }
 
     private void lock() {
-        final String operation = "Lock running";
         try {
-            invokeBlocking(operation, new Function<NetconfBaseOps, ListenableFuture<DOMRpcResult>>() {
+            invokeBlocking("Lock running", new Function<NetconfBaseOps, ListenableFuture<DOMRpcResult>>() {
                 @Override
                 public ListenableFuture<DOMRpcResult> apply(final NetconfBaseOps input) {
-                    return perfomRequestWithTimeout(operation, input.lockRunning(new NetconfRpcFutureCallback(operation, id)));
+                    return input.lockRunning(new NetconfRpcFutureCallback("Lock running", id));
                 }
             });
         } catch (final NetconfDocumentedException e) {
@@ -97,14 +96,14 @@ public class WriteRunningTx extends AbstractWriteTx {
 
     @Override
     public synchronized CheckedFuture<Void, TransactionCommitFailedException> submit() {
-        final ListenableFuture<Void> commitFutureAsVoid = Futures.transform(commit(), new Function<RpcResult<TransactionStatus>, Void>() {
+        final ListenableFuture<Void> commmitFutureAsVoid = Futures.transform(commit(), new Function<RpcResult<TransactionStatus>, Void>() {
             @Override
             public Void apply(final RpcResult<TransactionStatus> input) {
                 return null;
             }
         });
 
-        return Futures.makeChecked(commitFutureAsVoid, new Function<Exception, TransactionCommitFailedException>() {
+        return Futures.makeChecked(commmitFutureAsVoid, new Function<Exception, TransactionCommitFailedException>() {
             @Override
             public TransactionCommitFailedException apply(final Exception input) {
                 return new TransactionCommitFailedException("Submit of transaction " + getIdentifier() + " failed", input);
@@ -120,26 +119,24 @@ public class WriteRunningTx extends AbstractWriteTx {
 
     @Override
     protected void editConfig(final DataContainerChild<?, ?> editStructure, final Optional<ModifyAction> defaultOperation) throws NetconfDocumentedException {
-        final String operation = "Edit running";
-        invokeBlocking(operation, new Function<NetconfBaseOps, ListenableFuture<DOMRpcResult>>() {
+        invokeBlocking("Edit running", new Function<NetconfBaseOps, ListenableFuture<DOMRpcResult>>() {
             @Override
             public ListenableFuture<DOMRpcResult> apply(final NetconfBaseOps input) {
-                        return perfomRequestWithTimeout(operation, defaultOperation.isPresent()
-                                ? input.editConfigRunning(new NetconfRpcFutureCallback(operation, id), editStructure, defaultOperation.get(),
-                                rollbackSupport)
-                                : input.editConfigRunning(new NetconfRpcFutureCallback(operation, id), editStructure,
-                                rollbackSupport));
+                    return defaultOperation.isPresent()
+                            ? input.editConfigRunning(new NetconfRpcFutureCallback("Edit running", id), editStructure, defaultOperation.get(),
+                            rollbackSupport)
+                            : input.editConfigRunning(new NetconfRpcFutureCallback("Edit running", id), editStructure,
+                            rollbackSupport);
             }
         });
     }
 
     private void unlock() {
-        final String operation = "Unlocking running";
         try {
-            invokeBlocking(operation, new Function<NetconfBaseOps, ListenableFuture<DOMRpcResult>>() {
+            invokeBlocking("Unlocking running", new Function<NetconfBaseOps, ListenableFuture<DOMRpcResult>>() {
                 @Override
                 public ListenableFuture<DOMRpcResult> apply(final NetconfBaseOps input) {
-                    return perfomRequestWithTimeout(operation, input.unlockRunning(new NetconfRpcFutureCallback(operation, id)));
+                    return input.unlockRunning(new NetconfRpcFutureCallback("Unlock running", id));
                 }
             });
         } catch (final NetconfDocumentedException e) {
index 2a6ba4301fe3e3827aac2ce4e0521959e0228469..81e09708f3addcb6daaf89a913ea2ee6c288e8c4 100644 (file)
@@ -106,7 +106,7 @@ public class KeepaliveSalFacadeTest {
         doReturn(Futures.immediateCheckedFuture(result)).when(deviceRpc).invokeRpc(any(SchemaPath.class), any(NormalizedNode.class));
 
         final KeepaliveSalFacade keepaliveSalFacade =
-                new KeepaliveSalFacade(REMOTE_DEVICE_ID, underlyingSalFacade, executorServiceSpy, 1L);
+                new KeepaliveSalFacade(REMOTE_DEVICE_ID, underlyingSalFacade, executorServiceSpy, 1L, 1L);
         keepaliveSalFacade.setListener(listener);
 
         keepaliveSalFacade.onDeviceConnected(null, null, deviceRpc);
@@ -133,7 +133,7 @@ public class KeepaliveSalFacadeTest {
                 .when(deviceRpc).invokeRpc(any(SchemaPath.class), any(NormalizedNode.class));
 
         final KeepaliveSalFacade keepaliveSalFacade =
-                new KeepaliveSalFacade(REMOTE_DEVICE_ID, underlyingSalFacade, executorServiceSpy, 1L);
+                new KeepaliveSalFacade(REMOTE_DEVICE_ID, underlyingSalFacade, executorServiceSpy, 1L, 1L);
         keepaliveSalFacade.setListener(listener);
 
         keepaliveSalFacade.onDeviceConnected(null, null, deviceRpc);
@@ -190,7 +190,7 @@ public class KeepaliveSalFacadeTest {
                 .when(deviceRpc).invokeRpc(any(SchemaPath.class), any(NormalizedNode.class));
 
         final KeepaliveSalFacade keepaliveSalFacade =
-                new KeepaliveSalFacade(REMOTE_DEVICE_ID, underlyingSalFacade, executorServiceSpy, 100L);
+                new KeepaliveSalFacade(REMOTE_DEVICE_ID, underlyingSalFacade, executorServiceSpy, 100L, 1L);
         keepaliveSalFacade.setListener(listener);
 
         keepaliveSalFacade.onDeviceConnected(null, null, deviceRpc);
index 1e15e115f35cb479defdeb2ed9754300dc570b06..c32f4fea3339fa1a676fa7d49d1fd23d5a3200be 100644 (file)
@@ -103,7 +103,7 @@ public class NetconfDeviceDataBrokerTest {
     private NetconfDeviceDataBroker getDataBroker(String... caps) {
         NetconfSessionPreferences prefs = NetconfSessionPreferences.fromStrings(Arrays.asList(caps));
         final RemoteDeviceId id = new RemoteDeviceId("device-1", InetSocketAddress.createUnresolved("localhost", 17830));
-        return new NetconfDeviceDataBroker(id, schemaContext, rpcService, prefs, 1000);
+        return new NetconfDeviceDataBroker(id, schemaContext, rpcService, prefs);
     }
 
 }
\ No newline at end of file
index 82fe4b23e788c64ea3c1924536c1432c118c6306..ecb0eeb7796e4582c35690f263dc9a566db0dcfb 100644 (file)
@@ -73,7 +73,7 @@ public class NetconfDeviceWriteOnlyTxTest {
     @Test
     public void testIgnoreNonVisibleData() {
         final WriteCandidateTx tx = new WriteCandidateTx(id, new NetconfBaseOps(rpc, mock(SchemaContext.class)),
-                false, 60000L);
+                false);
         final MapNode emptyList = ImmutableNodes.mapNodeBuilder(NETCONF_FILTER_QNAME).build();
         tx.merge(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create(new YangInstanceIdentifier.NodeIdentifier(NETCONF_FILTER_QNAME)), emptyList);
         tx.put(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create(new YangInstanceIdentifier.NodeIdentifier(NETCONF_FILTER_QNAME)), emptyList);
@@ -84,7 +84,7 @@ public class NetconfDeviceWriteOnlyTxTest {
     @Test
     public void testDiscardChanges() {
         final WriteCandidateTx tx = new WriteCandidateTx(id, new NetconfBaseOps(rpc, mock(SchemaContext.class)),
-                false, 60000L);
+                false);
         final CheckedFuture<Void, TransactionCommitFailedException> submitFuture = tx.submit();
         try {
             submitFuture.checkedGet();
@@ -110,7 +110,7 @@ public class NetconfDeviceWriteOnlyTxTest {
         .doReturn(rpcErrorFuture).when(rpc).invokeRpc(any(SchemaPath.class), any(NormalizedNode.class));
 
         final WriteCandidateTx tx = new WriteCandidateTx(id, new NetconfBaseOps(rpc, mock(SchemaContext.class)),
-                false, 60000L);
+                false);
 
         final CheckedFuture<Void, TransactionCommitFailedException> submitFuture = tx.submit();
         try {
@@ -129,7 +129,7 @@ public class NetconfDeviceWriteOnlyTxTest {
                 .when(rpc).invokeRpc(any(SchemaPath.class), any(NormalizedNode.class));
 
         final WriteRunningTx tx = new WriteRunningTx(id, new NetconfBaseOps(rpc, NetconfMessageTransformer.BaseSchema.BASE_NETCONF_CTX_WITH_NOTIFICATIONS.getSchemaContext()),
-                false, 60000L);
+                false);
         try {
             tx.delete(LogicalDatastoreType.CONFIGURATION, yangIId);
         } catch (final Exception e) {
index c005b5bf232c49730c8c726eda330f695b3a222c..1e9c0fcd86f26a632d0d1ebcb76d10139821c6fd 100644 (file)
@@ -13,27 +13,17 @@ import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
 
 import java.net.InetSocketAddress;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
 
-import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
-import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationException;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
 import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
 import org.opendaylight.controller.md.sal.dom.spi.DefaultDOMRpcResult;
 import org.opendaylight.netconf.sal.connect.netconf.util.NetconfBaseOps;
@@ -43,12 +33,7 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
 
-@PrepareForTest({NetconfBaseOps.class})
-@RunWith(PowerMockRunner.class)
 public class ReadOnlyTxTest {
 
     private static final YangInstanceIdentifier path = YangInstanceIdentifier.create();
@@ -70,33 +55,11 @@ public class ReadOnlyTxTest {
     public void testRead() throws Exception {
         final NetconfBaseOps netconfOps = new NetconfBaseOps(rpc, mock(SchemaContext.class));
 
-        final ReadOnlyTx readOnlyTx = new ReadOnlyTx(netconfOps, new RemoteDeviceId("a", new InetSocketAddress("localhost", 196)), 60000L);
+        final ReadOnlyTx readOnlyTx = new ReadOnlyTx(netconfOps, new RemoteDeviceId("a", new InetSocketAddress("localhost", 196)));
 
         readOnlyTx.read(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create());
         verify(rpc).invokeRpc(Mockito.eq(NetconfMessageTransformUtil.toPath(NetconfMessageTransformUtil.NETCONF_GET_CONFIG_QNAME)), any(NormalizedNode.class));
         readOnlyTx.read(LogicalDatastoreType.OPERATIONAL, path);
         verify(rpc).invokeRpc(Mockito.eq(NetconfMessageTransformUtil.toPath(NetconfMessageTransformUtil.NETCONF_GET_QNAME)), any(NormalizedNode.class));
     }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testReadTimeout() throws Exception {
-        final ListenableFuture<DOMRpcResult> future = mock(ListenableFuture.class);
-
-        Mockito.when(future.get(Mockito.anyLong(), any(TimeUnit.class))).then(new Answer<DOMRpcResult>() {
-            @Override
-            public DOMRpcResult answer(InvocationOnMock invocation)
-                    throws Throwable {
-                throw new TimeoutException("Processing Timeout");
-            }
-        });
-
-        final NetconfBaseOps netconfOps = PowerMockito.mock(NetconfBaseOps.class);
-        Mockito.when(netconfOps.getConfigRunning(any(FutureCallback.class), any(Optional.class))).thenReturn(future);
-
-
-        final ReadOnlyTx readOnlyTx = new ReadOnlyTx(netconfOps, new RemoteDeviceId("a", new InetSocketAddress("localhost", 196)), 100L);
-        Assert.assertNull("Read operation didn't correctly timeout", readOnlyTx.read(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create()));
-        readOnlyTx.close();
-    }
 }
\ No newline at end of file
index 5f6f490afc02069bfef37e9f61ae75433f0efc15..6dc684780fdb4c8b4d7e6d097460235b17b8222c 100644 (file)
@@ -130,30 +130,37 @@ public class RestPerfClient {
         final ExecutorService executorService = Executors.newFixedThreadPool(threadAmount);
 
         LOG.info("Starting performance test");
+        boolean allThreadsCompleted = true;
         final Stopwatch started = Stopwatch.createStarted();
         try {
             final List<Future<Void>> futures = executorService.invokeAll(callables, parameters.timeout, TimeUnit.MINUTES);
             for (int i = 0; i < futures.size(); i++) {
                 Future<Void> future = futures.get(i);
                 if (future.isCancelled()) {
+                    allThreadsCompleted = false;
                     LOG.info("{}. thread timed out.", i + 1);
                 } else {
                     try {
                         future.get();
                     } catch (final ExecutionException e) {
+                        allThreadsCompleted = false;
                         LOG.info("{}. thread failed.", i + 1, e);
                     }
                 }
             }
         } catch (final InterruptedException e) {
+            allThreadsCompleted = false;
             LOG.warn("Unable to execute requests", e);
         }
         executorService.shutdownNow();
         started.stop();
 
         LOG.info("FINISHED. Execution time: {}", started);
-        LOG.info("Requests per second: {}", (parameters.editCount * 1000.0 / started.elapsed(TimeUnit.MILLISECONDS)));
-
+        // If some threads failed or timed out, skip calculation of requests per second value
+        // and do not log it
+        if(allThreadsCompleted) {
+            LOG.info("Requests per second: {}", (parameters.editCount * 1000.0 / started.elapsed(TimeUnit.MILLISECONDS)));
+        }
         System.exit(0);
     }
 
index 31b614766f58f187499ccaf7c674de1205a2181b..86c8a3dd6723c799ce949f3cf89e8ab90f135a99 100644 (file)
     <dependency>
       <groupId>net.java.dev.stax-utils</groupId>
       <artifactId>stax-utils</artifactId>
-      <version>20070216</version>
     </dependency>
 
     <dependency>
               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>
             <Web-ContextPath>/restconf</Web-ContextPath>
           </instructions>
         </configuration>
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>