2 * Copyright (c) 2019 PANTHEON.tech, s.r.o. and others. All rights reserved.
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
8 package org.opendaylight.netconf.sal.connect.netconf;
10 import static java.util.Objects.requireNonNull;
11 import static org.opendaylight.netconf.sal.connect.netconf.NetconfDevice.LOG;
13 import com.google.common.collect.Sets;
15 import java.util.concurrent.Callable;
16 import org.opendaylight.netconf.sal.connect.api.NetconfDeviceSchemas;
17 import org.opendaylight.netconf.sal.connect.api.NetconfDeviceSchemasResolver;
18 import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
19 import org.opendaylight.netconf.sal.connect.netconf.sal.NetconfDeviceRpc;
20 import org.opendaylight.netconf.sal.connect.netconf.schema.NetconfRemoteSchemaYangSourceProvider;
21 import org.opendaylight.netconf.sal.connect.netconf.schema.YangLibrarySchemaYangSourceProvider;
22 import org.opendaylight.netconf.sal.connect.netconf.schema.mapping.BaseSchema;
23 import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
24 import org.opendaylight.yangtools.yang.common.QName;
25 import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
26 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceProvider;
29 * Schema building callable.
31 final class DeviceSourcesResolver implements Callable<DeviceSources> {
32 private final NetconfSessionPreferences remoteSessionCapabilities;
33 private final NetconfDeviceSchemasResolver stateSchemasResolver;
34 private final NetconfDeviceRpc deviceRpc;
35 private final BaseSchema baseSchema;
36 private final RemoteDeviceId id;
38 DeviceSourcesResolver(final RemoteDeviceId id, final BaseSchema baseSchema, final NetconfDeviceRpc deviceRpc,
39 final NetconfSessionPreferences remoteSessionCapabilities,
40 final NetconfDeviceSchemasResolver stateSchemasResolver) {
41 this.id = requireNonNull(id);
42 this.baseSchema = requireNonNull(baseSchema);
43 this.deviceRpc = requireNonNull(deviceRpc);
44 this.remoteSessionCapabilities = requireNonNull(remoteSessionCapabilities);
45 this.stateSchemasResolver = requireNonNull(stateSchemasResolver);
49 public DeviceSources call() {
50 final NetconfDeviceSchemas availableSchemas = stateSchemasResolver.resolve(deviceRpc, remoteSessionCapabilities,
51 id, baseSchema.getSchemaContext());
52 LOG.debug("{}: Schemas exposed by ietf-netconf-monitoring: {}", id,
53 availableSchemas.getAvailableYangSchemasQNames());
55 final Set<QName> requiredSources = Sets.newHashSet(remoteSessionCapabilities.getModuleBasedCaps());
56 final Set<QName> providedSources = availableSchemas.getAvailableYangSchemasQNames();
58 final Set<QName> requiredSourcesNotProvided = Sets.difference(requiredSources, providedSources);
59 if (!requiredSourcesNotProvided.isEmpty()) {
60 LOG.warn("{}: Netconf device does not provide all yang models reported in hello message capabilities,"
61 + " required but not provided: {}", id, requiredSourcesNotProvided);
62 LOG.warn("{}: Attempting to build schema context from required sources", id);
65 // Here all the sources reported in netconf monitoring are merged with those reported in hello.
66 // It is necessary to perform this since submodules are not mentioned in hello but still required.
67 // This clashes with the option of a user to specify supported yang models manually in configuration
68 // for netconf-connector and as a result one is not able to fully override yang models of a device.
69 // It is only possible to add additional models.
70 final Set<QName> providedSourcesNotRequired = Sets.difference(providedSources, requiredSources);
71 if (!providedSourcesNotRequired.isEmpty()) {
72 LOG.warn("{}: Netconf device provides additional yang models not reported in "
73 + "hello message capabilities: {}", id, providedSourcesNotRequired);
74 LOG.warn("{}: Adding provided but not required sources as required to prevent failures", id);
75 LOG.debug("{}: Netconf device reported in hello: {}", id, requiredSources);
76 requiredSources.addAll(providedSourcesNotRequired);
79 final SchemaSourceProvider<YangTextSchemaSource> sourceProvider;
80 if (availableSchemas instanceof LibraryModulesSchemas) {
81 sourceProvider = new YangLibrarySchemaYangSourceProvider(id,
82 ((LibraryModulesSchemas) availableSchemas).getAvailableModels());
84 sourceProvider = new NetconfRemoteSchemaYangSourceProvider(id, deviceRpc);
87 return new DeviceSources(requiredSources, providedSources, sourceProvider);