X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=netconf%2Fnetconf-topology-singleton%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fnetconf%2Ftopology%2Fsingleton%2Fimpl%2FRemoteDeviceConnectorImpl.java;h=0de0ea6bc3d39bc6921b985382b7c66e4c1035ac;hb=90dcdd5d040eb22b74e87baccffd70a30d93bfc0;hp=8ff961885e0c027cb215427d8e3fe7a222725c9f;hpb=9c0c58cd36aa84dfa5366acb17b1e74fb98ffce5;p=netconf.git diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/RemoteDeviceConnectorImpl.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/RemoteDeviceConnectorImpl.java index 8ff961885e..0de0ea6bc3 100644 --- a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/RemoteDeviceConnectorImpl.java +++ b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/RemoteDeviceConnectorImpl.java @@ -5,12 +5,12 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ - package org.opendaylight.netconf.topology.singleton.impl; +import static com.google.common.base.Preconditions.checkState; +import static java.util.Objects.requireNonNull; + import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Preconditions; -import com.google.common.collect.Lists; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; @@ -21,9 +21,7 @@ import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.Optional; -import javax.annotation.Nullable; import org.opendaylight.aaa.encrypt.AAAEncryptionService; import org.opendaylight.netconf.api.NetconfMessage; import org.opendaylight.netconf.client.NetconfClientSessionListener; @@ -34,6 +32,7 @@ import org.opendaylight.netconf.nettyutil.ReconnectStrategyFactory; import org.opendaylight.netconf.nettyutil.TimedReconnectStrategyFactory; import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler; import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.LoginPasswordHandler; +import org.opendaylight.netconf.sal.connect.api.DeviceActionFactory; import org.opendaylight.netconf.sal.connect.api.RemoteDevice; import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler; import org.opendaylight.netconf.sal.connect.netconf.LibraryModulesSchemas; @@ -51,11 +50,10 @@ import org.opendaylight.netconf.sal.connect.netconf.schema.YangLibrarySchemaYang import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId; import org.opendaylight.netconf.sal.connect.util.SslHandlerFactoryImpl; import org.opendaylight.netconf.topology.singleton.api.RemoteDeviceConnector; -import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfConnectorDTO; import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologySetup; import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologyUtils; -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.netconf.topology.spi.NetconfConnectorDTO; +import org.opendaylight.netconf.topology.spi.NetconfNodeUtils; 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; @@ -69,6 +67,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev15 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.credentials.login.pw.LoginPassword; import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.credentials.login.pw.unencrypted.LoginPasswordUnencrypted; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.opendaylight.yangtools.yang.common.Decimal64; import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier; import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource; import org.opendaylight.yangtools.yang.model.repo.spi.PotentialSchemaSource; @@ -88,17 +87,21 @@ public class RemoteDeviceConnectorImpl implements RemoteDeviceConnector { private final String privateKeyPath; private final String privateKeyPassphrase; private final AAAEncryptionService encryptionService; - private NetconfConnectorDTO deviceCommunicatorDTO; private final NetconfKeystoreAdapter keystoreAdapter; + private final DeviceActionFactory deviceActionFactory; - public RemoteDeviceConnectorImpl(final NetconfTopologySetup netconfTopologyDeviceSetup, - final RemoteDeviceId remoteDeviceId) { + // FIXME: this seems to be a builder-like transition between {start,stop}RemoteDeviceConnection. More documentation + // is needed, as to what the lifecycle is here. + private NetconfConnectorDTO deviceCommunicatorDTO; - this.netconfTopologyDeviceSetup = Preconditions.checkNotNull(netconfTopologyDeviceSetup); + public RemoteDeviceConnectorImpl(final NetconfTopologySetup netconfTopologyDeviceSetup, + final RemoteDeviceId remoteDeviceId, final DeviceActionFactory deviceActionFactory) { + this.netconfTopologyDeviceSetup = requireNonNull(netconfTopologyDeviceSetup); this.remoteDeviceId = remoteDeviceId; - this.privateKeyPath = netconfTopologyDeviceSetup.getPrivateKeyPath(); - this.privateKeyPassphrase = netconfTopologyDeviceSetup.getPrivateKeyPassphrase(); - this.encryptionService = netconfTopologyDeviceSetup.getEncryptionService(); + this.deviceActionFactory = requireNonNull(deviceActionFactory); + privateKeyPath = netconfTopologyDeviceSetup.getPrivateKeyPath(); + privateKeyPassphrase = netconfTopologyDeviceSetup.getPrivateKeyPassphrase(); + encryptionService = netconfTopologyDeviceSetup.getEncryptionService(); keystoreAdapter = new NetconfKeystoreAdapter(netconfTopologyDeviceSetup.getDataBroker()); } @@ -107,11 +110,10 @@ public class RemoteDeviceConnectorImpl implements RemoteDeviceConnector { final NetconfNode netconfNode = netconfTopologyDeviceSetup.getNode().augmentation(NetconfNode.class); final NodeId nodeId = netconfTopologyDeviceSetup.getNode().getNodeId(); - Preconditions.checkNotNull(netconfNode.getHost()); - Preconditions.checkNotNull(netconfNode.getPort()); - Preconditions.checkNotNull(netconfNode.isTcpOnly()); + requireNonNull(netconfNode.getHost()); + requireNonNull(netconfNode.getPort()); - this.deviceCommunicatorDTO = createDeviceCommunicator(nodeId, netconfNode, deviceHandler); + deviceCommunicatorDTO = createDeviceCommunicator(nodeId, netconfNode, deviceHandler); final NetconfDeviceCommunicator deviceCommunicator = deviceCommunicatorDTO.getCommunicator(); final NetconfClientSessionListener netconfClientSessionListener = deviceCommunicatorDTO.getSessionListener(); final NetconfReconnectingClientConfiguration clientConfig = @@ -126,7 +128,7 @@ public class RemoteDeviceConnectorImpl implements RemoteDeviceConnector { } @Override - public void onFailure(@Nullable final Throwable throwable) { + public void onFailure(final Throwable throwable) { LOG.error("{}: Connector failed", remoteDeviceId, throwable); } }, MoreExecutors.directExecutor()); @@ -149,13 +151,13 @@ public class RemoteDeviceConnectorImpl implements RemoteDeviceConnector { final RemoteDeviceHandler deviceHandler) { //setup default values since default value is not supported in mdsal final long defaultRequestTimeoutMillis = node.getDefaultRequestTimeoutMillis() == null - ? NetconfTopologyUtils.DEFAULT_REQUEST_TIMEOUT_MILLIS : node.getDefaultRequestTimeoutMillis(); + ? NetconfTopologyUtils.DEFAULT_REQUEST_TIMEOUT_MILLIS : node.getDefaultRequestTimeoutMillis().toJava(); final long keepaliveDelay = node.getKeepaliveDelay() == null - ? NetconfTopologyUtils.DEFAULT_KEEPALIVE_DELAY : node.getKeepaliveDelay(); - final boolean reconnectOnChangedSchema = node.isReconnectOnChangedSchema() == null - ? NetconfTopologyUtils.DEFAULT_RECONNECT_ON_CHANGED_SCHEMA : node.isReconnectOnChangedSchema(); + ? NetconfTopologyUtils.DEFAULT_KEEPALIVE_DELAY : node.getKeepaliveDelay().toJava(); + final boolean reconnectOnChangedSchema = node.getReconnectOnChangedSchema() == null + ? NetconfTopologyUtils.DEFAULT_RECONNECT_ON_CHANGED_SCHEMA : node.getReconnectOnChangedSchema(); - RemoteDeviceHandler salFacade = deviceHandler; + RemoteDeviceHandler salFacade = requireNonNull(deviceHandler); if (keepaliveDelay > 0) { LOG.info("{}: Adding keepalive facade.", remoteDeviceId); salFacade = new KeepaliveSalFacade(remoteDeviceId, salFacade, @@ -166,7 +168,7 @@ public class RemoteDeviceConnectorImpl implements RemoteDeviceConnector { final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO = netconfTopologyDeviceSetup.getSchemaResourcesDTO(); // pre register yang library sources as fallback schemas to schema registry - final List> registeredYangLibSources = Lists.newArrayList(); + final List> registeredYangLibSources = new ArrayList<>(); if (node.getYangLibrary() != null) { final String yangLibURL = node.getYangLibrary().getYangLibraryUrl().getValue(); final String yangLibUsername = node.getYangLibrary().getUsername(); @@ -194,14 +196,17 @@ public class RemoteDeviceConnectorImpl implements RemoteDeviceConnector { } final RemoteDevice device; - if (node.isSchemaless()) { - device = new SchemalessNetconfDevice(remoteDeviceId, salFacade); + if (node.getSchemaless()) { + device = new SchemalessNetconfDevice(netconfTopologyDeviceSetup.getBaseSchemas(), remoteDeviceId, + salFacade); } else { device = new NetconfDeviceBuilder() .setReconnectOnSchemasChange(reconnectOnChangedSchema) .setSchemaResourcesDTO(schemaResourcesDTO) .setGlobalProcessingExecutor(netconfTopologyDeviceSetup.getProcessingExecutor()) + .setBaseSchemas(netconfTopologyDeviceSetup.getBaseSchemas()) .setId(remoteDeviceId) + .setDeviceActionFactory(deviceActionFactory) .setSalFacade(salFacade) .build(); } @@ -209,25 +214,23 @@ public class RemoteDeviceConnectorImpl implements RemoteDeviceConnector { final Optional userCapabilities = getUserCapabilities(node); final int rpcMessageLimit = node.getConcurrentRpcLimit() == null - ? NetconfTopologyUtils.DEFAULT_CONCURRENT_RPC_LIMIT : node.getConcurrentRpcLimit(); + ? NetconfTopologyUtils.DEFAULT_CONCURRENT_RPC_LIMIT : node.getConcurrentRpcLimit().toJava(); if (rpcMessageLimit < 1) { LOG.info("{}: Concurrent rpc limit is smaller than 1, no limit will be enforced.", remoteDeviceId); } - NetconfDeviceCommunicator netconfDeviceCommunicator = - userCapabilities.isPresent() ? new NetconfDeviceCommunicator(remoteDeviceId, device, - new UserPreferences(userCapabilities.get(), - Objects.isNull(node.getYangModuleCapabilities()) - ? false : node.getYangModuleCapabilities().isOverride(), - Objects.isNull(node.getNonModuleCapabilities()) - ? false : node.getNonModuleCapabilities().isOverride()), rpcMessageLimit) + NetconfDeviceCommunicator netconfDeviceCommunicator = userCapabilities.isPresent() + ? new NetconfDeviceCommunicator(remoteDeviceId, device, new UserPreferences(userCapabilities.get(), + node.getYangModuleCapabilities() == null ? false : node.getYangModuleCapabilities().getOverride(), + node.getNonModuleCapabilities() == null ? false : node.getNonModuleCapabilities().getOverride()), + rpcMessageLimit) : new NetconfDeviceCommunicator(remoteDeviceId, device, rpcMessageLimit); if (salFacade instanceof KeepaliveSalFacade) { ((KeepaliveSalFacade)salFacade).setListener(netconfDeviceCommunicator); } - return new NetconfConnectorDTO(netconfDeviceCommunicator, salFacade); + return new NetconfConnectorDTO(netconfDeviceCommunicator, salFacade, registeredYangLibSources); } private static Optional getUserCapabilities(final NetconfNode node) { @@ -242,7 +245,7 @@ public class RemoteDeviceConnectorImpl implements RemoteDeviceConnector { //non-module capabilities should not exist in yang module capabilities final NetconfSessionPreferences netconfSessionPreferences = NetconfSessionPreferences.fromStrings(capabilities); - Preconditions.checkState(netconfSessionPreferences.getNonModuleCaps().isEmpty(), + checkState(netconfSessionPreferences.getNonModuleCaps().isEmpty(), "List yang-module-capabilities/capability should contain only module based capabilities. " + "Non-module capabilities used: " + netconfSessionPreferences.getNonModuleCaps()); @@ -253,42 +256,33 @@ public class RemoteDeviceConnectorImpl implements RemoteDeviceConnector { return Optional.of(NetconfSessionPreferences.fromStrings(capabilities, CapabilityOrigin.UserDefined)); } - //TODO: duplicate code - private static InetSocketAddress getSocketAddress(final Host host, final int port) { - if (host.getDomainName() != null) { - return new InetSocketAddress(host.getDomainName().getValue(), port); - } else { - final IpAddress ipAddress = host.getIpAddress(); - final String ip = ipAddress.getIpv4Address() != null ? ipAddress.getIpv4Address().getValue() : - ipAddress.getIpv6Address().getValue(); - return new InetSocketAddress(ip, port); - } - } - @VisibleForTesting NetconfReconnectingClientConfiguration getClientConfig(final NetconfClientSessionListener listener, final NetconfNode node) { //setup default values since default value is not supported in mdsal final long clientConnectionTimeoutMillis = node.getConnectionTimeoutMillis() == null - ? NetconfTopologyUtils.DEFAULT_CONNECTION_TIMEOUT_MILLIS : node.getConnectionTimeoutMillis(); + ? NetconfTopologyUtils.DEFAULT_CONNECTION_TIMEOUT_MILLIS : node.getConnectionTimeoutMillis().toJava(); final long maxConnectionAttempts = node.getMaxConnectionAttempts() == null - ? NetconfTopologyUtils.DEFAULT_MAX_CONNECTION_ATTEMPTS : node.getMaxConnectionAttempts(); + ? NetconfTopologyUtils.DEFAULT_MAX_CONNECTION_ATTEMPTS : node.getMaxConnectionAttempts().toJava(); final int betweenAttemptsTimeoutMillis = node.getBetweenAttemptsTimeoutMillis() == null - ? NetconfTopologyUtils.DEFAULT_BETWEEN_ATTEMPTS_TIMEOUT_MILLIS : node.getBetweenAttemptsTimeoutMillis(); - final BigDecimal sleepFactor = node.getSleepFactor() == null + ? NetconfTopologyUtils.DEFAULT_BETWEEN_ATTEMPTS_TIMEOUT_MILLIS + : node.getBetweenAttemptsTimeoutMillis().toJava(); + final boolean isTcpOnly = node.getTcpOnly() == null + ? NetconfTopologyUtils.DEFAULT_IS_TCP_ONLY : node.getTcpOnly(); + final Decimal64 sleepFactor = node.getSleepFactor() == null ? NetconfTopologyUtils.DEFAULT_SLEEP_FACTOR : node.getSleepFactor(); - final InetSocketAddress socketAddress = getSocketAddress(node.getHost(), node.getPort().getValue()); + final InetSocketAddress socketAddress = NetconfNodeUtils.toInetSocketAddress(node); final ReconnectStrategyFactory sf = - new TimedReconnectStrategyFactory(netconfTopologyDeviceSetup.getEventExecutor(), maxConnectionAttempts, - betweenAttemptsTimeoutMillis, sleepFactor); + new TimedReconnectStrategyFactory(netconfTopologyDeviceSetup.getEventExecutor(), maxConnectionAttempts, + betweenAttemptsTimeoutMillis, BigDecimal.valueOf(sleepFactor.unscaledValue(), sleepFactor.scale())); final NetconfReconnectingClientConfigurationBuilder reconnectingClientConfigurationBuilder; final Protocol protocol = node.getProtocol(); - if (node.isTcpOnly()) { + if (isTcpOnly) { reconnectingClientConfigurationBuilder = NetconfReconnectingClientConfigurationBuilder.create() .withProtocol(NetconfClientConfiguration.NetconfClientProtocol.TCP) .withAuthHandler(getHandlerFromCredentials(node.getCredentials())); @@ -320,7 +314,7 @@ public class RemoteDeviceConnectorImpl implements RemoteDeviceConnector { private static List getOdlHelloCapabilities(final NetconfNode node) { final OdlHelloMessageCapabilities helloCapabilities = node.getOdlHelloMessageCapabilities(); - return helloCapabilities != null ? helloCapabilities.getCapability() : null; + return helloCapabilities != null ? List.copyOf(helloCapabilities.getCapability()) : null; } private AuthenticationHandler getHandlerFromCredentials(final Credentials credentials) {