Separate out DeviceSources(Resolver) 91/83991/8
authorRobert Varga <robert.varga@pantheon.tech>
Mon, 26 Aug 2019 13:38:45 +0000 (15:38 +0200)
committerRobert Varga <nite@hq.sk>
Wed, 28 Aug 2019 15:12:28 +0000 (15:12 +0000)
NetconfDevice is quite overloaded, making it unclear what methods
participate on each stage of context assebly. This separates out
DeviceSourcesResolver, so that the logic inside it is well contained
outside of NetconfDevice.

Change-Id: I3f05a73470f0c3b15fc6a111202bd5e0dacb92d3
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/DeviceSources.java [new file with mode: 0644]
netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/DeviceSourcesResolver.java [new file with mode: 0644]
netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/NetconfDevice.java

diff --git a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/DeviceSources.java b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/DeviceSources.java
new file mode 100644 (file)
index 0000000..132468f
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech, s.r.o. 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.netconf.sal.connect.netconf;
+
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.collect.Collections2;
+import java.util.Collection;
+import java.util.Set;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier;
+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.SchemaSourceProvider;
+
+/**
+ * Contains RequiredSources - sources from capabilities.
+ */
+final class DeviceSources {
+    private final Set<QName> requiredSources;
+    private final Set<QName> providedSources;
+    private final SchemaSourceProvider<YangTextSchemaSource> sourceProvider;
+
+    DeviceSources(final Set<QName> requiredSources, final Set<QName> providedSources,
+            final SchemaSourceProvider<YangTextSchemaSource> sourceProvider) {
+        this.requiredSources = requireNonNull(requiredSources);
+        this.providedSources = requireNonNull(providedSources);
+        this.sourceProvider = requireNonNull(sourceProvider);
+    }
+
+    Set<QName> getRequiredSourcesQName() {
+        return requiredSources;
+    }
+
+    Set<QName> getProvidedSourcesQName() {
+        return providedSources;
+    }
+
+    Collection<SourceIdentifier> getRequiredSources() {
+        return Collections2.transform(requiredSources, DeviceSources::toSourceId);
+    }
+
+    Collection<SourceIdentifier> getProvidedSources() {
+        return Collections2.transform(providedSources, DeviceSources::toSourceId);
+    }
+
+    SchemaSourceProvider<YangTextSchemaSource> getSourceProvider() {
+        return sourceProvider;
+    }
+
+    private static SourceIdentifier toSourceId(final QName input) {
+        return RevisionSourceIdentifier.create(input.getLocalName(), input.getRevision());
+    }
+}
\ No newline at end of file
diff --git a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/DeviceSourcesResolver.java b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/DeviceSourcesResolver.java
new file mode 100644 (file)
index 0000000..771d5a9
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech, s.r.o. 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.netconf.sal.connect.netconf;
+
+import static java.util.Objects.requireNonNull;
+import static org.opendaylight.netconf.sal.connect.netconf.NetconfDevice.LOG;
+
+import com.google.common.collect.Sets;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import org.opendaylight.netconf.sal.connect.api.NetconfDeviceSchemas;
+import org.opendaylight.netconf.sal.connect.api.NetconfDeviceSchemasResolver;
+import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
+import org.opendaylight.netconf.sal.connect.netconf.sal.NetconfDeviceRpc;
+import org.opendaylight.netconf.sal.connect.netconf.schema.NetconfRemoteSchemaYangSourceProvider;
+import org.opendaylight.netconf.sal.connect.netconf.schema.YangLibrarySchemaYangSourceProvider;
+import org.opendaylight.netconf.sal.connect.netconf.schema.mapping.BaseSchema;
+import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
+import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceProvider;
+
+/**
+ * Schema building callable.
+ */
+final class DeviceSourcesResolver implements Callable<DeviceSources> {
+    private final NetconfSessionPreferences remoteSessionCapabilities;
+    private final NetconfDeviceSchemasResolver stateSchemasResolver;
+    private final NetconfDeviceRpc deviceRpc;
+    private final BaseSchema baseSchema;
+    private final RemoteDeviceId id;
+
+    DeviceSourcesResolver(final RemoteDeviceId id, final BaseSchema baseSchema, final NetconfDeviceRpc deviceRpc,
+            final NetconfSessionPreferences remoteSessionCapabilities,
+            final NetconfDeviceSchemasResolver stateSchemasResolver) {
+        this.id = requireNonNull(id);
+        this.baseSchema = requireNonNull(baseSchema);
+        this.deviceRpc = requireNonNull(deviceRpc);
+        this.remoteSessionCapabilities = requireNonNull(remoteSessionCapabilities);
+        this.stateSchemasResolver = requireNonNull(stateSchemasResolver);
+    }
+
+    @Override
+    public DeviceSources call() {
+        final NetconfDeviceSchemas availableSchemas = stateSchemasResolver.resolve(deviceRpc, remoteSessionCapabilities,
+            id, baseSchema.getSchemaContext());
+        LOG.debug("{}: Schemas exposed by ietf-netconf-monitoring: {}", id,
+            availableSchemas.getAvailableYangSchemasQNames());
+
+        final Set<QName> requiredSources = Sets.newHashSet(remoteSessionCapabilities.getModuleBasedCaps());
+        final Set<QName> providedSources = availableSchemas.getAvailableYangSchemasQNames();
+
+        final Set<QName> requiredSourcesNotProvided = Sets.difference(requiredSources, providedSources);
+        if (!requiredSourcesNotProvided.isEmpty()) {
+            LOG.warn("{}: Netconf device does not provide all yang models reported in hello message capabilities,"
+                    + " required but not provided: {}", id, requiredSourcesNotProvided);
+            LOG.warn("{}: Attempting to build schema context from required sources", id);
+        }
+
+        // Here all the sources reported in netconf monitoring are merged with those reported in hello.
+        // It is necessary to perform this since submodules are not mentioned in hello but still required.
+        // This clashes with the option of a user to specify supported yang models manually in configuration
+        // for netconf-connector and as a result one is not able to fully override yang models of a device.
+        // It is only possible to add additional models.
+        final Set<QName> providedSourcesNotRequired = Sets.difference(providedSources, requiredSources);
+        if (!providedSourcesNotRequired.isEmpty()) {
+            LOG.warn("{}: Netconf device provides additional yang models not reported in "
+                    + "hello message capabilities: {}", id, providedSourcesNotRequired);
+            LOG.warn("{}: Adding provided but not required sources as required to prevent failures", id);
+            LOG.debug("{}: Netconf device reported in hello: {}", id, requiredSources);
+            requiredSources.addAll(providedSourcesNotRequired);
+        }
+
+        final SchemaSourceProvider<YangTextSchemaSource> sourceProvider;
+        if (availableSchemas instanceof LibraryModulesSchemas) {
+            sourceProvider = new YangLibrarySchemaYangSourceProvider(id,
+                    ((LibraryModulesSchemas) availableSchemas).getAvailableModels());
+        } else {
+            sourceProvider = new NetconfRemoteSchemaYangSourceProvider(id, deviceRpc);
+        }
+
+        return new DeviceSources(requiredSources, providedSources, sourceProvider);
+    }
+}
\ No newline at end of file
index a56cd8c057c671728d1c35b81ccc18e65cb09586..88e5af62b14395d9bdda6146d880f640029f3ec4 100644 (file)
@@ -19,6 +19,7 @@ import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.ListeningExecutorService;
 import com.google.common.util.concurrent.MoreExecutors;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import io.netty.util.concurrent.EventExecutor;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -27,7 +28,6 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.Optional;
 import java.util.Set;
-import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
@@ -37,7 +37,6 @@ import org.opendaylight.mdsal.dom.api.DOMRpcService;
 import org.opendaylight.netconf.api.NetconfMessage;
 import org.opendaylight.netconf.sal.connect.api.DeviceActionFactory;
 import org.opendaylight.netconf.sal.connect.api.MessageTransformer;
-import org.opendaylight.netconf.sal.connect.api.NetconfDeviceSchemas;
 import org.opendaylight.netconf.sal.connect.api.NetconfDeviceSchemasResolver;
 import org.opendaylight.netconf.sal.connect.api.RemoteDevice;
 import org.opendaylight.netconf.sal.connect.api.RemoteDeviceCommunicator;
@@ -46,8 +45,6 @@ import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCapabi
 import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCommunicator;
 import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
 import org.opendaylight.netconf.sal.connect.netconf.sal.NetconfDeviceRpc;
-import org.opendaylight.netconf.sal.connect.netconf.schema.NetconfRemoteSchemaYangSourceProvider;
-import org.opendaylight.netconf.sal.connect.netconf.schema.YangLibrarySchemaYangSourceProvider;
 import org.opendaylight.netconf.sal.connect.netconf.schema.mapping.BaseSchema;
 import org.opendaylight.netconf.sal.connect.netconf.schema.mapping.NetconfMessageTransformer;
 import org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil;
@@ -62,7 +59,6 @@ import org.opendaylight.yangtools.rfc8528.data.api.MountPointContext;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.repo.api.MissingSchemaSourceException;
-import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier;
 import org.opendaylight.yangtools.yang.model.repo.api.SchemaContextFactory;
 import org.opendaylight.yangtools.yang.model.repo.api.SchemaRepository;
 import org.opendaylight.yangtools.yang.model.repo.api.SchemaResolutionException;
@@ -81,7 +77,9 @@ import org.slf4j.LoggerFactory;
 public class NetconfDevice
         implements RemoteDevice<NetconfSessionPreferences, NetconfMessage, NetconfDeviceCommunicator> {
 
-    private static final Logger LOG = LoggerFactory.getLogger(NetconfDevice.class);
+    @SuppressFBWarnings(value = "SLF4J_LOGGER_SHOULD_BE_PRIVATE",
+            justification = "Needed for common logging of related classes")
+    static final Logger LOG = LoggerFactory.getLogger(NetconfDevice.class);
 
     protected final RemoteDeviceId id;
     protected final SchemaContextFactory schemaContextFactory;
@@ -148,9 +146,8 @@ public class NetconfDevice
         final BaseSchema baseSchema = resolveBaseSchema(remoteSessionCapabilities.isNotificationsSupported());
         final NetconfDeviceRpc initRpc = new NetconfDeviceRpc(baseSchema.getSchemaContext(), listener,
             new NetconfMessageTransformer(baseSchema.getMountPointContext(), false, baseSchema));
-        final DeviceSourcesResolver task = new DeviceSourcesResolver(remoteSessionCapabilities, id,
-            stateSchemasResolver, initRpc, baseSchema.getSchemaContext());
-        final ListenableFuture<DeviceSources> sourceResolverFuture = processingExecutor.submit(task);
+        final ListenableFuture<DeviceSources> sourceResolverFuture = processingExecutor.submit(
+            new DeviceSourcesResolver(id, baseSchema, initRpc, remoteSessionCapabilities, stateSchemasResolver));
 
         if (shouldListenOnSchemaChange(remoteSessionCapabilities)) {
             registerToBaseNetconfStream(initRpc, listener);
@@ -331,117 +328,6 @@ public class NetconfDevice
         }
     }
 
-    /**
-     * Schema building callable.
-     */
-    private static class DeviceSourcesResolver implements Callable<DeviceSources> {
-
-        private final NetconfDeviceRpc deviceRpc;
-        private final NetconfSessionPreferences remoteSessionCapabilities;
-        private final RemoteDeviceId id;
-        private final NetconfDeviceSchemasResolver stateSchemasResolver;
-        private final SchemaContext schemaContext;
-
-        DeviceSourcesResolver(final NetconfDeviceRpc deviceRpc,
-                              final NetconfSessionPreferences remoteSessionCapabilities,
-                              final RemoteDeviceId id, final NetconfDeviceSchemasResolver stateSchemasResolver,
-                              final SchemaContext schemaContext) {
-            this.deviceRpc = deviceRpc;
-            this.remoteSessionCapabilities = remoteSessionCapabilities;
-            this.id = id;
-            this.stateSchemasResolver = stateSchemasResolver;
-            this.schemaContext = schemaContext;
-        }
-
-        DeviceSourcesResolver(final NetconfSessionPreferences remoteSessionCapabilities, final RemoteDeviceId id,
-                                     final NetconfDeviceSchemasResolver stateSchemasResolver,
-                                     final NetconfDeviceRpc rpcForMonitoring, final SchemaContext schemaCtx) {
-            this(rpcForMonitoring, remoteSessionCapabilities, id, stateSchemasResolver, schemaCtx);
-        }
-
-        @Override
-        public DeviceSources call() {
-            final NetconfDeviceSchemas availableSchemas =
-                    stateSchemasResolver.resolve(deviceRpc, remoteSessionCapabilities, id, schemaContext);
-            LOG.debug("{}: Schemas exposed by ietf-netconf-monitoring: {}", id,
-                    availableSchemas.getAvailableYangSchemasQNames());
-
-            final Set<QName> requiredSources = Sets.newHashSet(remoteSessionCapabilities.getModuleBasedCaps());
-            final Set<QName> providedSources = availableSchemas.getAvailableYangSchemasQNames();
-
-            final Set<QName> requiredSourcesNotProvided = Sets.difference(requiredSources, providedSources);
-            if (!requiredSourcesNotProvided.isEmpty()) {
-                LOG.warn("{}: Netconf device does not provide all yang models reported in hello message capabilities,"
-                        + " required but not provided: {}", id, requiredSourcesNotProvided);
-                LOG.warn("{}: Attempting to build schema context from required sources", id);
-            }
-
-            // Here all the sources reported in netconf monitoring are merged with those reported in hello.
-            // It is necessary to perform this since submodules are not mentioned in hello but still required.
-            // This clashes with the option of a user to specify supported yang models manually in configuration
-            // for netconf-connector and as a result one is not able to fully override yang models of a device.
-            // It is only possible to add additional models.
-            final Set<QName> providedSourcesNotRequired = Sets.difference(providedSources, requiredSources);
-            if (!providedSourcesNotRequired.isEmpty()) {
-                LOG.warn("{}: Netconf device provides additional yang models not reported in "
-                        + "hello message capabilities: {}", id, providedSourcesNotRequired);
-                LOG.warn("{}: Adding provided but not required sources as required to prevent failures", id);
-                LOG.debug("{}: Netconf device reported in hello: {}", id, requiredSources);
-                requiredSources.addAll(providedSourcesNotRequired);
-            }
-
-            final SchemaSourceProvider<YangTextSchemaSource> sourceProvider;
-            if (availableSchemas instanceof LibraryModulesSchemas) {
-                sourceProvider = new YangLibrarySchemaYangSourceProvider(id,
-                        ((LibraryModulesSchemas) availableSchemas).getAvailableModels());
-            } else {
-                sourceProvider = new NetconfRemoteSchemaYangSourceProvider(id, deviceRpc);
-            }
-
-            return new DeviceSources(requiredSources, providedSources, sourceProvider);
-        }
-    }
-
-    /**
-     * Contains RequiredSources - sources from capabilities.
-     */
-    private static final class DeviceSources {
-        private final Set<QName> requiredSources;
-        private final Set<QName> providedSources;
-        private final SchemaSourceProvider<YangTextSchemaSource> sourceProvider;
-
-        DeviceSources(final Set<QName> requiredSources, final Set<QName> providedSources,
-                             final SchemaSourceProvider<YangTextSchemaSource> sourceProvider) {
-            this.requiredSources = requiredSources;
-            this.providedSources = providedSources;
-            this.sourceProvider = sourceProvider;
-        }
-
-        public Set<QName> getRequiredSourcesQName() {
-            return requiredSources;
-        }
-
-        public Set<QName> getProvidedSourcesQName() {
-            return providedSources;
-        }
-
-        public Collection<SourceIdentifier> getRequiredSources() {
-            return Collections2.transform(requiredSources, DeviceSources::toSourceId);
-        }
-
-        public Collection<SourceIdentifier> getProvidedSources() {
-            return Collections2.transform(providedSources, DeviceSources::toSourceId);
-        }
-
-        public SchemaSourceProvider<YangTextSchemaSource> getSourceProvider() {
-            return sourceProvider;
-        }
-
-        private static SourceIdentifier toSourceId(final QName input) {
-            return RevisionSourceIdentifier.create(input.getLocalName(), input.getRevision());
-        }
-    }
-
     /**
      * Schema builder that tries to build schema context from provided sources or biggest subset of it.
      */