2 * Copyright (c) 2016 Cisco Systems, Inc. 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.restconf.rest.services.impl;
10 import com.google.common.base.Optional;
11 import com.google.common.base.Preconditions;
12 import java.util.Collections;
14 import javax.ws.rs.core.UriInfo;
15 import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
16 import org.opendaylight.netconf.sal.restconf.impl.InstanceIdentifierContext;
17 import org.opendaylight.netconf.sal.restconf.impl.NormalizedNodeContext;
18 import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException;
19 import org.opendaylight.netconf.sal.restconf.impl.RestconfError.ErrorTag;
20 import org.opendaylight.netconf.sal.restconf.impl.RestconfError.ErrorType;
21 import org.opendaylight.restconf.Draft17;
22 import org.opendaylight.restconf.common.references.SchemaContextRef;
23 import org.opendaylight.restconf.handlers.DOMMountPointServiceHandler;
24 import org.opendaylight.restconf.handlers.SchemaContextHandler;
25 import org.opendaylight.restconf.rest.services.api.RestconfModulesService;
26 import org.opendaylight.restconf.utils.RestconfConstants;
27 import org.opendaylight.restconf.utils.mapping.RestconfMappingNodeUtil;
28 import org.opendaylight.restconf.utils.parser.ParserIdentifier;
29 import org.opendaylight.restconf.utils.schema.context.RestconfSchemaUtil;
30 import org.opendaylight.yangtools.yang.common.QName;
31 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
32 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
33 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
34 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
35 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
36 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
37 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
38 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
39 import org.opendaylight.yangtools.yang.model.api.Module;
40 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
45 * Implementation of {@link RestconfModulesService}
47 public class RestconfModulesServiceImpl implements RestconfModulesService {
49 private static final Logger LOG = LoggerFactory.getLogger(RestconfModulesServiceImpl.class);
50 private final SchemaContextHandler schemaContextHandler;
51 private final DOMMountPointServiceHandler domMountPointServiceHandler;
54 * Set {@link SchemaContextHandler} for getting actual {@link SchemaContext}
56 * @param schemaContextHandler
57 * - handling schema context
58 * @param domMountPointServiceHandler
59 * - handling dom mount point service
61 public RestconfModulesServiceImpl(final SchemaContextHandler schemaContextHandler,
62 final DOMMountPointServiceHandler domMountPointServiceHandler) {
63 this.schemaContextHandler = schemaContextHandler;
64 this.domMountPointServiceHandler = domMountPointServiceHandler;
68 public NormalizedNodeContext getModules(final UriInfo uriInfo) {
69 final SchemaContextRef schemaContextRef = new SchemaContextRef(this.schemaContextHandler.get());
70 return getModules(schemaContextRef.getModules(), schemaContextRef, null);
74 public NormalizedNodeContext getModules(final String identifier, final UriInfo uriInfo) {
75 Preconditions.checkNotNull(identifier);
76 if (!identifier.contains(RestconfConstants.MOUNT)) {
77 final String errMsg = "URI has bad format. If modules behind mount point should be showed,"
78 + " URI has to end with " + RestconfConstants.MOUNT;
79 LOG.debug(errMsg + " for " + identifier);
80 throw new RestconfDocumentedException(errMsg, ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
82 final SchemaContextRef schemaContextRef = new SchemaContextRef(this.schemaContextHandler.get());
83 final InstanceIdentifierContext<?> mountPointIdentifier = ParserIdentifier.toInstanceIdentifier(
84 identifier, schemaContextRef.get(), Optional.of(this.domMountPointServiceHandler.get()));
85 final DOMMountPoint mountPoint = mountPointIdentifier.getMountPoint();
86 return getModules(mountPoint.getSchemaContext().getModules(), schemaContextRef, mountPoint);
91 public NormalizedNodeContext getModule(final String identifier, final UriInfo uriInfo) {
92 Preconditions.checkNotNull(identifier);
93 final SchemaContextRef schemaContextRef = new SchemaContextRef(this.schemaContextHandler.get());
94 final QName moduleQname = ParserIdentifier.makeQNameFromIdentifier(identifier);
96 DOMMountPoint mountPoint = null;
97 if (identifier.contains(RestconfConstants.MOUNT)) {
98 // we only need to find mount point itself
99 final String mountPointPath = identifier.substring(
100 0, identifier.indexOf(RestconfConstants.MOUNT) + RestconfConstants.MOUNT.length());
101 final InstanceIdentifierContext<?> mountPointContext = ParserIdentifier.toInstanceIdentifier(
102 mountPointPath, schemaContextRef.get(), Optional.of(this.domMountPointServiceHandler.get()));
103 mountPoint = mountPointContext.getMountPoint();
104 module = schemaContextRef.findModuleInMountPointByQName(mountPoint, moduleQname);
106 module = schemaContextRef.findModuleByQName(moduleQname);
109 if (module == null) {
110 final String errMsg = "Module with name '" + moduleQname.getLocalName() + "' and revision '"
111 + moduleQname.getRevision() + "' was not found.";
113 throw new RestconfDocumentedException(errMsg, ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT);
116 final Set<Module> modules = Collections.singleton(module);
117 final MapNode moduleMap = RestconfMappingNodeUtil
118 .restconfMappingNode(schemaContextRef.getRestconfModule(), modules);
119 final DataSchemaNode moduleSchemaNode = RestconfSchemaUtil.getRestconfSchemaNode(
120 schemaContextRef.getRestconfModule(), Draft17.RestconfModule.MODULE_LIST_SCHEMA_NODE);
121 Preconditions.checkState(moduleSchemaNode instanceof ListSchemaNode);
122 if (mountPoint == null) {
123 return new NormalizedNodeContext(
124 new InstanceIdentifierContext<>(null, moduleSchemaNode, mountPoint, schemaContextRef.get()), moduleMap);
126 return new NormalizedNodeContext(
127 new InstanceIdentifierContext<>(null, moduleSchemaNode, mountPoint, mountPoint.getSchemaContext()),
133 * Get {@link NormalizedNodeContext} from set of modules. Used by
134 * {@link #getModules(UriInfo)} and {@link #getModules(String, UriInfo)}
138 * @param schemaContextRef
139 * - schema context reference
142 * @return {@link NormalizedNodeContext}
144 private NormalizedNodeContext getModules(final Set<Module> modules, final SchemaContextRef schemaContextRef,
145 final DOMMountPoint mountPoint) {
146 final Module restconfModule = schemaContextRef.getRestconfModule();
147 Preconditions.checkNotNull(restconfModule);
149 final MapNode mapNodes = RestconfMappingNodeUtil.restconfMappingNode(restconfModule, modules);
150 final DataSchemaNode schemaNode = RestconfSchemaUtil.getRestconfSchemaNode(restconfModule,
151 Draft17.RestconfModule.MODULES_CONTAINER_SCHEMA_NODE);
152 Preconditions.checkState(schemaNode instanceof ContainerSchemaNode);
153 final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> modulContainerSchemaNodeBuilder = Builders
154 .containerBuilder((ContainerSchemaNode) schemaNode);
155 modulContainerSchemaNodeBuilder.withChild(mapNodes);
156 if (mountPoint == null) {
157 return new NormalizedNodeContext(
158 new InstanceIdentifierContext<>(null, schemaNode, mountPoint, schemaContextRef.get()),
159 modulContainerSchemaNodeBuilder.build());
161 return new NormalizedNodeContext(
162 new InstanceIdentifierContext<>(null, schemaNode, mountPoint, mountPoint.getSchemaContext()),
163 modulContainerSchemaNodeBuilder.build());