/**
* NetconfMessage that can carry additional header with session metadata.
- * See {@link NetconfHelloMessageAdditionalHeader}
+ *
+ * @see NetconfHelloMessageAdditionalHeader
*/
public final class NetconfHelloMessage extends NetconfMessage {
import io.netty.channel.EventLoopGroup;
import io.netty.util.Timer;
import io.netty.util.concurrent.Future;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
import org.opendaylight.netconf.client.conf.NetconfClientConfiguration;
import org.opendaylight.netconf.client.conf.NetconfReconnectingClientConfiguration;
import org.opendaylight.protocol.framework.AbstractDispatcher;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
}
protected NetconfClientSessionNegotiatorFactory getNegotiatorFactory(final NetconfClientConfiguration cfg) {
- return new NetconfClientSessionNegotiatorFactory(timer, cfg.getAdditionalHeader(),
- cfg.getConnectionTimeoutMillis());
+ final List<Uri> odlHelloCapabilities = cfg.getOdlHelloCapabilities();
+ if (odlHelloCapabilities == null || odlHelloCapabilities.isEmpty()) {
+ return new NetconfClientSessionNegotiatorFactory(timer, cfg.getAdditionalHeader(),
+ cfg.getConnectionTimeoutMillis());
+ } else {
+ // LinkedHashSet since perhaps the device cares about order of hello message capabilities.
+ // This allows user control of the order while complying with the existing interface.
+ final Set<String> stringCapabilities = new LinkedHashSet<>();
+ for (final Uri uri : odlHelloCapabilities) {
+ stringCapabilities.add(uri.getValue());
+ }
+ return new NetconfClientSessionNegotiatorFactory(timer, cfg.getAdditionalHeader(),
+ cfg.getConnectionTimeoutMillis(), stringCapabilities);
+ }
}
}
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import java.net.InetSocketAddress;
+import java.util.List;
import org.opendaylight.netconf.api.messages.NetconfHelloMessageAdditionalHeader;
import org.opendaylight.netconf.client.NetconfClientSessionListener;
import org.opendaylight.netconf.client.SslHandlerFactory;
import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
import org.opendaylight.protocol.framework.ReconnectStrategy;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private final AuthenticationHandler authHandler;
private final SslHandlerFactory sslHandlerFactory;
+ private final List<Uri> odlHelloCapabilities;
+
NetconfClientConfiguration(final NetconfClientProtocol protocol, final InetSocketAddress address,
final Long connectionTimeoutMillis,
final NetconfHelloMessageAdditionalHeader additionalHeader,
final NetconfClientSessionListener sessionListener,
final ReconnectStrategy reconnectStrategy, final AuthenticationHandler authHandler,
- final SslHandlerFactory sslHandlerFactory) {
+ final SslHandlerFactory sslHandlerFactory,
+ final List<Uri> odlHelloCapabilities) {
this.address = address;
this.connectionTimeoutMillis = connectionTimeoutMillis;
this.additionalHeader = additionalHeader;
this.reconnectStrategy = reconnectStrategy;
this.authHandler = authHandler;
this.sslHandlerFactory = sslHandlerFactory;
+ this.odlHelloCapabilities = odlHelloCapabilities;
validateConfiguration();
}
return sslHandlerFactory;
}
+ public List<Uri> getOdlHelloCapabilities() {
+ return odlHelloCapabilities;
+ }
+
private void validateConfiguration() {
Preconditions.checkNotNull(clientProtocol, " ");
switch (clientProtocol) {
package org.opendaylight.netconf.client.conf;
import java.net.InetSocketAddress;
+import java.util.List;
import org.opendaylight.netconf.api.messages.NetconfHelloMessageAdditionalHeader;
import org.opendaylight.netconf.client.NetconfClientSessionListener;
import org.opendaylight.netconf.client.SslHandlerFactory;
import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
import org.opendaylight.protocol.framework.ReconnectStrategy;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
public class NetconfClientConfigurationBuilder {
private AuthenticationHandler authHandler;
private NetconfClientConfiguration.NetconfClientProtocol clientProtocol = DEFAULT_CLIENT_PROTOCOL;
private SslHandlerFactory sslHandlerFactory;
+ private List<Uri> odlHelloCapabilities;
+
protected NetconfClientConfigurationBuilder() {
}
return this;
}
+ @SuppressWarnings("checkstyle:hiddenField")
+ public NetconfClientConfigurationBuilder withOdlHelloCapabilities(final List<Uri> odlHelloCapabilities) {
+ this.odlHelloCapabilities = odlHelloCapabilities;
+ return this;
+ }
+
final InetSocketAddress getAddress() {
return address;
}
return sslHandlerFactory;
}
+ final List<Uri> getOdlHelloCapabilities() {
+ return odlHelloCapabilities;
+ }
+
public NetconfClientConfiguration build() {
return new NetconfClientConfiguration(clientProtocol, address, connectionTimeoutMillis, additionalHeader,
- sessionListener, reconnectStrategy, authHandler, sslHandlerFactory);
+ sessionListener, reconnectStrategy, authHandler, sslHandlerFactory, odlHelloCapabilities);
}
}
import com.google.common.base.MoreObjects.ToStringHelper;
import com.google.common.base.Preconditions;
import java.net.InetSocketAddress;
+import java.util.List;
import org.opendaylight.netconf.api.messages.NetconfHelloMessageAdditionalHeader;
import org.opendaylight.netconf.client.NetconfClientSessionListener;
import org.opendaylight.netconf.client.SslHandlerFactory;
import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
import org.opendaylight.protocol.framework.ReconnectStrategy;
import org.opendaylight.protocol.framework.ReconnectStrategyFactory;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
public final class NetconfReconnectingClientConfiguration extends NetconfClientConfiguration {
final ReconnectStrategy reconnectStrategy,
final ReconnectStrategyFactory connectStrategyFactory,
final AuthenticationHandler authHandler,
- final SslHandlerFactory sslHandlerFactory) {
+ final SslHandlerFactory sslHandlerFactory,
+ final List<Uri> odlHelloCapabilities) {
super(clientProtocol, address, connectionTimeoutMillis, additionalHeader, sessionListener, reconnectStrategy,
- authHandler, sslHandlerFactory);
+ authHandler, sslHandlerFactory, odlHelloCapabilities);
this.connectStrategyFactory = connectStrategyFactory;
validateReconnectConfiguration();
}
package org.opendaylight.netconf.client.conf;
import java.net.InetSocketAddress;
+import java.util.List;
import org.opendaylight.netconf.api.messages.NetconfHelloMessageAdditionalHeader;
import org.opendaylight.netconf.client.NetconfClientSessionListener;
import org.opendaylight.netconf.client.SslHandlerFactory;
import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
import org.opendaylight.protocol.framework.ReconnectStrategy;
import org.opendaylight.protocol.framework.ReconnectStrategyFactory;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
public final class NetconfReconnectingClientConfigurationBuilder extends NetconfClientConfigurationBuilder {
public NetconfReconnectingClientConfiguration build() {
return new NetconfReconnectingClientConfiguration(getProtocol(), getAddress(), getConnectionTimeoutMillis(),
getAdditionalHeader(), getSessionListener(), getReconnectStrategy(), connectStrategyFactory,
- getAuthHandler(), getSslHandlerFactory());
+ getAuthHandler(), getSslHandlerFactory(), getOdlHelloCapabilities());
}
// Override setter methods to return subtype
final SslHandlerFactory sslHandlerFactory) {
return (NetconfReconnectingClientConfigurationBuilder) super.withSslHandlerFactory(sslHandlerFactory);
}
+
+ @Override
+ public NetconfReconnectingClientConfigurationBuilder withOdlHelloCapabilities(List<Uri> odlHelloCapabilities) {
+ return (NetconfReconnectingClientConfigurationBuilder) super.withOdlHelloCapabilities(odlHelloCapabilities);
+ }
}
default 5;
description "Time that slave actor will wait for response from master.";
}
+
+ container odl-hello-message-capabilities {
+ config true;
+ leaf-list capability {
+ type inet:uri;
+ description "Certain devices are non-accepting of ODL's hello message. This allows specification of
+ a custom ODL hello message based on a list of supported capabilities.";
+ }
+ }
}
grouping netconf-node-connection-status {
import org.opendaylight.protocol.framework.TimedReconnectStrategy;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.parameters.OdlHelloMessageCapabilities;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.available.capabilities.AvailableCapability.CapabilityOrigin;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.Credentials;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.credentials.KeyAuth;
final AuthenticationHandler authHandler = getHandlerFromCredentials(node.getCredentials());
- return NetconfReconnectingClientConfigurationBuilder.create()
- .withAddress(socketAddress)
- .withConnectionTimeoutMillis(clientConnectionTimeoutMillis)
- .withReconnectStrategy(strategy)
- .withAuthHandler(authHandler)
- .withProtocol(node.isTcpOnly()
- ? NetconfClientConfiguration.NetconfClientProtocol.TCP
- : NetconfClientConfiguration.NetconfClientProtocol.SSH)
- .withConnectStrategyFactory(sf)
- .withSessionListener(listener)
- .build();
+ final NetconfReconnectingClientConfigurationBuilder builder =
+ NetconfReconnectingClientConfigurationBuilder.create()
+ .withAddress(socketAddress)
+ .withConnectionTimeoutMillis(clientConnectionTimeoutMillis)
+ .withReconnectStrategy(strategy)
+ .withAuthHandler(authHandler)
+ .withProtocol(node.isTcpOnly()
+ ? NetconfClientConfiguration.NetconfClientProtocol.TCP
+ : NetconfClientConfiguration.NetconfClientProtocol.SSH)
+ .withConnectStrategyFactory(sf)
+ .withSessionListener(listener);
+
+ final List<Uri> odlHelloCapabilities = getOdlHelloCapabilities(node);
+ if (odlHelloCapabilities != null) {
+ builder.withOdlHelloCapabilities(odlHelloCapabilities);
+ }
+ return builder.build();
+ }
+
+ private List<Uri> getOdlHelloCapabilities(final NetconfNode node) {
+ final OdlHelloMessageCapabilities helloCapabilities = node.getOdlHelloMessageCapabilities();
+ if (helloCapabilities != null) {
+ return helloCapabilities.getCapability();
+ }
+ return null;
}
private AuthenticationHandler getHandlerFromCredentials(final Credentials credentials) {
default 5;
description "Time that slave actor will wait for response from master.";
}
+
+ container odl-hello-message-capabilities {
+ config true;
+ leaf-list capability {
+ type inet:uri;
+ description "Certain devices are non-accepting of ODL's hello message. This allows specification of
+ a custom ODL hello message based on a list of supported capabilities.";
+ }
+ }
}
grouping netconf-node-connection-status {
}
}
- grouping netconf-node-credentials {
+ grouping username-password {
+ leaf username {
+ type string;
+ }
+ leaf password {
+ type string;
+ }
+ }
+
+ grouping netconf-node-credentials {
choice credentials {
config true;
case login-password {
- leaf username {
- type string;
+ description "Deprecated way of storing credentials, unencrypted.";
+
+ status deprecated;
+ uses username-password;
+ }
+ case login-pw {
+ description "login-password credentials, encrypted.";
+
+ container login-password {
+ uses username-password;
}
+ }
+ case login-pw-unencrypted {
+ description "login-password credentials, not encrypted.";
- leaf password {
- type string;
+ container login-password-unencrypted {
+ uses username-password;
+ }
+ }
+ case key-auth {
+ description "key-based authentication, use the id for the pair thats stored in the keystore.";
+
+ container key-based {
+ leaf key-id {
+ type string;
+ }
+
+ leaf username {
+ type string;
+ }
}
}
}
description "Limit of concurrent messages that can be send before reply messages are received.
If value <1 is provided, no limit will be enforced";
}
+
+ leaf actor-response-wait-time {
+ config true;
+ type uint16 {
+ range "1..max";
+ }
+ default 5;
+ description "Time that slave actor will wait for response from master.";
+ }
+
+ container odl-hello-message-capabilities {
+ config true;
+ leaf-list capability {
+ type inet:uri;
+ description "Certain devices are non-accepting of ODL's hello message. This allows specification of
+ a custom ODL hello message based on a list of supported capabilities.";
+ }
+ }
}
grouping netconf-node-connection-status {
}
}
}
+ leaf netconf-master-node {
+ config false;
+ type string;
+ }
}
leaf connected-message {
}
+ rpc create-device {
+ input {
+ uses netconf-node-fields;
+ leaf node-id {
+ type string;
+ }
+ }
+ }
+
+ rpc delete-device {
+ input {
+ leaf node-id {
+ type string;
+ }
+ }
+ }
+
augment "/nt:network-topology/nt:topology/nt:node" {
when "../../nt:topology-types/topology-netconf";
ext:augment-identifier "netconf-node";
uses netconf-node-fields;
}
-}
\ No newline at end of file
+
+}