<properties>\r
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\r
<nexusproxy>http://nexus.opendaylight.org/content</nexusproxy>\r
- <yang.version>0.6.1</yang.version>\r
- <yang.codegen.version>0.6.1</yang.codegen.version>\r
+ <yang.version>0.6.2-SNAPSHOT</yang.version>\r
+ <yang.codegen.version>0.6.2-SNAPSHOT</yang.codegen.version>\r
<bundle.plugin.version>2.3.7</bundle.plugin.version>\r
</properties>\r
<scm>\r
<enforcer.version>1.3.1</enforcer.version>
<bundle.plugin.version>2.3.7</bundle.plugin.version>
<junit.version>4.8.1</junit.version>
- <yangtools.version>0.6.1</yangtools.version>
+ <yangtools.version>0.6.2-SNAPSHOT</yangtools.version>
<!--versions for bits of the controller -->
<controller.version>0.4.2-SNAPSHOT</controller.version>
<hosttracker.api.version>0.5.2-SNAPSHOT</hosttracker.api.version>
package org.opendaylight.controller.config.persist.storage.directory.autodetect;
import java.io.File;
+import java.io.IOException;
import java.util.List;
import junit.framework.Assert;
import org.junit.Test;
import org.junit.matchers.JUnitMatchers;
import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
import org.opendaylight.controller.config.persist.test.PropertiesProviderTest;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
public class AutodetectDirectoryPersisterTest {
String snapFromXml = configs.get(1).getConfigSnapshot();
org.junit.Assert.assertThat(snapFromXml, JUnitMatchers.containsString("<config>xml</config>"));
- Assert.assertEquals(configs.get(0).getCapabilities(), configs.get(1).getCapabilities()); }
+ Assert.assertEquals(configs.get(0).getCapabilities(), configs.get(1).getCapabilities());
+ }
+
+ @Test
+ public void testInvalidXml() throws Exception {
+ File resourcePath = FileTypeTest.getResourceAsFile("/bad_controller.xml.config");
+ File parentFile = resourcePath.getParentFile();
+
+ AutodetectDirectoryStorageAdapter adapter = new AutodetectDirectoryStorageAdapter();
+
+ PropertiesProviderTest pp = new PropertiesProviderTest();
+ pp.addProperty("directoryStorage",parentFile.getPath());
+ AutodetectDirectoryPersister persister = (AutodetectDirectoryPersister) adapter.instantiate(pp);
+ try {
+ List<ConfigSnapshotHolder> configs = persister.loadLastConfigs();
+ fail("An exception of type " + IllegalStateException.class + " was expected");
+ } catch (IllegalStateException ise){
+ String message = ise.getMessage();
+ assertThat(message, JUnitMatchers.containsString("Unable to restore configuration snapshot from "));
+ }
+
+ }
+
+ @Test
+ public void testPersistConfig() throws Exception {
+ File resourcePath = FileTypeTest.getResourceAsFile("/combined/1controller.txt.config");
+ File parentFile = resourcePath.getParentFile();
+
+ AutodetectDirectoryStorageAdapter adapter = new AutodetectDirectoryStorageAdapter();
+
+ PropertiesProviderTest pp = new PropertiesProviderTest();
+ pp.addProperty("directoryStorage",parentFile.getPath());
+ AutodetectDirectoryPersister persister = (AutodetectDirectoryPersister) adapter.instantiate(pp);
+ List<ConfigSnapshotHolder> configs = null;
+ try {
+ configs = persister.loadLastConfigs();
+ } catch (IOException e) {
+ fail("An exception of type " + UnsupportedOperationException.class + " was expected");
+ }
+ Assert.assertEquals(2, configs.size());
+ try {
+ persister.persistConfig(configs.get(0));
+ } catch (UnsupportedOperationException uoe){
+ String message = uoe.getMessage();
+ assertThat(message,JUnitMatchers.containsString("This adapter is read only. Please set readonly=true on class"));
+ }
+ }
+
}
--- /dev/null
+<snapshot>
+ <required-capabilities>
+ <capability
+ <capability>cap2</capability>
+ <capability>capa a</capability>
+ </required-capabilities>
+ <configuration>
+ <config>xml</config>
+ </configuration>
+</snapshot>
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.config.persist.storage.file.xml.model;
-
-import javax.xml.bind.ValidationEventHandler;
-import javax.xml.bind.annotation.DomHandler;
-import javax.xml.transform.Source;
-import javax.xml.transform.stream.StreamResult;
-import javax.xml.transform.stream.StreamSource;
-import java.io.StringReader;
-import java.io.StringWriter;
-
-class CapabilityHandler implements DomHandler<String, StreamResult> {
-
- private static final String START_TAG = "<capability>";
- private static final String END_TAG = "</capability>";
-
- private StringWriter xmlWriter = new StringWriter();
-
- public StreamResult createUnmarshaller(ValidationEventHandler errorHandler) {
- xmlWriter.getBuffer().setLength(0);
- return new StreamResult(xmlWriter);
- }
-
- public String getElement(StreamResult rt) {
- String xml = rt.getWriter().toString();
- int beginIndex = xml.indexOf(START_TAG) + START_TAG.length();
- int endIndex = xml.indexOf(END_TAG);
- return xml.substring(beginIndex, endIndex);
- }
-
- public Source marshal(String n, ValidationEventHandler errorHandler) {
- try {
- String xml = START_TAG + n.trim() + END_TAG;
- StringReader xmlReader = new StringReader(xml);
- return new StreamSource(xmlReader);
- } catch(Exception e) {
- throw new RuntimeException(e);
- }
- }
-
-}
import com.google.common.base.Charsets;
import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
import java.nio.file.Files;
import java.util.List;
import java.util.SortedSet;
private static int i;
private File file;
+ private static final String NON_EXISTENT_DIRECTORY = "./nonExistentDir/";
+ private static final String NON_EXISTENT_FILE = "nonExistent.txt";
@Before
public void setUp() throws Exception {
i = 1;
}
+ @Test
+ public void testNewFile() throws Exception {
+ XmlFileStorageAdapter storage = new XmlFileStorageAdapter();
+ PropertiesProviderTest pp = new PropertiesProviderTest();
+ pp.addProperty("fileStorage",NON_EXISTENT_DIRECTORY+NON_EXISTENT_FILE);
+ pp.addProperty("numberOfBackups",Integer.toString(Integer.MAX_VALUE));
+ storage.instantiate(pp);
+
+ final ConfigSnapshotHolder holder = new ConfigSnapshotHolder() {
+ @Override
+ public String getConfigSnapshot() {
+ return createConfig();
+ }
+
+ @Override
+ public SortedSet<String> getCapabilities() {
+ return createCaps();
+ }
+ };
+ storage.persistConfig(holder);
+
+ storage.persistConfig(holder);
+
+ Assert.assertEquals(storage.toString().replace("\\","/"),"XmlFileStorageAdapter [storage="+NON_EXISTENT_DIRECTORY+NON_EXISTENT_FILE+"]");
+ delete(new File(NON_EXISTENT_DIRECTORY));
+ }
@Test
public void testFileAdapter() throws Exception {
XmlFileStorageAdapter storage = new XmlFileStorageAdapter();
return "<config>" + i++ + "</config>";
}
+ private void delete(File f) throws IOException {
+ if (f.isDirectory()) {
+ for (File c : f.listFiles())
+ delete(c);
+ }
+ if (!f.delete())
+ throw new FileNotFoundException("Failed to delete file: " + f);
+ }
}
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-binding</artifactId>
- <version>0.6.1</version>
+ <version>${yangtools.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>binding-type-provider</artifactId>
- <version>0.6.1</version>
+ <version>${yangtools.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>maven-sal-api-gen-plugin</artifactId>
- <version>0.6.1</version>
+ <version>${yangtools.version}</version>
<type>jar</type>
</dependency>
</dependencies>
choice band-type {
case drop {
leaf drop-rate {
+ description "Rate for dropping packets";
type uint32;
}
leaf drop-burst-size {
+ description "Size of bursts";
type uint32;
}
}
case dscp-remark {
leaf dscp-remark-rate {
+ description "Rate for remarking packets";
type uint32;
}
leaf dscp-remark-burst-size {
+ description "Size of bursts";
type uint32;
}
leaf perc_level {
+ description "Number of drop precedence level to add";
type uint8;
}
}
case experimenter {
leaf experimenter-rate {
+ description "Rate for remarking packets";
type uint32;
}
leaf experimenter-burst-size {
+ description "Size of bursts";
type uint32;
}
leaf experimenter {
+ description "Experimenter id";
type uint32;
}
}
grouping meter {
leaf flags {
+ description "Meter configuration flags";
type meter-flags;
}
leaf meter-id {
+ description "Meter instance";
type meter-id;
}
leaf barrier {
+ description "If true, barrier message is sent";
type boolean;
}
leaf meter-name {
+ description "Name of meter instance";
type string;
}
leaf container-name {
+ description "Name of container";
type string;
}
list meter-band-header {
key "band-id";
leaf band-id {
+ description "Meter band id";
type band-id;
}
container meter-band-types {
leaf flags {
+ description "Meter band flags";
type meter-band-type;
}
}
leaf band-rate {
+ description "Rate for this band";
type uint32;
}
leaf band-burst-size {
+ description "Size of bursts";
type uint32;
}
uses band-type;
</profiles>
<properties>
- <yangtools.version>0.6.1</yangtools.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<nexusproxy>http://nexus.opendaylight.org/content</nexusproxy>
<!-- Java Versions -->
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>maven-sal-api-gen-plugin</artifactId>
- <version>0.6.1</version>
+ <version>${yangtools.version}</version>
<type>jar</type>
</dependency>
</dependencies>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>maven-sal-api-gen-plugin</artifactId>
- <version>0.6.1</version>
+ <version>${yangtools.version}</version>
<type>jar</type>
</dependency>
</dependencies>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>concepts</artifactId>
- <version>0.6.1</version>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>concepts</artifactId>
- <version>0.6.1</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>maven-sal-api-gen-plugin</artifactId>
- <version>0.6.1</version>
+ <version>${yangtools.version}</version>
<type>jar</type>
</dependency>
</dependencies>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>maven-sal-api-gen-plugin</artifactId>
- <version>0.6.1</version>
+ <version>${yangtools.version}</version>
<type>jar</type>
</dependency>
</dependencies>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>maven-sal-api-gen-plugin</artifactId>
- <version>0.6.1</version>
+ <version>${yangtools.version}</version>
<type>jar</type>
</dependency>
</dependencies>
*/
package org.opendaylight.controller.config.yang.md.sal.connector.netconf;
+import com.google.common.net.InetAddresses;
import io.netty.channel.EventLoopGroup;
import io.netty.util.concurrent.GlobalEventExecutor;
-
-import java.io.File;
-import java.io.InputStream;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-import javax.net.ssl.SSLContext;
-
import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
import org.opendaylight.controller.netconf.client.NetconfSshClientDispatcher;
import org.opendaylight.controller.netconf.util.handler.ssh.authentication.AuthenticationHandler;
import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider;
import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProviders;
import org.osgi.framework.BundleContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
-import static com.google.common.base.Preconditions.*;
+import java.io.File;
+import java.io.InputStream;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
-import com.google.common.base.Optional;
-import com.google.common.net.InetAddresses;
+import static org.opendaylight.controller.config.api.JmxAttributeValidationException.checkCondition;
+import static org.opendaylight.controller.config.api.JmxAttributeValidationException.checkNotNull;
/**
*
*/
public final class NetconfConnectorModule extends org.opendaylight.controller.config.yang.md.sal.connector.netconf.AbstractNetconfConnectorModule
{
+ private static final Logger logger = LoggerFactory.getLogger(NetconfConnectorModule.class);
private static ExecutorService GLOBAL_PROCESSING_EXECUTOR = null;
private static AbstractCachingSchemaSourceProvider<String, InputStream> GLOBAL_NETCONF_SOURCE_PROVIDER = null;
}
@Override
- public void validate(){
- super.validate();
- checkState(getAddress() != null,"Address must be set.");
+ protected void customValidation() {
+ checkNotNull(getAddress(), addressJmxAttribute);
//checkState(getAddress().getIpv4Address() != null || getAddress().getIpv6Address() != null,"Address must be set.");
- checkState(getPort() != null,"Port must be set.");
- checkState(getDomRegistry() != null,"Dom Registry must be provided.");
- }
+ checkNotNull(getPort(), portJmxAttribute);
+ checkNotNull(getDomRegistry(), portJmxAttribute);
+ checkNotNull(getDomRegistry(), domRegistryJmxAttribute);
+
+ checkNotNull(getConnectionTimeoutMillis(), connectionTimeoutMillisJmxAttribute);
+ checkCondition(getConnectionTimeoutMillis() > 0, "must be > 0", connectionTimeoutMillisJmxAttribute);
+ checkNotNull(getBetweenAttemptsTimeoutMillis(), betweenAttemptsTimeoutMillisJmxAttribute);
+ checkCondition(getBetweenAttemptsTimeoutMillis() > 0, "must be > 0", betweenAttemptsTimeoutMillisJmxAttribute);
+
+ }
@Override
public java.lang.AutoCloseable createInstance() {
getDomRegistryDependency();
NetconfDevice device = new NetconfDevice(getIdentifier().getInstanceName());
String addressValue = getAddress();
-
-
- int attemptMsTimeout = 60*1000;
- int connectionAttempts = 5;
+
+ Long connectionAttempts;
+ if (getMaxConnectionAttempts() != null && getMaxConnectionAttempts() > 0) {
+ connectionAttempts = getMaxConnectionAttempts();
+ } else {
+ logger.trace("Setting {} on {} to infinity", maxConnectionAttemptsJmxAttribute, this);
+ connectionAttempts = null;
+ }
+ long clientConnectionTimeoutMillis = getConnectionTimeoutMillis();
/*
* Uncomment after Switch to IP Address
if(getAddress().getIpv4Address() != null) {
addressValue = getAddress().getIpv6Address().getValue();
}
*/
- ReconnectStrategy strategy = new TimedReconnectStrategy(GlobalEventExecutor.INSTANCE, attemptMsTimeout, 1000, 1.0, null,
- Long.valueOf(connectionAttempts), null);
+ double sleepFactor = 1.0;
+ int minSleep = 1000;
+ Long maxSleep = null;
+ Long deadline = null;
+ ReconnectStrategy strategy = new TimedReconnectStrategy(GlobalEventExecutor.INSTANCE, getBetweenAttemptsTimeoutMillis(),
+ minSleep, sleepFactor, maxSleep, connectionAttempts, deadline);
device.setReconnectStrategy(strategy);
device.setSocketAddress(socketAddress);
device.setEventExecutor(getEventExecutorDependency());
- device.setDispatcher(createDispatcher());
+ device.setDispatcher(createDispatcher(clientConnectionTimeoutMillis));
device.setSchemaSourceProvider(getGlobalNetconfSchemaProvider(bundleContext));
getDomRegistryDependency().registerProvider(device, bundleContext);
return GLOBAL_NETCONF_SOURCE_PROVIDER;
}
- private NetconfClientDispatcher createDispatcher() {
+ private NetconfClientDispatcher createDispatcher(long clientConnectionTimeoutMillis) {
EventLoopGroup bossGroup = getBossThreadGroupDependency();
EventLoopGroup workerGroup = getWorkerThreadGroupDependency();
if(getTcpOnly()) {
- return new NetconfClientDispatcher( bossGroup, workerGroup);
+ return new NetconfClientDispatcher( bossGroup, workerGroup, clientConnectionTimeoutMillis);
} else {
AuthenticationHandler authHandler = new LoginPassword(getUsername(),getPassword());
- return new NetconfSshClientDispatcher(authHandler , bossGroup, workerGroup);
+ return new NetconfSshClientDispatcher(authHandler , bossGroup, workerGroup, clientConnectionTimeoutMillis);
}
}
}
}
}
+
+ leaf connection-timeout-millis {
+ description "Specifies timeout in milliseconds after which connection must be established.";
+ type uint32;
+ default 5000;
+ }
+
+ leaf max-connection-attempts {
+ description "Maximum number of connection retries. Non positive value or null is interpreted as infinity.";
+ type uint32;
+ default 0; // retry forever
+ }
+
+
+ leaf between-attempts-timeout-millis {
+ description "Timeout in milliseconds to wait between connection attempts.";
+ type uint16;
+ default 10000;
+ }
}
}
}
\ No newline at end of file
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>maven-sal-api-gen-plugin</artifactId>
- <version>0.6.1</version>
+ <version>${yangtools.version}</version>
<type>jar</type>
</dependency>
</dependencies>
try {
NetconfOperationServiceImpl.checkConsistencyBetweenYangStoreAndConfig(mockJmxClient("qname1"),
mockYangStoreSnapshot("qname2", "qname1"));
- fail("An exception of type " + IllegalArgumentException.class + " was expected");
+ fail("An exception of type " + IllegalStateException.class + " was expected");
} catch (IllegalStateException e) {
String message = e.getMessage();
Assert.assertThat(
private final EventLoopGroup nettyThreadgroup;
// Default timeout for netconf becoming stable
- public static final long DEFAULT_TIMEOUT = TimeUnit.MINUTES.toNanos(2);
+ public static final long DEFAULT_TIMEOUT_NANOS = TimeUnit.MINUTES.toNanos(2);
+ private static final long DEFAULT_CONNECTION_TIMEOUT_MILLIS = 5000;
private final int delayMillis = 5000;
private final long timeoutNanos;
+ private final long connectionTimeoutMillis;
public ConfigPusher(InetSocketAddress address, EventLoopGroup nettyThreadgroup) {
- this(address, nettyThreadgroup, DEFAULT_TIMEOUT);
+ this(address, nettyThreadgroup, DEFAULT_TIMEOUT_NANOS, DEFAULT_CONNECTION_TIMEOUT_MILLIS);
}
- @Deprecated
- public ConfigPusher(InetSocketAddress address, long timeoutMillis, EventLoopGroup nettyThreadgroup) {
- this(address, nettyThreadgroup, TimeUnit.MILLISECONDS.toNanos(timeoutMillis));
- }
-
- public ConfigPusher(InetSocketAddress address, EventLoopGroup nettyThreadgroup, long timeoutNanos) {
+ public ConfigPusher(InetSocketAddress address, EventLoopGroup nettyThreadgroup, long timeoutNanos, long connectionTimeoutMillis) {
this.address = address;
this.nettyThreadgroup = nettyThreadgroup;
this.timeoutNanos = timeoutNanos;
+ this.connectionTimeoutMillis = connectionTimeoutMillis;
}
public synchronized NetconfClient init(List<ConfigSnapshotHolder> configs) throws InterruptedException {
String additionalHeader = NetconfMessageAdditionalHeader.toString("unknown", address.getAddress().getHostAddress(),
Integer.toString(address.getPort()), "tcp", Optional.of("persister"));
- Set<String> latestCapabilities = new HashSet<>();
+ Set<String> latestCapabilities = null;
while (System.nanoTime() < deadline) {
attempt++;
NetconfClientDispatcher netconfClientDispatcher = new NetconfClientDispatcher(nettyThreadgroup,
- nettyThreadgroup, additionalHeader);
+ nettyThreadgroup, additionalHeader, connectionTimeoutMillis);
NetconfClient netconfClient;
try {
netconfClient = new NetconfClient(this.toString(), address, delayMillis, netconfClientDispatcher);
Util.closeClientAndDispatcher(netconfClient);
Thread.sleep(delayMillis);
}
+ if (latestCapabilities == null) {
+ logger.error("Could not connect to the server in {} ms", timeoutNanos / 1000);
+ throw new RuntimeException("Could not connect to netconf server");
+ }
Set<String> allNotFound = new HashSet<>(expectedCaps);
allNotFound.removeAll(latestCapabilities);
logger.error("Netconf server did not provide required capabilities. Expected but not found: {}, all expected {}, current {}",
}
String timeoutProperty = propertiesProvider.getProperty(PUSH_TIMEOUT);
- long timeout = timeoutProperty == null ? ConfigPusher.DEFAULT_TIMEOUT : TimeUnit.SECONDS.toNanos(Integer.valueOf(timeoutProperty));
+ long timeout = timeoutProperty == null ? ConfigPusher.DEFAULT_TIMEOUT_NANOS : TimeUnit.SECONDS.toNanos(Integer.valueOf(timeoutProperty));
final Pattern ignoredMissingCapabilityRegex = Pattern.compile(regex);
nettyThreadgroup = new NioEventLoopGroup();
package org.opendaylight.controller.netconf.client;
+import com.google.common.base.Optional;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.util.HashedWheelTimer;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.Promise;
-
-import java.io.Closeable;
-import java.net.InetSocketAddress;
-
import org.opendaylight.controller.netconf.api.NetconfMessage;
import org.opendaylight.controller.netconf.api.NetconfSession;
import org.opendaylight.controller.netconf.api.NetconfTerminationReason;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.Optional;
+import java.io.Closeable;
+import java.net.InetSocketAddress;
public class NetconfClientDispatcher extends AbstractDispatcher<NetconfClientSession, NetconfClientSessionListener> implements Closeable {
private final NetconfClientSessionNegotiatorFactory negotatorFactory;
private final HashedWheelTimer timer;
- public NetconfClientDispatcher(EventLoopGroup bossGroup, EventLoopGroup workerGroup) {
+ public NetconfClientDispatcher(EventLoopGroup bossGroup, EventLoopGroup workerGroup, long clientConnectionTimeoutMillis) {
super(bossGroup, workerGroup);
timer = new HashedWheelTimer();
- this.negotatorFactory = new NetconfClientSessionNegotiatorFactory(timer, Optional.<String>absent());
+ this.negotatorFactory = new NetconfClientSessionNegotiatorFactory(timer, Optional.<String>absent(), clientConnectionTimeoutMillis);
}
- public NetconfClientDispatcher(EventLoopGroup bossGroup, EventLoopGroup workerGroup, String additionalHeader) {
+ public NetconfClientDispatcher(EventLoopGroup bossGroup, EventLoopGroup workerGroup, String additionalHeader, long connectionTimeoutMillis) {
super(bossGroup, workerGroup);
timer = new HashedWheelTimer();
- this.negotatorFactory = new NetconfClientSessionNegotiatorFactory(timer, Optional.of(additionalHeader));
+ this.negotatorFactory = new NetconfClientSessionNegotiatorFactory(timer, Optional.of(additionalHeader), connectionTimeoutMillis);
}
public Future<NetconfClientSession> createClient(InetSocketAddress address,
AbstractNetconfSessionNegotiator<NetconfSessionPreferences, NetconfClientSession> {
protected NetconfClientSessionNegotiator(NetconfSessionPreferences sessionPreferences,
- Promise<NetconfClientSession> promise, Channel channel, Timer timer, SessionListener sessionListener) {
- super(sessionPreferences, promise, channel, timer, sessionListener);
+ Promise<NetconfClientSession> promise, Channel channel, Timer timer, SessionListener sessionListener,
+ long connectionTimeoutMillis) {
+ super(sessionPreferences, promise, channel, timer, sessionListener, connectionTimeoutMillis);
}
private static Collection<String> getCapabilities(Document doc) {
package org.opendaylight.controller.netconf.client;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
import io.netty.channel.Channel;
import io.netty.util.Timer;
import io.netty.util.concurrent.Promise;
-
-import java.io.IOException;
-import java.io.InputStream;
-
import org.opendaylight.controller.netconf.api.NetconfMessage;
import org.opendaylight.controller.netconf.api.NetconfSessionPreferences;
import org.opendaylight.controller.netconf.util.xml.XmlUtil;
import org.opendaylight.protocol.framework.SessionNegotiatorFactory;
import org.xml.sax.SAXException;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
+import java.io.IOException;
+import java.io.InputStream;
public class NetconfClientSessionNegotiatorFactory implements SessionNegotiatorFactory {
private final Timer timer;
private final Optional<String> additionalHeader;
+ private final long connectionTimeoutMillis;
- public NetconfClientSessionNegotiatorFactory(Timer timer, Optional<String> additionalHeader) {
+ public NetconfClientSessionNegotiatorFactory(Timer timer, Optional<String> additionalHeader, long connectionTimeoutMillis) {
this.timer = timer;
this.additionalHeader = additionalHeader;
+ this.connectionTimeoutMillis = connectionTimeoutMillis;
}
private static NetconfMessage loadHelloMessageTemplate() {
}
NetconfSessionPreferences proposal = new NetconfSessionPreferences(helloMessage);
return new NetconfClientSessionNegotiator(proposal, promise, channel, timer,
- sessionListenerFactory.getSessionListener());
+ sessionListenerFactory.getSessionListener(), connectionTimeoutMillis);
}
}
package org.opendaylight.controller.netconf.client;
+import com.google.common.base.Optional;
import io.netty.channel.ChannelHandler;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.util.HashedWheelTimer;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.Promise;
-
-import java.io.IOException;
-import java.net.InetSocketAddress;
-
import org.opendaylight.controller.netconf.api.NetconfMessage;
import org.opendaylight.controller.netconf.api.NetconfSession;
import org.opendaylight.controller.netconf.api.NetconfTerminationReason;
import org.opendaylight.protocol.framework.SessionListener;
import org.opendaylight.protocol.framework.SessionListenerFactory;
-import com.google.common.base.Optional;
+import java.io.IOException;
+import java.net.InetSocketAddress;
public class NetconfSshClientDispatcher extends NetconfClientDispatcher {
private NetconfClientSessionNegotiatorFactory negotatorFactory;
public NetconfSshClientDispatcher(AuthenticationHandler authHandler, EventLoopGroup bossGroup,
- EventLoopGroup workerGroup) {
- super(bossGroup, workerGroup);
+ EventLoopGroup workerGroup, long connectionTimeoutMillis) {
+ super(bossGroup, workerGroup, connectionTimeoutMillis);
this.authHandler = authHandler;
this.timer = new HashedWheelTimer();
- this.negotatorFactory = new NetconfClientSessionNegotiatorFactory(timer, Optional.<String>absent());
+ this.negotatorFactory = new NetconfClientSessionNegotiatorFactory(timer, Optional.<String>absent(), connectionTimeoutMillis);
}
public NetconfSshClientDispatcher(AuthenticationHandler authHandler, EventLoopGroup bossGroup,
- EventLoopGroup workerGroup, String additionalHeader) {
- super(bossGroup, workerGroup, additionalHeader);
+ EventLoopGroup workerGroup, String additionalHeader, long socketTimeoutMillis) {
+ super(bossGroup, workerGroup, additionalHeader, socketTimeoutMillis);
this.authHandler = authHandler;
this.timer = new HashedWheelTimer();
- this.negotatorFactory = new NetconfClientSessionNegotiatorFactory(timer, Optional.of(additionalHeader));
+ this.negotatorFactory = new NetconfClientSessionNegotiatorFactory(timer, Optional.of(additionalHeader), socketTimeoutMillis);
}
public Future<NetconfClientSession> createClient(InetSocketAddress address,
nettyThreadgroup = new NioEventLoopGroup();
netconfClientDispatcher = new NetconfSshClientDispatcher(new LoginPassword(
System.getProperty("username"), System.getProperty("password")),
- nettyThreadgroup, nettyThreadgroup);
+ nettyThreadgroup, nettyThreadgroup, 5000);
}
@Test
package org.opendaylight.controller.netconf.impl;
+import com.google.common.base.Optional;
import io.netty.channel.Channel;
import io.netty.util.Timer;
import io.netty.util.concurrent.Promise;
-
-import java.net.InetSocketAddress;
-
import org.opendaylight.controller.netconf.api.NetconfMessage;
import org.opendaylight.controller.netconf.api.NetconfServerSessionPreferences;
import org.opendaylight.controller.netconf.impl.util.AdditionalHeaderUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.Optional;
+import java.net.InetSocketAddress;
public class NetconfServerSessionNegotiator extends
AbstractNetconfSessionNegotiator<NetconfServerSessionPreferences, NetconfServerSession> {
static final Logger logger = LoggerFactory.getLogger(NetconfServerSessionNegotiator.class);
protected NetconfServerSessionNegotiator(NetconfServerSessionPreferences sessionPreferences,
- Promise<NetconfServerSession> promise, Channel channel, Timer timer, SessionListener sessionListener) {
- super(sessionPreferences, promise, channel, timer, sessionListener);
+ Promise<NetconfServerSession> promise, Channel channel, Timer timer, SessionListener sessionListener,
+ long connectionTimeoutMillis) {
+ super(sessionPreferences, promise, channel, timer, sessionListener, connectionTimeoutMillis);
}
@Override
private static final Document helloMessageTemplate = loadHelloMessageTemplate();
private final SessionIdProvider idProvider;
private final NetconfOperationServiceFactoryListener factoriesListener;
+ private final long connectionTimeoutMillis;
public NetconfServerSessionNegotiatorFactory(Timer timer, NetconfOperationServiceFactoryListener factoriesListener,
- SessionIdProvider idProvider) {
+ SessionIdProvider idProvider, long connectionTimeoutMillis) {
this.timer = timer;
this.factoriesListener = factoriesListener;
this.idProvider = idProvider;
+ this.connectionTimeoutMillis = connectionTimeoutMillis;
}
private static Document loadHelloMessageTemplate() {
NetconfServerSessionPreferences proposal = new NetconfServerSessionPreferences(createHelloMessage(sessionId),
sessionId);
return new NetconfServerSessionNegotiator(proposal, promise, channel, timer,
- sessionListenerFactory.getSessionListener());
+ sessionListenerFactory.getSessionListener(), connectionTimeoutMillis);
}
private static final XPathExpression sessionIdXPath = XMLNetconfUtil
SessionIdProvider idProvider = new SessionIdProvider();
timer = new HashedWheelTimer();
+ long connectionTimeoutMillis = NetconfConfigUtil.extractTimeoutMillis(context);
NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory(
- timer, factoriesListener, idProvider);
+ timer, factoriesListener, idProvider, connectionTimeoutMillis);
commitNot = new DefaultCommitNotificationProducer(ManagementFactory.getPlatformMBeanServer());
package org.opendaylight.controller.netconf.impl;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.junit.Assert.fail;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
+import com.google.common.base.Optional;
+import com.google.common.collect.Sets;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.util.HashedWheelTimer;
-
-import java.io.DataOutputStream;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.lang.management.ManagementFactory;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
-import javax.management.ObjectName;
-
import org.apache.commons.io.IOUtils;
import org.junit.After;
-import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
-import com.google.common.base.Optional;
-import com.google.common.collect.Sets;
+import javax.management.ObjectName;
+import java.io.DataOutputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.management.ManagementFactory;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
public class ConcurrentClientsTest {
private static final int CONCURRENCY = 16;
- private static EventLoopGroup nettyGroup = new NioEventLoopGroup();
- public static final NetconfClientDispatcher NETCONF_CLIENT_DISPATCHER =
- new NetconfClientDispatcher( nettyGroup, nettyGroup);
+ private EventLoopGroup nettyGroup;
+ private NetconfClientDispatcher netconfClientDispatcher;
@Mock
private YangStoreService yangStoreService;
@Mock
private SessionMonitoringService monitoring;
+ HashedWheelTimer hashedWheelTimer;
+
@Before
public void setUp() throws Exception {
{ // init mocks
doReturn(Collections.emptySet()).when(jmxClient).lookupConfigBeans();
}
+ nettyGroup = new NioEventLoopGroup();
+ netconfClientDispatcher = new NetconfClientDispatcher( nettyGroup, nettyGroup, 5000);
+
NetconfOperationServiceFactoryListenerImpl factoriesListener = new NetconfOperationServiceFactoryListenerImpl();
factoriesListener.onAddNetconfOperationServiceFactory(mockOpF());
SessionIdProvider idProvider = new SessionIdProvider();
+ hashedWheelTimer = new HashedWheelTimer();
NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory(
- new HashedWheelTimer(5000, TimeUnit.MILLISECONDS), factoriesListener, idProvider);
+ hashedWheelTimer, factoriesListener, idProvider, 5000);
commitNot = new DefaultCommitNotificationProducer(ManagementFactory.getPlatformMBeanServer());
s.await();
}
- @AfterClass
- public static void tearDownStatic() {
+ @After
+ public void tearDown(){
+ hashedWheelTimer.stop();
nettyGroup.shutdownGracefully();
}
@Override
public void run() {
try {
- final NetconfClient netconfClient = new NetconfClient(clientId, netconfAddress, NETCONF_CLIENT_DISPATCHER);
+ final NetconfClient netconfClient = new NetconfClient(clientId, netconfAddress, netconfClientDispatcher);
long sessionId = netconfClient.getSessionId();
logger.info("Client with sessionid {} hello exchanged", sessionId);
private EventLoopGroup nettyGroup;
private NetconfServerDispatcher dispatch;
private DefaultCommitNotificationProducer commitNot;
+ private HashedWheelTimer hashedWheelTimer;
@Before
public void setUp() throws Exception {
NetconfOperationServiceFactoryListener factoriesListener = new NetconfOperationServiceFactoryListenerImpl();
SessionIdProvider idProvider = new SessionIdProvider();
+ hashedWheelTimer = new HashedWheelTimer();
NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory(
- new HashedWheelTimer(), factoriesListener, idProvider);
+ hashedWheelTimer, factoriesListener, idProvider, 5000);
NetconfServerSessionListenerFactory listenerFactory = new NetconfServerSessionListenerFactory(
factoriesListener, commitNot, idProvider, null);
@After
public void tearDown() throws Exception {
+ hashedWheelTimer.stop();
commitNot.close();
nettyGroup.shutdownGracefully();
}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.it;
+
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.util.HashedWheelTimer;
+import org.junit.After;
+import org.junit.Before;
+import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
+import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer;
+import org.opendaylight.controller.netconf.impl.NetconfServerDispatcher;
+import org.opendaylight.controller.netconf.impl.NetconfServerSessionListenerFactory;
+import org.opendaylight.controller.netconf.impl.NetconfServerSessionNegotiatorFactory;
+import org.opendaylight.controller.netconf.impl.SessionIdProvider;
+import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListenerImpl;
+import org.opendaylight.controller.netconf.impl.osgi.SessionMonitoringService;
+
+public class AbstractNetconfConfigTest extends AbstractConfigTest {
+
+ protected EventLoopGroup nettyThreadgroup;
+ private HashedWheelTimer hashedWheelTimer;
+
+ @Before
+ public void setUpAbstractNetconfConfigTest() {
+ nettyThreadgroup = new NioEventLoopGroup();
+ hashedWheelTimer = new HashedWheelTimer();
+ }
+
+
+ protected NetconfServerDispatcher createDispatcher(
+ NetconfOperationServiceFactoryListenerImpl factoriesListener, SessionMonitoringService sessionMonitoringService,
+ DefaultCommitNotificationProducer commitNotifier) {
+ SessionIdProvider idProvider = new SessionIdProvider();
+
+ NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory(
+ hashedWheelTimer, factoriesListener, idProvider, 5000);
+
+ NetconfServerSessionListenerFactory listenerFactory = new NetconfServerSessionListenerFactory(
+ factoriesListener, commitNotifier, idProvider,
+ sessionMonitoringService);
+
+ NetconfServerDispatcher.ServerChannelInitializer serverChannelInitializer = new NetconfServerDispatcher.ServerChannelInitializer(
+ serverNegotiatorFactory, listenerFactory);
+ return new NetconfServerDispatcher(serverChannelInitializer, nettyThreadgroup, nettyThreadgroup);
+ }
+
+
+ @After
+ public void cleanUpTimer() {
+ hashedWheelTimer.stop();
+ nettyThreadgroup.shutdownGracefully();
+ }
+
+}
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import io.netty.channel.ChannelFuture;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.util.HashedWheelTimer;
import org.apache.commons.lang3.StringUtils;
+import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.matchers.JUnitMatchers;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
-import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
import org.opendaylight.controller.config.persist.api.Persister;
import org.opendaylight.controller.netconf.confignetconfconnector.osgi.NetconfOperationServiceFactoryImpl;
import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer;
import org.opendaylight.controller.netconf.impl.NetconfServerDispatcher;
-import org.opendaylight.controller.netconf.impl.NetconfServerSessionListenerFactory;
-import org.opendaylight.controller.netconf.impl.NetconfServerSessionNegotiatorFactory;
-import org.opendaylight.controller.netconf.impl.SessionIdProvider;
import org.opendaylight.controller.netconf.impl.osgi.NetconfMonitoringServiceImpl;
import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListener;
import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListenerImpl;
import java.util.Collection;
import java.util.List;
import java.util.Set;
-import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
import static junit.framework.Assert.assertEquals;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
-public class NetconfConfigPersisterITTest extends AbstractConfigTest {
+public class NetconfConfigPersisterITTest extends AbstractNetconfConfigTest {
private static final Logger logger = LoggerFactory.getLogger(NetconfConfigPersisterITTest.class);
private static final InetSocketAddress tcpAddress = new InetSocketAddress("127.0.0.1", 12023);
- private EventLoopGroup nettyThreadgroup;
+
private NetconfClientDispatcher clientDispatcher;
+ DefaultCommitNotificationProducer commitNotifier;
+
@Before
public void setUp() throws Exception {
super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(NetconfITTest.getModuleFactoriesS().toArray(
.onAddNetconfOperationServiceFactory(new NetconfMonitoringActivator.NetconfMonitoringOperationServiceFactory(
new NetconfMonitoringOperationService(monitoringService)));
- nettyThreadgroup = new NioEventLoopGroup();
- NetconfServerDispatcher dispatch = createDispatcher(factoriesListener);
+ commitNotifier = new DefaultCommitNotificationProducer(platformMBeanServer);
+ NetconfServerDispatcher dispatch = createDispatcher(factoriesListener, mockSessionMonitoringService(), commitNotifier);
ChannelFuture s = dispatch.createServer(tcpAddress);
s.await();
- clientDispatcher = new NetconfClientDispatcher(nettyThreadgroup, nettyThreadgroup);
+ clientDispatcher = new NetconfClientDispatcher(nettyThreadgroup, nettyThreadgroup, 5000);
+ }
+
+ @After
+ public void cleanUp(){
+ commitNotifier.close();
}
private HardcodedYangStoreService getYangStore() throws YangStoreException, IOException {
return new HardcodedYangStoreService(yangDependencies);
}
- private NetconfServerDispatcher createDispatcher(
- NetconfOperationServiceFactoryListenerImpl factoriesListener) {
- SessionIdProvider idProvider = new SessionIdProvider();
- NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory(
- new HashedWheelTimer(5000, TimeUnit.MILLISECONDS), factoriesListener, idProvider);
-
- NetconfServerSessionListenerFactory listenerFactory = new NetconfServerSessionListenerFactory(
- factoriesListener, new DefaultCommitNotificationProducer(platformMBeanServer), idProvider, mockSessionMonitoringService());
- NetconfServerDispatcher.ServerChannelInitializer serverChannelInitializer = new NetconfServerDispatcher.ServerChannelInitializer(
- serverNegotiatorFactory, listenerFactory);
- return new NetconfServerDispatcher(serverChannelInitializer, nettyThreadgroup, nettyThreadgroup);
- }
-
- private SessionMonitoringService mockSessionMonitoringService() {
+ protected SessionMonitoringService mockSessionMonitoringService() {
SessionMonitoringService mockedSessionMonitor = mock(SessionMonitoringService.class);
doNothing().when(mockedSessionMonitor).onSessionUp(any(NetconfManagementSession.class));
doNothing().when(mockedSessionMonitor).onSessionDown(any(NetconfManagementSession.class));
return mockedSessionMonitor;
}
+
+
@Test
public void testNetconfCommitNotifications() throws Exception {
package org.opendaylight.controller.netconf.it;
import io.netty.channel.ChannelFuture;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.util.HashedWheelTimer;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.management.ManagementFactory;
-import java.net.InetSocketAddress;
-import java.security.KeyManagementException;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.UnrecoverableKeyException;
-import java.security.cert.CertificateException;
-import java.util.Collection;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.SSLContext;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
import org.opendaylight.controller.config.spi.ModuleFactory;
import org.opendaylight.controller.config.yang.store.api.YangStoreException;
import org.opendaylight.controller.netconf.confignetconfconnector.osgi.NetconfOperationServiceFactoryImpl;
import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer;
import org.opendaylight.controller.netconf.impl.NetconfServerDispatcher;
-import org.opendaylight.controller.netconf.impl.NetconfServerSessionListenerFactory;
-import org.opendaylight.controller.netconf.impl.NetconfServerSessionNegotiatorFactory;
-import org.opendaylight.controller.netconf.impl.SessionIdProvider;
import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListenerImpl;
-public class NetconfITSecureTest extends AbstractConfigTest {
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.management.ManagementFactory;
+import java.net.InetSocketAddress;
+import java.security.KeyManagementException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+import java.util.Collection;
+import java.util.List;
+
+public class NetconfITSecureTest extends AbstractNetconfConfigTest {
private static final InetSocketAddress tlsAddress = new InetSocketAddress("127.0.0.1", 12024);
private DefaultCommitNotificationProducer commitNot;
private NetconfServerDispatcher dispatchS;
- private EventLoopGroup nettyThreadgroup;
@Before
commitNot = new DefaultCommitNotificationProducer(ManagementFactory.getPlatformMBeanServer());
- nettyThreadgroup = new NioEventLoopGroup();
dispatchS = createDispatcher(factoriesListener);
ChannelFuture s = dispatchS.createServer(tlsAddress);
}
private NetconfServerDispatcher createDispatcher(NetconfOperationServiceFactoryListenerImpl factoriesListener) {
- SessionIdProvider idProvider = new SessionIdProvider();
- NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory(
- new HashedWheelTimer(5000, TimeUnit.MILLISECONDS), factoriesListener, idProvider);
-
- NetconfServerSessionListenerFactory listenerFactory = new NetconfServerSessionListenerFactory(
- factoriesListener, commitNot, idProvider, NetconfITTest.getNetconfMonitoringListenerService());
-
- NetconfServerDispatcher.ServerChannelInitializer serverChannelInitializer = new NetconfServerDispatcher.ServerChannelInitializer(
- serverNegotiatorFactory, listenerFactory);
- return new NetconfServerDispatcher(serverChannelInitializer, nettyThreadgroup, nettyThreadgroup);
+ return super.createDispatcher(factoriesListener, NetconfITTest.getNetconfMonitoringListenerService(), commitNot);
}
@After
public void tearDown() throws Exception {
commitNot.close();
- nettyThreadgroup.shutdownGracefully();
}
private SSLContext getSslContext() throws KeyStoreException, NoSuchAlgorithmException, CertificateException,
@Test
public void testSecure() throws Exception {
- NetconfClientDispatcher dispatch = new NetconfClientDispatcher(nettyThreadgroup, nettyThreadgroup);
+ NetconfClientDispatcher dispatch = new NetconfClientDispatcher(nettyThreadgroup, nettyThreadgroup, 5000);
try (NetconfClient netconfClient = new NetconfClient("tls-client", tlsAddress, 4000, dispatch)) {
}
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import io.netty.channel.ChannelFuture;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.util.HashedWheelTimer;
import junit.framework.Assert;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
-import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
import org.opendaylight.controller.config.spi.ModuleFactory;
import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
import org.opendaylight.controller.netconf.confignetconfconnector.osgi.NetconfOperationServiceFactoryImpl;
import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer;
import org.opendaylight.controller.netconf.impl.NetconfServerDispatcher;
-import org.opendaylight.controller.netconf.impl.NetconfServerSessionListenerFactory;
-import org.opendaylight.controller.netconf.impl.NetconfServerSessionNegotiatorFactory;
-import org.opendaylight.controller.netconf.impl.SessionIdProvider;
import org.opendaylight.controller.netconf.impl.osgi.NetconfMonitoringServiceImpl;
import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListener;
import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListenerImpl;
import java.util.Collections;
import java.util.List;
import java.util.Set;
-import java.util.concurrent.TimeUnit;
import static java.util.Collections.emptyList;
import static junit.framework.Assert.assertEquals;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
-public class NetconfITTest extends AbstractConfigTest {
+public class NetconfITTest extends AbstractNetconfConfigTest {
// TODO refactor, pull common code up to AbstractNetconfITTest
closeSession, startExi, stopExi;
private DefaultCommitNotificationProducer commitNot;
private NetconfServerDispatcher dispatch;
- private EventLoopGroup nettyThreadgroup;
private NetconfClientDispatcher clientDispatcher;
NetconfOperationServiceFactoryListenerImpl factoriesListener = new NetconfOperationServiceFactoryListenerImpl();
factoriesListener.onAddNetconfOperationServiceFactory(new NetconfOperationServiceFactoryImpl(getYangStore()));
- nettyThreadgroup = new NioEventLoopGroup();
commitNot = new DefaultCommitNotificationProducer(ManagementFactory.getPlatformMBeanServer());
ChannelFuture s = dispatch.createServer(tcpAddress);
s.await();
- clientDispatcher = new NetconfClientDispatcher( nettyThreadgroup, nettyThreadgroup);
+ clientDispatcher = new NetconfClientDispatcher( nettyThreadgroup, nettyThreadgroup, 5000);
}
private NetconfServerDispatcher createDispatcher(NetconfOperationServiceFactoryListenerImpl factoriesListener) {
- SessionIdProvider idProvider = new SessionIdProvider();
- NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory(
- new HashedWheelTimer(5000, TimeUnit.MILLISECONDS), factoriesListener, idProvider);
-
- NetconfServerSessionListenerFactory listenerFactory = new NetconfServerSessionListenerFactory(
- factoriesListener, commitNot, idProvider, getNetconfMonitoringListenerService());
-
- NetconfServerDispatcher.ServerChannelInitializer serverChannelInitializer = new NetconfServerDispatcher.ServerChannelInitializer(
- serverNegotiatorFactory, listenerFactory);
- return new NetconfServerDispatcher(serverChannelInitializer, nettyThreadgroup, nettyThreadgroup);
+ return super.createDispatcher(factoriesListener, getNetconfMonitoringListenerService(), commitNot);
}
static NetconfMonitoringServiceImpl getNetconfMonitoringListenerService() {
@After
public void tearDown() throws Exception {
commitNot.close();
- nettyThreadgroup.shutdownGracefully();
clientDispatcher.close();
}
import com.google.common.base.Optional;
import com.google.common.collect.Sets;
import io.netty.channel.ChannelFuture;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.util.HashedWheelTimer;
import junit.framework.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.matchers.JUnitMatchers;
import org.mockito.Mock;
-import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
import org.opendaylight.controller.config.spi.ModuleFactory;
import org.opendaylight.controller.config.yang.store.api.YangStoreException;
import org.opendaylight.controller.netconf.confignetconfconnector.osgi.NetconfOperationServiceFactoryImpl;
import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer;
import org.opendaylight.controller.netconf.impl.NetconfServerDispatcher;
-import org.opendaylight.controller.netconf.impl.NetconfServerSessionListenerFactory;
-import org.opendaylight.controller.netconf.impl.NetconfServerSessionNegotiatorFactory;
-import org.opendaylight.controller.netconf.impl.SessionIdProvider;
import org.opendaylight.controller.netconf.impl.osgi.NetconfMonitoringServiceImpl;
import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListener;
import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListenerImpl;
import java.util.Collection;
import java.util.List;
import java.util.Set;
-import java.util.concurrent.TimeUnit;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
-public class NetconfMonitoringITTest extends AbstractConfigTest {
+public class NetconfMonitoringITTest extends AbstractNetconfConfigTest {
private static final Logger logger = LoggerFactory.getLogger(NetconfITTest.class);
@Mock
private DefaultCommitNotificationProducer commitNot;
private NetconfServerDispatcher dispatch;
- private EventLoopGroup nettyThreadgroup;
private NetconfClientDispatcher clientDispatcher;
.onAddNetconfOperationServiceFactory(new NetconfMonitoringActivator.NetconfMonitoringOperationServiceFactory(
new NetconfMonitoringOperationService(monitoringService)));
- nettyThreadgroup = new NioEventLoopGroup();
dispatch = createDispatcher(factoriesListener);
ChannelFuture s = dispatch.createServer(tcpAddress);
s.await();
- clientDispatcher = new NetconfClientDispatcher(nettyThreadgroup, nettyThreadgroup);
+ clientDispatcher = new NetconfClientDispatcher(nettyThreadgroup, nettyThreadgroup, 5000);
}
private HardcodedYangStoreService getYangStore() throws YangStoreException, IOException {
private NetconfServerDispatcher createDispatcher(
NetconfOperationServiceFactoryListenerImpl factoriesListener) {
- SessionIdProvider idProvider = new SessionIdProvider();
- NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory(
- new HashedWheelTimer(5000, TimeUnit.MILLISECONDS), factoriesListener, idProvider);
-
- NetconfServerSessionListenerFactory listenerFactory = new NetconfServerSessionListenerFactory(
- factoriesListener, commitNot, idProvider, getNetconfMonitoringListenerService(logger, monitoringService));
-
- NetconfServerDispatcher.ServerChannelInitializer serverChannelInitializer = new NetconfServerDispatcher.ServerChannelInitializer(
- serverNegotiatorFactory, listenerFactory);
- return new NetconfServerDispatcher(serverChannelInitializer, nettyThreadgroup, nettyThreadgroup);
+ return super.createDispatcher(factoriesListener, getNetconfMonitoringListenerService(logger, monitoringService), commitNot);
}
static SessionMonitoringService getNetconfMonitoringListenerService(final Logger logger, final NetconfMonitoringServiceImpl monitor) {
public abstract class AbstractNetconfSessionNegotiator<P extends NetconfSessionPreferences, S extends NetconfSession>
extends AbstractSessionNegotiator<NetconfMessage, S> {
- // TODO Adjust wait time for negotiation, now is 1 minute ?
- private static final long INITIAL_HOLDTIMER = 1;
-
private static final Logger logger = LoggerFactory.getLogger(AbstractNetconfSessionNegotiator.class);
public static final String NAME_OF_EXCEPTION_HANDLER = "lastExceptionHandler";
private State state = State.IDLE;
private final Timer timer;
+ private final long connectionTimeoutMillis;
protected AbstractNetconfSessionNegotiator(P sessionPreferences, Promise<S> promise, Channel channel, Timer timer,
- SessionListener sessionListener) {
+ SessionListener sessionListener, long connectionTimeoutMillis) {
super(promise, channel);
this.sessionPreferences = sessionPreferences;
this.timer = timer;
this.sessionListener = sessionListener;
+ this.connectionTimeoutMillis = connectionTimeoutMillis;
}
@Override
public void run(final Timeout timeout) throws Exception {
synchronized (this) {
if (state != State.ESTABLISHED) {
+ logger.debug("Connection timeout after {}", timeout);
final IllegalStateException cause = new IllegalStateException(
"Session was not established after " + timeout);
negotiationFailed(cause);
}
}
}
- }, INITIAL_HOLDTIMER, TimeUnit.MINUTES);
+ }, connectionTimeoutMillis, TimeUnit.MILLISECONDS);
sendMessage(helloMessage);
changeState(State.OPEN_WAIT);
package org.opendaylight.controller.netconf.util.handler;
+import com.google.common.base.Charsets;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
-
-import java.util.List;
-
import org.opendaylight.controller.netconf.util.messages.FramingMechanism;
import org.opendaylight.controller.netconf.util.messages.NetconfMessageConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.List;
+
public class NetconfMessageAggregator extends ByteToMessageDecoder {
private final static Logger logger = LoggerFactory.getLogger(NetconfMessageAggregator.class);
int index = indexOfSequence(in, eom);
if (index == -1) {
logger.debug("Message is not complete, read again.");
+ if (logger.isTraceEnabled()) {
+ String str = in.toString(Charsets.UTF_8);
+ logger.trace("Message read so far: {}", str);
+ }
ctx.read();
} else {
ByteBuf msg = in.readBytes(index);
package org.opendaylight.controller.netconf.util.osgi;
- import com.google.common.base.Optional;
- import java.net.InetSocketAddress;
- import org.osgi.framework.BundleContext;
- import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.base.Optional;
+import org.osgi.framework.BundleContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.InetSocketAddress;
+
+import static com.google.common.base.Preconditions.checkNotNull;
public class NetconfConfigUtil {
+ private static final Logger logger = LoggerFactory.getLogger(NetconfConfigUtil.class);
+
private static final String PREFIX_PROP = "netconf.";
+
+
private enum InfixProp {
tcp, ssh
}
private static final String CLIENT_PROP = ".client";
private static final String PRIVATE_KEY_PATH_PROP = ".pk.path";
+ private static final String CONNECTION_TIMEOUT_MILLIS_PROP = "connectionTimeoutMillis";
+ private static final long DEFAULT_TIMEOUT_MILLIS = 5000;
+
+ public static long extractTimeoutMillis(BundleContext bundleContext) {
+ String key = PREFIX_PROP + CONNECTION_TIMEOUT_MILLIS_PROP;
+ String timeoutString = bundleContext.getProperty(key);
+ if (timeoutString == null || timeoutString.length() == 0) {
+ return DEFAULT_TIMEOUT_MILLIS;
+ }
+ try {
+ return Long.parseLong(timeoutString);
+ }catch(NumberFormatException e) {
+ logger.warn("Cannot parse {} property: {}, using defaults", key, timeoutString, e);
+ return DEFAULT_TIMEOUT_MILLIS;
+ }
+ }
+
public static InetSocketAddress extractTCPNetconfAddress(BundleContext context, String exceptionMessageIfNotFound, boolean forClient) {
Optional<InetSocketAddress> inetSocketAddressOptional = extractSomeNetconfAddress(context, InfixProp.tcp, exceptionMessageIfNotFound, forClient);
this.myAppData = ByteBuffer
.allocate(session.getApplicationBufferSize());
this.peerAppData = ByteBuffer.allocate(session
- .getApplicationBufferSize());
+ .getApplicationBufferSize() * 2);
this.myNetData = ByteBuffer.allocate(session.getPacketBufferSize());
- this.peerNetData = ByteBuffer.allocate(session.getPacketBufferSize());
+ this.peerNetData = ByteBuffer.allocate(session.getPacketBufferSize() * 2);
}
@Override
salMatch.setField(new MatchField(MatchType.DL_VLAN,
vlan));
}
- if (ofMatch.getDataLayerVirtualLanPriorityCodePoint() != 0) {
+ if ((ofMatch.getWildcards() & OFMatch.OFPFW_DL_VLAN_PCP) == 0) {
salMatch.setField(MatchType.DL_VLAN_PR, ofMatch
.getDataLayerVirtualLanPriorityCodePoint());
}
salMatch.setField(new MatchField(MatchType.DL_VLAN,
vlan));
}
- if (v6Match.getDataLayerVirtualLanPriorityCodePoint() != 0) {
+ if ((v6Match.getWildcards() & OFMatch.OFPFW_DL_VLAN_PCP) == 0) {
salMatch.setField(MatchType.DL_VLAN_PR, v6Match
.getDataLayerVirtualLanPriorityCodePoint());
}
this.dlVlanIDState = MatchFieldState.MATCH_ABSENT;
}
- if (match.getDataLayerVirtualLanPriorityCodePoint() != 0) {
+ if ((match.getWildcards() & OFMatch.OFPFW_DL_VLAN_PCP) == 0) {
this.setDataLayerVirtualLanPriorityCodePoint(
match.getDataLayerVirtualLanPriorityCodePoint(), (byte) 0);
} else {
// extract the vlan id
super.setDataLayerVirtualLan(getVlanID(firstByte,
secondByte));
- } else {
this.wildcards ^= (1 << 1); // Sync with 0F 1.0 Match
}
if ((this.dataLayerVirtualLanTCIMask & 0xe000) != 0) {
// else if its a vlan pcp mask
// extract the vlan pcp
super.setDataLayerVirtualLanPriorityCodePoint(getVlanPCP(firstByte));
- } else {
this.wildcards ^= (1 << 20);
}
this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_WITH_MASK;
super.setDataLayerVirtualLan(getVlanID(firstByte, secondByte));
this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_ONLY;
this.match_len += 6;
+ this.wildcards ^= (1 << 1); // Sync with 0F 1.0 Match
+ this.wildcards ^= (1 << 20);
}
}
}
// ipv4 dest processing
this.wildcards ^= (((1 << 5) - 1) << 14);
}
- } else {
- this.wildcards = 0;
}
}
import org.junit.Assert;
import org.junit.Test;
import org.opendaylight.controller.protocol_plugin.openflow.vendorextension.v6extension.V6Match;
-import org.openflow.protocol.OFMatch;
-import org.openflow.protocol.action.OFAction;
-
import org.opendaylight.controller.sal.action.Action;
import org.opendaylight.controller.sal.action.Flood;
import org.opendaylight.controller.sal.action.FloodAll;
import org.opendaylight.controller.sal.utils.IPProtocols;
import org.opendaylight.controller.sal.utils.NodeConnectorCreator;
import org.opendaylight.controller.sal.utils.NodeCreator;
+import org.openflow.protocol.OFMatch;
+import org.openflow.protocol.action.OFAction;
+import org.openflow.util.U32;
public class FlowProgrammerServiceTest {
*/
FlowConverter salToOF = new FlowConverter(aFlow);
V6Match v6Match = (V6Match) salToOF.getOFMatch();
+ // need this hardcoding here to make the test pass.
+ // this should not be a problem in actual code.
+ // in the test the sal match is converted to a V6 match.
+ // we lose the wildcard info as the V6 match is used for nicira extensions
+ // and nicira deals with wildcards in a different way.
+ // converting the V6 match back to sal match is not going to preserve the wildcard info.
+ // and we need the wildcard info for reading the vlan pcp now.
+ // when creating a V6Match using the readFrom method
+ // we do convert the nicira extensions format correctly to populate the wildcard info.
+ v6Match.setWildcards(U32.t(Long.valueOf(~OFMatch.OFPFW_DL_VLAN_PCP)));
List<OFAction> ofActions = salToOF.getOFActions();
/*
import org.junit.Assert;
import org.junit.Test;
import org.openflow.protocol.OFMatch;
+import org.openflow.util.U32;
public class V6ExtensionTest {
match.fromString("input_port=1");
match.fromString("dl_dst=20:A0:11:10:00:99");
match.fromString("dl_src=00:10:08:22:12:75");
-
match.fromString("ip_src=10.1.1.1");
match.fromString("ip_dst=1.2.3.4");
match.fromString("eth_type=0x800");
match.fromString("dl_vlan=10");
- match.fromString("dl_vpcp=1");
match.fromString("nw_proto=6");
match.fromString("nw_tos=100");
match.fromString("tp_dst=8080");
match.fromString("tp_src=60");
+ match.fromString("dl_vpcp=1");
Assert.assertTrue(match.getInputPort() == 1);
// Assert.assertTrue(match.getIPv6MatchLen()==6);
-
ofm.setInputPort((short) 1);
// V6Match is meant for IPv6, but if using OFMatch, it will be set to
// IPv4 values, as OF1.0 doesn't support IPv6.
ofm.setTransportSource((short) 60);
ofm.setTransportDestination((short) 8080);
+ // this v6match ctor now looks at the wildcard field to
+ // determine if vlan pcp has been set
+ // so set the wildcards appropriately to reflect that vlan pcp
+ // has been set.
+ int wildcards = OFMatch.OFPFW_ALL;
+ wildcards &= ~OFMatch.OFPFW_DL_VLAN_PCP;
+ ofm.setWildcards(U32.t(Long.valueOf(wildcards)));
V6Match match3 = new V6Match(ofm);
Assert.assertTrue(match.getInputPort() == match3.getInputPort());
one.lib.helper = {
parseInt : function(value) {
- return (value !== null && value !== '') ?
+ return (value != null && value.trim() !== '') ?
parseInt(value) : ''
},
parseFloat : function(value) {
- return (value !== null && value !== '') ?
+ return (value != null && value.trim() !== '') ?
parseFloat(value) : ''
}
}
public class Troubleshoot implements IDaylightWeb {
private static final UserLevel AUTH_LEVEL = UserLevel.CONTAINERUSER;
private static final List<String> flowStatsColumnNames = Arrays.asList("Node", "In Port",
- "DL Src", "DL Dst", "DL Type", "DL Vlan", "NW Src", "NW Dst","ToS Bits",
+ "DL Src", "DL Dst", "DL Type", "DL Vlan","Vlan Priority", "NW Src", "NW Dst","ToS Bits",
"NW Proto", "TP Src", "TP Dst", "Actions", "Bytes", "Packets",
"Time (s)", "Timeout (s)",
"Priority");
} else {
row.put(MatchType.DL_VLAN.id(), "*");
}
+ //Vlan Priority
+ if (match.isPresent(MatchType.DL_VLAN_PR)) {
+ if (((Byte) flow.getMatch().getField(MatchType.DL_VLAN_PR).getValue())
+ .shortValue() < 0) {
+ row.put(MatchType.DL_VLAN_PR.id(), "0");
+ } else {
+ row.put(MatchType.DL_VLAN_PR.id(), ((Byte) flow.getMatch()
+ .getField(MatchType.DL_VLAN_PR).getValue()).toString());
+ }
+ } else {
+ row.put(MatchType.DL_VLAN_PR.id(), "*");
+ }
+
if (match.isPresent(MatchType.NW_SRC)) {
row.put(MatchType.NW_SRC.id(), ((InetAddress) flow.getMatch()
.getField(MatchType.NW_SRC).getValue()).getHostAddress());
row.put("durationSeconds",
((Integer) flowOnNode.getDurationSeconds()).toString());
row.put("idleTimeout", ((Short) flow.getIdleTimeout()).toString());
- row.put("priority", String.valueOf(flow.getPriority()));
+ row.put("priority", String.valueOf(NetUtils.getUnsignedShort(flow.getPriority())));
return row;
}
label: 'DL Vlan',
sortable: true
},
+ {
+ property: 'dlVlanPriority',
+ label: 'Vlan PCP',
+ sortable: true
+ },
{
property: 'nwSrc',
label: 'NW Src',