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 com.google.common.base.Preconditions.checkArgument;
11 import static java.util.Objects.requireNonNull;
13 import com.google.common.collect.ImmutableMap;
14 import java.util.HashMap;
15 import java.util.Iterator;
17 import java.util.Optional;
18 import org.eclipse.jdt.annotation.NonNull;
19 import org.opendaylight.yangtools.concepts.Immutable;
20 import org.opendaylight.yangtools.rfc8528.data.api.MountPointContext;
21 import org.opendaylight.yangtools.rfc8528.data.api.MountPointContextFactory;
22 import org.opendaylight.yangtools.rfc8528.data.api.MountPointIdentifier;
23 import org.opendaylight.yangtools.rfc8528.model.api.SchemaMountConstants;
24 import org.opendaylight.yangtools.yang.common.QName;
25 import org.opendaylight.yangtools.yang.common.QNameModule;
26 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
27 import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
28 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
29 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
30 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
31 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
32 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
33 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
34 import org.opendaylight.yangtools.yang.model.api.Module;
35 import org.opendaylight.yangtools.yang.model.util.AbstractEffectiveModelContextProvider;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
39 // TODO: this should really come from rfc8528-data-util
40 final class DeviceMountPointContext extends AbstractEffectiveModelContextProvider implements Immutable,
42 private static final Logger LOG = LoggerFactory.getLogger(DeviceMountPointContext.class);
43 private static final NodeIdentifier MOUNT_POINT = NodeIdentifier.create(
44 QName.create(SchemaMountConstants.RFC8528_MODULE, "mount-point").intern());
45 private static final NodeIdentifier CONFIG = NodeIdentifier.create(
46 QName.create(SchemaMountConstants.RFC8528_MODULE, "config").intern());
47 private static final NodeIdentifier MODULE = NodeIdentifier.create(
48 QName.create(SchemaMountConstants.RFC8528_MODULE, "module").intern());
49 private static final NodeIdentifier LABEL = NodeIdentifier.create(
50 QName.create(SchemaMountConstants.RFC8528_MODULE, "label").intern());
51 private static final NodeIdentifier SCHEMA_REF = NodeIdentifier.create(
52 QName.create(SchemaMountConstants.RFC8528_MODULE, "schema-ref").intern());
53 private static final NodeIdentifier INLINE = NodeIdentifier.create(
54 QName.create(SchemaMountConstants.RFC8528_MODULE, "inline").intern());
55 private static final NodeIdentifier SHARED_SCHEMA = NodeIdentifier.create(
56 QName.create(SchemaMountConstants.RFC8528_MODULE, "shared-schema").intern());
57 private static final NodeIdentifier PARENT_REFERENCE = NodeIdentifier.create(
58 QName.create(SchemaMountConstants.RFC8528_MODULE, "parent-reference").intern());
60 private final ImmutableMap<MountPointIdentifier, NetconfMountPointContextFactory> mountPoints;
62 private DeviceMountPointContext(final EffectiveModelContext schemaContext,
63 final Map<MountPointIdentifier, NetconfMountPointContextFactory> mountPoints) {
65 this.mountPoints = ImmutableMap.copyOf(mountPoints);
68 static MountPointContext create(final MountPointContext emptyContext, final ContainerNode mountData) {
69 final Optional<DataContainerChild<?, ?>> optMountPoint = mountData.getChild(MOUNT_POINT);
70 if (optMountPoint.isEmpty()) {
71 LOG.debug("mount-point list not present in {}", mountData);
75 final EffectiveModelContext schemaContext = emptyContext.getEffectiveModelContext();
76 final DataContainerChild<?, ?> mountPoint = optMountPoint.get();
77 checkArgument(mountPoint instanceof MapNode, "mount-point list %s is not a MapNode", mountPoint);
79 final Map<MountPointIdentifier, NetconfMountPointContextFactory> mountPoints = new HashMap<>();
80 for (MapEntryNode entry : ((MapNode) mountPoint).getValue()) {
81 final String moduleName = entry.getChild(MODULE).map(mod -> {
82 checkArgument(mod instanceof LeafNode, "Unexpected module leaf %s", mod);
83 final Object value = mod.getValue();
84 checkArgument(value instanceof String, "Unexpected module leaf value %s", value);
85 return (String) value;
86 }).orElseThrow(() -> new IllegalArgumentException("Mount module missing in " + entry));
87 final Iterator<? extends Module> it = schemaContext.findModules(moduleName).iterator();
88 checkArgument(it.hasNext(), "Failed to find a module named %s", moduleName);
89 final QNameModule module = it.next().getQNameModule();
91 final MountPointIdentifier mountId = MountPointIdentifier.of(QName.create(module,
92 entry.getChild(LABEL).map(lbl -> {
93 checkArgument(lbl instanceof LeafNode, "Unexpected label leaf %s", lbl);
94 final Object value = lbl.getValue();
95 checkArgument(value instanceof String, "Unexpected label leaf value %s", value);
96 return (String) value;
97 }).orElseThrow(() -> new IllegalArgumentException("Mount module missing in " + entry))));
99 final DataContainerChild<?, ?> child = entry.getChild(SCHEMA_REF).orElseThrow(
100 () -> new IllegalArgumentException("Missing schema-ref choice in " + entry));
101 checkArgument(child instanceof ChoiceNode, "Unexpected schema-ref choice %s", child);
102 final ChoiceNode schemaRef = (ChoiceNode) child;
104 final Optional<DataContainerChild<?, ?>> maybeShared = schemaRef.getChild(SHARED_SCHEMA);
105 if (maybeShared.isEmpty()) {
106 LOG.debug("Ignoring non-shared mountpoint entry {}", entry);
110 mountPoints.put(mountId, new NetconfMountPointContextFactory(schemaContext));
113 return new DeviceMountPointContext(schemaContext, mountPoints);
117 public Optional<MountPointContextFactory> findMountPoint(@NonNull final MountPointIdentifier label) {
118 return Optional.ofNullable(mountPoints.get(requireNonNull(label)));