Merge "Bug 4700 - RestPerfClient spits NumberFormatException and hangs"
authorTony Tkacik <ttkacik@cisco.com>
Fri, 11 Dec 2015 13:20:13 +0000 (13:20 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Fri, 11 Dec 2015 13:20:13 +0000 (13:20 +0000)
features/netconf/pom.xml
features/netconf/src/main/features/features.xml
features/restconf/pom.xml
features/restconf/src/main/features/features.xml
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/netconf/impl/osgi/NetconfImplActivator.java
opendaylight/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/KeepaliveSalFacade.java
opendaylight/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/KeepaliveSalFacadeTest.java
opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/netconf/test/tool/client/http/perf/Parameters.java
opendaylight/netconf/tools/netconf-testtool/src/main/java/org/opendaylight/netconf/test/tool/client/http/perf/PerfClientCallable.java
opendaylight/restconf/sal-rest-connector/pom.xml
opendaylight/restconf/sal-rest-connector/src/main/resources/WEB-INF/web.xml

index 9d24f37e543de15a7134445937adc614b7f91f74..b79e70badd9140036ce1bff4fac4532efa9ff112 100644 (file)
   </dependencyManagement>
 
   <dependencies>
+    <dependency>
+      <groupId>org.opendaylight.aaa</groupId>
+      <artifactId>features-aaa-shiro</artifactId>
+      <version>${aaa.version}</version>
+      <classifier>features</classifier>
+      <type>xml</type>
+    </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>features-protocol-framework</artifactId>
       <groupId>io.netty</groupId>
       <artifactId>netty-transport</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.bouncycastle</groupId>
+      <artifactId>bcpkix-jdk15on</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.bouncycastle</groupId>
+      <artifactId>bcprov-jdk15on</artifactId>
+    </dependency>
     <dependency>
       <groupId>${project.groupId}</groupId>
       <artifactId>netconf-client</artifactId>
index 9a123722831d041fd961c64cb03aa71288182e11..65d89fe4310eb5f088e4db1bba24f32402202528 100644 (file)
@@ -81,8 +81,8 @@
     <feature version='${project.version}'>odl-netconf-mapping-api</feature>
     <feature version='${project.version}'>odl-netconf-util</feature>
     <bundle>mvn:org.opendaylight.netconf/netconf-netty-util/{{VERSION}}</bundle>
-    <bundle>mvn:org.bouncycastle/bcpkix-jdk15on/${bouncycastle.version}</bundle>
-    <bundle>mvn:org.bouncycastle/bcprov-jdk15on/${bouncycastle.version}</bundle>
+    <bundle>mvn:org.bouncycastle/bcpkix-jdk15on/{{VERSION}}</bundle>
+    <bundle>mvn:org.bouncycastle/bcprov-jdk15on/{{VERSION}}</bundle>
     <bundle>mvn:org.apache.sshd/sshd-core/{{VERSION}}</bundle>
     <bundle>mvn:openexi/nagasena/{{VERSION}}</bundle>
     <bundle>mvn:io.netty/netty-codec/{{VERSION}}</bundle>
index fa4c63882c97f3f93124b264aea2e78ea34175ce..d130180040ce8048b0015ab189f71ed9f336d6b0 100644 (file)
     <controller.mdsal.version>1.3.0-SNAPSHOT</controller.mdsal.version>
     <features.test.version>1.6.0-SNAPSHOT</features.test.version>
     <jersey-servlet.version>1.17</jersey-servlet.version>
-
     <mdsal.version>2.0.0-SNAPSHOT</mdsal.version>
     <mdsal.model.version>0.8.0-SNAPSHOT</mdsal.model.version>
     <restconf.version>1.3.0-SNAPSHOT</restconf.version>
-    <yangtools.version>0.8.0-SNAPSHOT</yangtools.version>
     <surefire.version>2.15</surefire.version>
+    <yangtools.version>0.8.0-SNAPSHOT</yangtools.version>
 
     <features.file>features.xml</features.file>
     <config.configfile.directory>etc/opendaylight/karaf</config.configfile.directory>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.aaa</groupId>
-      <artifactId>features-aaa</artifactId>
+      <artifactId>features-aaa-shiro</artifactId>
       <version>${aaa.version}</version>
       <classifier>features</classifier>
       <type>xml</type>
     </dependency>
-
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal-remote</artifactId>
     <dependency>
       <groupId>com.sun.jersey</groupId>
       <artifactId>jersey-core</artifactId>
-      <version>${jersey.version}</version>
     </dependency>
     <dependency>
       <groupId>com.sun.jersey</groupId>
       <artifactId>jersey-server</artifactId>
-      <version>${jersey.version}</version>
     </dependency>
     <dependency>
       <groupId>com.sun.jersey</groupId>
       <artifactId>jersey-servlet</artifactId>
-      <version>${jersey.version}</version>
     </dependency>
     <dependency>
       <groupId>io.netty</groupId>
index 10060895fe0230b47dbda2492d66a686f2b1e9c5..2ede2bc45a21d2aa6bad2bcdbd88dc9fa8589030 100644 (file)
 
     <repository>mvn:org.opendaylight.controller/features-mdsal/{{VERSION}}/xml/features</repository>
     <repository>mvn:org.opendaylight.yangtools/features-yangtools/{{VERSION}}/xml/features</repository>
-    <repository>mvn:org.opendaylight.aaa/features-aaa/{{VERSION}}/xml/features</repository>
+    <repository>mvn:org.opendaylight.aaa/features-aaa-shiro/{{VERSION}}/xml/features</repository>
     <feature name='odl-restconf-all' version='${project.version}' description='OpenDaylight :: Restconf :: All'>
         <feature version='${project.version}'>odl-restconf</feature>
         <feature version='${project.version}'>odl-mdsal-apidocs</feature>
     </feature>
 
     <feature name='odl-restconf' version='${project.version}' description="OpenDaylight :: Restconf">
-        <feature version='${aaa.version}'>odl-aaa-authn</feature>
+        <!-- Enables AAA through the odl-shiro-act bundle Activator -->
+        <bundle>mvn:org.opendaylight.aaa/aaa-shiro-act/{{VERSION}}</bundle>
         <feature version='${project.version}'>odl-restconf-noauth</feature>
     </feature>
     <feature name='odl-restconf-noauth' version='${project.version}' description="OpenDaylight :: Restconf">
+        <feature version='${aaa.version}'>odl-aaa-shiro</feature>
         <feature version='${controller.mdsal.version}'>odl-mdsal-broker</feature>
         <feature>war</feature>
         <!-- presently we need sal-remote to be listed BEFORE sal-rest-connector because sal-rest-connector
index e62089601b0ffc15026c3d17facb3a8ebafbb1f2..7512f2616b4eac6c44a905d2ea9b10c3a9703071 100644 (file)
@@ -72,7 +72,7 @@ public class NetconfImplActivator implements BundleActivator {
                     new ServiceTracker<>(context, NetconfNotificationCollector.class, new ServiceTrackerCustomizer<NetconfNotificationCollector, NetconfNotificationCollector>() {
                         @Override
                         public NetconfNotificationCollector addingService(ServiceReference<NetconfNotificationCollector> reference) {
-                            Preconditions.checkState(listenerReg != null, "Notification collector service was already added");
+                            Preconditions.checkState(listenerReg == null, "Notification collector service was already added");
                             listenerReg = context.getService(reference).registerBaseNotificationPublisher();
                             monitoringService.setNotificationPublisher(listenerReg);
                             return null;
index cadfc35050a765b20188d1af8e40869bd974af62..862b860eef38ab7e4e001428b220382595dc44b6 100644 (file)
@@ -185,8 +185,13 @@ public final class KeepaliveSalFacade implements RemoteDeviceHandler<NetconfSess
 
         @Override
         public void onSuccess(final DOMRpcResult result) {
-            LOG.debug("{}: Keepalive RPC successful with response: {}", id, result.getResult());
-            scheduleKeepalive();
+            if (result != null && result.getResult() != null) {
+                LOG.debug("{}: Keepalive RPC successful with response: {}", id, result.getResult());
+                scheduleKeepalive();
+            } else {
+                LOG.warn("{} Keepalive RPC returned null with response: {}. Reconnecting netconf session", id, result);
+                reconnect();
+            }
         }
 
         @Override
index b6ea4ddbe141cfd166d4371db79f9e3b4de5d6b0..5dda13a956ca5e9c4fe7a9ed02b988c3dce92e93 100644 (file)
@@ -98,10 +98,13 @@ public class KeepaliveSalFacadeTest {
         final DOMRpcResult result = new DefaultDOMRpcResult(Builders.containerBuilder().withNodeIdentifier(
                 new YangInstanceIdentifier.NodeIdentifier(NetconfMessageTransformUtil.NETCONF_RUNNING_QNAME)).build());
 
-        final DOMRpcResult resultFail = new DefaultDOMRpcResult(mock(RpcError.class));
+        RpcError error = mock(RpcError.class);
+        doReturn("Failure").when(error).toString();
+
+        final DOMRpcResult resultFailWithResultAndError = new DefaultDOMRpcResult(mock(NormalizedNode.class), error);
 
         doReturn(Futures.immediateCheckedFuture(result))
-                .doReturn(Futures.immediateCheckedFuture(resultFail))
+                .doReturn(Futures.immediateCheckedFuture(resultFailWithResultAndError))
                 .doReturn(Futures.immediateFailedCheckedFuture(new IllegalStateException("illegal-state")))
                 .when(deviceRpc).invokeRpc(any(SchemaPath.class), any(NormalizedNode.class));
 
@@ -121,7 +124,7 @@ public class KeepaliveSalFacadeTest {
 
         // Reconnect with same keepalive responses
         doReturn(Futures.immediateCheckedFuture(result))
-                .doReturn(Futures.immediateCheckedFuture(resultFail))
+                .doReturn(Futures.immediateCheckedFuture(resultFailWithResultAndError))
                 .doReturn(Futures.immediateFailedCheckedFuture(new IllegalStateException("illegal-state")))
                 .when(deviceRpc).invokeRpc(any(SchemaPath.class), any(NormalizedNode.class));
 
@@ -131,6 +134,16 @@ public class KeepaliveSalFacadeTest {
         verify(listener, timeout(15000).times(2)).disconnect();
         // 6 attempts now total
         verify(deviceRpc, times(3 * 2)).invokeRpc(any(SchemaPath.class), any(NormalizedNode.class));
+
+        final DOMRpcResult resultFailwithError = new DefaultDOMRpcResult(error);
+
+        doReturn(Futures.immediateCheckedFuture(resultFailwithError))
+                .when(deviceRpc).invokeRpc(any(SchemaPath.class), any(NormalizedNode.class));
+
+        keepaliveSalFacade.onDeviceConnected(null, null, deviceRpc);
+
+        // 1 failed that results in disconnect, 3 total with previous fail
+        verify(listener, timeout(15000).times(3)).disconnect();
     }
 
     @Test
index a91e684ac1672e79bac78dea454485eddb73d28f..7985eef925204e3656fc75698cbaaf3081141dea 100644 (file)
@@ -13,6 +13,7 @@ import java.io.File;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.UnknownHostException;
+import java.util.ArrayList;
 import net.sourceforge.argparse4j.ArgumentParsers;
 import net.sourceforge.argparse4j.annotation.Arg;
 import net.sourceforge.argparse4j.inf.ArgumentParser;
@@ -49,6 +50,9 @@ public class Parameters {
     @Arg(dest = "throttle")
     public int throttle;
 
+    @Arg(dest = "auth")
+    public ArrayList<String> auth;
+
     static ArgumentParser getParser() {
         final ArgumentParser parser = ArgumentParsers.newArgumentParser("netconf stress client");
 
@@ -113,6 +117,11 @@ public class Parameters {
                         "with mutltiple threads this gets divided among all threads")
                 .dest("throttle");
 
+        parser.addArgument("--auth")
+                .nargs(2)
+                .help("Username and password for HTTP basic authentication in order username password.")
+                .dest("auth");
+
         return parser;
     }
 
index e073fbcb2624d9e1cf9edbb413afd8fd319874c8..fed504abb0d212c0cce3cb911518270e0f503d6a 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.netconf.test.tool.client.http.perf;
 
 import com.ning.http.client.AsyncHttpClient;
 import com.ning.http.client.AsyncHttpClientConfig;
+import com.ning.http.client.Realm;
 import com.ning.http.client.Request;
 import java.util.ArrayList;
 import java.util.concurrent.Callable;
@@ -36,12 +37,22 @@ public class PerfClientCallable implements Callable<Void>{
                 .build());
         this.payloads = new ArrayList<>();
         for (DestToPayload payload : payloads) {
-            this.payloads.add(asyncHttpClient.preparePost(payload.getDestination())
+            AsyncHttpClient.BoundRequestBuilder requestBuilder = asyncHttpClient.preparePost(payload.getDestination())
                     .addHeader("content-type", "application/json")
                     .addHeader("Accept", "application/xml")
                     .setBody(payload.getPayload())
-                    .setRequestTimeout(Integer.MAX_VALUE)
-                    .build());
+                    .setRequestTimeout(Integer.MAX_VALUE);
+
+            if(params.auth != null) {
+                requestBuilder.setRealm(new Realm.RealmBuilder()
+                        .setScheme(Realm.AuthScheme.BASIC)
+                        .setPrincipal(params.auth.get(0))
+                        .setPassword(params.auth.get(1))
+                        .setUsePreemptiveAuth(true)
+                        .build());
+            }
+
+            this.payloads.add(requestBuilder.build());
         }
         executionStrategy = getExecutionStrategy();
     }
index 41d746284b07d603298980dd2df67396c6368341..0edf03112ad10973307f2047608d105cc155d05d 100644 (file)
       <artifactId>logback-classic</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>com.sun.jersey</groupId>
+      <artifactId>jersey-server</artifactId>
+    </dependency>
 
     <!-- Testing Dependencies -->
     <dependency>
 
   <build>
     <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <classpathDependencyExcludes>
+            <!-- Removes com.sun.jersey from testing classpath so there is no conflict with org.glassfish.jersey -->
+            <classpathDependencyExclude>com.sun.jersey</classpathDependencyExclude>
+          </classpathDependencyExcludes>
+        </configuration>
+      </plugin>
       <plugin>
         <groupId>org.apache.felix</groupId>
         <artifactId>maven-bundle-plugin</artifactId>
               org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.rest.connector.rev140724.*,
             </Private-Package>
             <Import-Package>
-              com.sun.jersey.spi.container.servlet, org.eclipse.jetty.servlets,
-              <!-- Set the javax packages version to 0. Relying on "*" includes versions from jsr305 dependency whic are
-              incompatible with karaf provided packages -->
-              javax.*;version="0.0",
               *,
+              com.sun.jersey.spi.container.servlet,
+              org.eclipse.jetty.servlets,
+              org.opendaylight.aaa.shiro.filters,
+              org.opendaylight.aaa.shiro.realm,
+              org.opendaylight.aaa.shiro.web.env,
+              org.apache.shiro.web.env
             </Import-Package>
             <Embed-Dependency>stax-utils</Embed-Dependency>
             <Web-ContextPath>/restconf</Web-ContextPath>
index 66cadd0cbce4ea9db0f9f83c67b52280c515b4bf..493572952598594c7cb32d0e80b3cab03c8ad461 100644 (file)
             <param-name>javax.ws.rs.Application</param-name>
             <param-value>org.opendaylight.netconf.sal.rest.impl.RestconfApplication</param-value>
         </init-param>
-        <!-- AAA Auth Filter -->
-        <init-param>
-            <param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name>
-            <param-value> org.opendaylight.aaa.sts.TokenAuthFilter</param-value>
-        </init-param>
         <load-on-startup>1</load-on-startup>
     </servlet>
 
+    <context-param>
+      <param-name>shiroEnvironmentClass</param-name>
+      <param-value>org.opendaylight.aaa.shiro.web.env.KarafIniWebEnvironment</param-value>
+    </context-param>
+
+    <listener>
+        <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
+    </listener>
+
+    <filter>
+        <filter-name>ShiroFilter</filter-name>
+        <filter-class>org.opendaylight.aaa.shiro.filters.AAAFilter</filter-class>
+    </filter>
+
+    <filter-mapping>
+        <filter-name>ShiroFilter</filter-name>
+        <url-pattern>/*</url-pattern>
+    </filter-mapping>
+
     <servlet-mapping>
         <servlet-name>JAXRSRestconf</servlet-name>
         <url-pattern>/*</url-pattern>