</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>
<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>
<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>
<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
of the session that made the change will be reported.";
choice server-or-user {
mandatory true;
- //FIXME: After Bug 4414 is resolved, use shorthand version of case statement
- case server {
- leaf server {
- type empty;
- description
+ leaf server {
+ type empty;
+ description
"If present, the change was caused
- by the server.";
- }
+ by the server.";
}
+
case by-user {
uses common-session-parms;
}
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;
@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
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));
// 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));
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
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;
@Arg(dest = "throttle")
public int throttle;
+ @Arg(dest = "auth")
+ public ArrayList<String> auth;
+
static ArgumentParser getParser() {
final ArgumentParser parser = ArgumentParsers.newArgumentParser("netconf stress client");
"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;
}
Preconditions.checkArgument(editContent.exists(), "Edit content file missing");
Preconditions.checkArgument(editContent.isDirectory() == false, "Edit content file is a dir");
Preconditions.checkArgument(editContent.canRead(), "Edit content file is unreadable");
+
+ Preconditions.checkArgument(destination.startsWith("/"), "Destination should start with a '/'");
+
// TODO validate
}
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;
.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();
}
<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>
<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>