Hide NetconfDevice.LOG
[netconf.git] / netconf / sal-netconf-connector / src / main / java / org / opendaylight / netconf / sal / connect / netconf / DeviceSourcesResolver.java
1 /*
2  * Copyright (c) 2019 PANTHEON.tech, s.r.o. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.netconf.sal.connect.netconf;
9
10 import static java.util.Objects.requireNonNull;
11
12 import com.google.common.collect.Sets;
13 import java.util.Set;
14 import java.util.concurrent.Callable;
15 import org.opendaylight.netconf.sal.connect.api.NetconfDeviceSchemas;
16 import org.opendaylight.netconf.sal.connect.api.NetconfDeviceSchemasResolver;
17 import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
18 import org.opendaylight.netconf.sal.connect.netconf.sal.NetconfDeviceRpc;
19 import org.opendaylight.netconf.sal.connect.netconf.schema.NetconfRemoteSchemaYangSourceProvider;
20 import org.opendaylight.netconf.sal.connect.netconf.schema.YangLibrarySchemaYangSourceProvider;
21 import org.opendaylight.netconf.sal.connect.netconf.schema.mapping.BaseSchema;
22 import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
23 import org.opendaylight.yangtools.yang.common.QName;
24 import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
25 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceProvider;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28
29 /**
30  * Schema building callable.
31  */
32 final class DeviceSourcesResolver implements Callable<DeviceSources> {
33     private static final Logger LOG = LoggerFactory.getLogger(DeviceSourcesResolver.class);
34
35     private final NetconfSessionPreferences remoteSessionCapabilities;
36     private final NetconfDeviceSchemasResolver stateSchemasResolver;
37     private final NetconfDeviceRpc deviceRpc;
38     private final BaseSchema baseSchema;
39     private final RemoteDeviceId id;
40
41     DeviceSourcesResolver(final RemoteDeviceId id, final BaseSchema baseSchema, final NetconfDeviceRpc deviceRpc,
42             final NetconfSessionPreferences remoteSessionCapabilities,
43             final NetconfDeviceSchemasResolver stateSchemasResolver) {
44         this.id = requireNonNull(id);
45         this.baseSchema = requireNonNull(baseSchema);
46         this.deviceRpc = requireNonNull(deviceRpc);
47         this.remoteSessionCapabilities = requireNonNull(remoteSessionCapabilities);
48         this.stateSchemasResolver = requireNonNull(stateSchemasResolver);
49     }
50
51     @Override
52     public DeviceSources call() {
53         final NetconfDeviceSchemas availableSchemas = stateSchemasResolver.resolve(deviceRpc, remoteSessionCapabilities,
54             id, baseSchema.getEffectiveModelContext());
55         LOG.debug("{}: Schemas exposed by ietf-netconf-monitoring: {}", id,
56             availableSchemas.getAvailableYangSchemasQNames());
57
58         final Set<QName> requiredSources = Sets.newHashSet(remoteSessionCapabilities.getModuleBasedCaps());
59         final Set<QName> providedSources = availableSchemas.getAvailableYangSchemasQNames();
60
61         final Set<QName> requiredSourcesNotProvided = Sets.difference(requiredSources, providedSources);
62         if (!requiredSourcesNotProvided.isEmpty()) {
63             LOG.warn("{}: Netconf device does not provide all yang models reported in hello message capabilities,"
64                     + " required but not provided: {}", id, requiredSourcesNotProvided);
65             LOG.warn("{}: Attempting to build schema context from required sources", id);
66         }
67
68         // Here all the sources reported in netconf monitoring are merged with those reported in hello.
69         // It is necessary to perform this since submodules are not mentioned in hello but still required.
70         // This clashes with the option of a user to specify supported yang models manually in configuration
71         // for netconf-connector and as a result one is not able to fully override yang models of a device.
72         // It is only possible to add additional models.
73         final Set<QName> providedSourcesNotRequired = Sets.difference(providedSources, requiredSources);
74         if (!providedSourcesNotRequired.isEmpty()) {
75             LOG.warn("{}: Netconf device provides additional yang models not reported in "
76                     + "hello message capabilities: {}", id, providedSourcesNotRequired);
77             LOG.warn("{}: Adding provided but not required sources as required to prevent failures", id);
78             LOG.debug("{}: Netconf device reported in hello: {}", id, requiredSources);
79             requiredSources.addAll(providedSourcesNotRequired);
80         }
81
82         final SchemaSourceProvider<YangTextSchemaSource> sourceProvider;
83         if (availableSchemas instanceof LibraryModulesSchemas) {
84             sourceProvider = new YangLibrarySchemaYangSourceProvider(id,
85                     ((LibraryModulesSchemas) availableSchemas).getAvailableModels());
86         } else {
87             sourceProvider = new NetconfRemoteSchemaYangSourceProvider(id, deviceRpc);
88         }
89
90         return new DeviceSources(requiredSources, providedSources, sourceProvider);
91     }
92 }