Bug 5528 - Preparing enviroment for impl of restful services
[netconf.git] / restconf / sal-rest-connector / src / main / java / org / opendaylight / restconf / rest / services / impl / RestconfModulesServiceImpl.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. 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.restconf.rest.services.impl;
9
10 import com.google.common.base.Preconditions;
11 import java.util.Collections;
12 import java.util.Set;
13 import javax.ws.rs.core.UriInfo;
14 import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
15 import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
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.Draft11;
22 import org.opendaylight.restconf.common.handlers.api.SchemaContextHandler;
23 import org.opendaylight.restconf.common.references.SchemaContextRef;
24 import org.opendaylight.restconf.rest.handlers.api.DOMMountPointServiceHandler;
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;
43
44 /**
45  * Implementation of {@link RestconfModulesService}
46  */
47 public class RestconfModulesServiceImpl implements RestconfModulesService {
48
49     private static final Logger LOG = LoggerFactory.getLogger(RestconfModulesServiceImpl.class);
50     private final SchemaContextHandler schemaContextHandler;
51     private final DOMMountPointServiceHandler domMountPointServiceHandler;
52
53     /**
54      * Set {@link SchemaContextHandler} for getting actual {@link SchemaContext}
55      *
56      * @param schemaContextHandler
57      *            - handling schema context
58      * @param domMountPointServiceHandler
59      *            - handling dom mount point service
60      */
61     public RestconfModulesServiceImpl(final SchemaContextHandler schemaContextHandler,
62             final DOMMountPointServiceHandler domMountPointServiceHandler) {
63         this.schemaContextHandler = schemaContextHandler;
64         this.domMountPointServiceHandler = domMountPointServiceHandler;
65     }
66
67     @Override
68     public NormalizedNodeContext getModules(final UriInfo uriInfo) {
69         final SchemaContextRef schemaContextRef = new SchemaContextRef(this.schemaContextHandler.getSchemaContext());
70         return getModules(schemaContextRef.getModules(), schemaContextRef, null);
71     }
72
73     @Override
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);
81         }
82         final SchemaContextRef schemaContextRef = new SchemaContextRef(this.schemaContextHandler.getSchemaContext());
83         final InstanceIdentifierContext<?> mountPointIdentifier = ParserIdentifier.toInstanceIdentifier(identifier,
84                 schemaContextRef.get());
85         final DOMMountPointService domMointPointService = this.domMountPointServiceHandler.getDOMMountPointService();
86         final DOMMountPoint mountPoint = domMointPointService
87                 .getMountPoint(mountPointIdentifier.getInstanceIdentifier()).get();
88         return getModules(mountPoint.getSchemaContext().getModules(), schemaContextRef, mountPoint);
89     }
90
91
92     @Override
93     public NormalizedNodeContext getModule(final String identifier, final UriInfo uriInfo) {
94         Preconditions.checkNotNull(identifier);
95         final SchemaContextRef schemaContextRef = new SchemaContextRef(this.schemaContextHandler.getSchemaContext());
96         final QName moduleQname = ParserIdentifier.makeQNameFromIdentifier(identifier);
97         Module module = null;
98         DOMMountPoint mountPoint = null;
99         if (identifier.contains(RestconfConstants.MOUNT)) {
100             final InstanceIdentifierContext<?> point = ParserIdentifier.toInstanceIdentifier(identifier,
101                     schemaContextRef.get());
102             final DOMMountPointService domMointPointService = this.domMountPointServiceHandler
103                     .getDOMMountPointService();
104             mountPoint = domMointPointService.getMountPoint(point.getInstanceIdentifier()).get();
105             module = schemaContextRef.findModuleInMountPointByQName(mountPoint, moduleQname);
106         } else {
107             module = schemaContextRef.findModuleByQName(moduleQname);
108         }
109
110         if (module == null) {
111             final String errMsg = "Module with name '" + moduleQname.getLocalName() + "' and revision '"
112                     + moduleQname.getRevision() + "' was not found.";
113             LOG.debug(errMsg);
114             throw new RestconfDocumentedException(errMsg, ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT);
115         }
116
117         final Set<Module> modules = Collections.singleton(module);
118         final MapNode moduleMap = RestconfMappingNodeUtil
119                 .restconfMappingNode(schemaContextRef.getRestconfModule(), modules);
120         final DataSchemaNode moduleSchemaNode = RestconfSchemaUtil.getRestconfSchemaNode(
121                 schemaContextRef.getRestconfModule(), Draft11.RestconfModule.MODULE_LIST_SCHEMA_NODE);
122         Preconditions.checkState(moduleSchemaNode instanceof ListSchemaNode);
123         if (mountPoint == null) {
124             return new NormalizedNodeContext(
125                 new InstanceIdentifierContext<>(null, moduleSchemaNode, mountPoint, schemaContextRef.get()), moduleMap);
126         } else {
127             return new NormalizedNodeContext(
128                     new InstanceIdentifierContext<>(null, moduleSchemaNode, mountPoint, mountPoint.getSchemaContext()),
129                     moduleMap);
130         }
131     }
132
133     /**
134      * Get {@link NormalizedNodeContext} from set of modules. Used by
135      * {@link #getModules(UriInfo)} and {@link #getModules(String, UriInfo)}
136      *
137      * @param modules
138      *            - all modules
139      * @param schemaContextRef
140      *            - schema context reference
141      * @param mountPoint
142      *            - mount point
143      * @return {@link NormalizedNodeContext}
144      */
145     private NormalizedNodeContext getModules(final Set<Module> modules, final SchemaContextRef schemaContextRef,
146             final DOMMountPoint mountPoint) {
147         final Module restconfModule = schemaContextRef.getRestconfModule();
148         Preconditions.checkNotNull(restconfModule);
149
150         final MapNode mapNodes = RestconfMappingNodeUtil.restconfMappingNode(restconfModule, modules);
151         final DataSchemaNode schemaNode = RestconfSchemaUtil.getRestconfSchemaNode(restconfModule,
152                 Draft11.RestconfModule.MODULES_CONTAINER_SCHEMA_NODE);
153         Preconditions.checkState(schemaNode instanceof ContainerSchemaNode);
154         final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> modulContainerSchemaNodeBuilder = Builders
155                 .containerBuilder((ContainerSchemaNode) schemaNode);
156         modulContainerSchemaNodeBuilder.withChild(mapNodes);
157         if (mountPoint == null) {
158             return new NormalizedNodeContext(
159                     new InstanceIdentifierContext<>(null, schemaNode, mountPoint, schemaContextRef.get()),
160                     modulContainerSchemaNodeBuilder.build());
161         } else {
162             return new NormalizedNodeContext(
163                     new InstanceIdentifierContext<>(null, schemaNode, mountPoint, mountPoint.getSchemaContext()),
164                     modulContainerSchemaNodeBuilder.build());
165         }
166     }
167 }