2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
3 * Copyright (c) 2014 Brocade Communication Systems, Inc.
5 * This program and the accompanying materials are made available under the
6 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
7 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.controller.sal.restconf.impl;
12 import java.text.ParseException;
13 import java.text.SimpleDateFormat;
14 import java.util.ArrayList;
15 import java.util.Arrays;
16 import java.util.Collection;
17 import java.util.Collections;
18 import java.util.Date;
19 import java.util.HashMap;
20 import java.util.List;
22 import java.util.concurrent.Future;
24 import javax.ws.rs.core.Response;
25 import javax.ws.rs.core.Response.Status;
26 import javax.ws.rs.core.UriBuilder;
27 import javax.ws.rs.core.UriInfo;
29 import org.apache.commons.lang3.StringUtils;
30 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
31 import org.opendaylight.controller.sal.core.api.mount.MountInstance;
32 import org.opendaylight.controller.sal.rest.api.Draft02;
33 import org.opendaylight.controller.sal.rest.api.RestconfService;
34 import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorTag;
35 import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorType;
36 import org.opendaylight.controller.sal.restconf.rpc.impl.BrokerRpcExecutor;
37 import org.opendaylight.controller.sal.restconf.rpc.impl.MountPointRpcExecutor;
38 import org.opendaylight.controller.sal.restconf.rpc.impl.RpcExecutor;
39 import org.opendaylight.controller.sal.streams.listeners.ListenerAdapter;
40 import org.opendaylight.controller.sal.streams.listeners.Notificator;
41 import org.opendaylight.controller.sal.streams.websockets.WebSocketServer;
42 import org.opendaylight.yangtools.concepts.Codec;
43 import org.opendaylight.yangtools.yang.common.QName;
44 import org.opendaylight.yangtools.yang.common.RpcError;
45 import org.opendaylight.yangtools.yang.common.RpcResult;
46 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
47 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
48 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.InstanceIdentifierBuilder;
49 import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode;
50 import org.opendaylight.yangtools.yang.data.api.Node;
51 import org.opendaylight.yangtools.yang.data.api.SimpleNode;
52 import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
53 import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
54 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
55 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
56 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
57 import org.opendaylight.yangtools.yang.model.api.FeatureDefinition;
58 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
59 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
60 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
61 import org.opendaylight.yangtools.yang.model.api.Module;
62 import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
63 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
64 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
65 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
66 import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
67 import org.opendaylight.yangtools.yang.model.util.EmptyType;
68 import org.opendaylight.yangtools.yang.parser.builder.impl.ContainerSchemaNodeBuilder;
69 import org.opendaylight.yangtools.yang.parser.builder.impl.LeafSchemaNodeBuilder;
71 import com.google.common.base.Objects;
72 import com.google.common.base.Preconditions;
73 import com.google.common.base.Splitter;
74 import com.google.common.base.Strings;
75 import com.google.common.collect.ImmutableList;
76 import com.google.common.collect.Iterables;
77 import com.google.common.collect.Lists;
79 public class RestconfImpl implements RestconfService {
80 private final static RestconfImpl INSTANCE = new RestconfImpl();
82 private static final int CHAR_NOT_FOUND = -1;
84 private final static String MOUNT_POINT_MODULE_NAME = "ietf-netconf";
86 private final static SimpleDateFormat REVISION_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
88 private final static String SAL_REMOTE_NAMESPACE = "urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote";
90 private final static String SAL_REMOTE_RPC_SUBSRCIBE = "create-data-change-event-subscription";
92 private BrokerFacade broker;
94 private ControllerContext controllerContext;
96 public void setBroker(final BrokerFacade broker) {
100 public void setControllerContext(final ControllerContext controllerContext) {
101 this.controllerContext = controllerContext;
104 private RestconfImpl() {
107 public static RestconfImpl getInstance() {
112 public StructuredData getModules() {
113 final Module restconfModule = this.getRestconfModule();
115 final List<Node<?>> modulesAsData = new ArrayList<Node<?>>();
116 final DataSchemaNode moduleSchemaNode = controllerContext.getRestconfModuleRestConfSchemaNode(
117 restconfModule, Draft02.RestConfModule.MODULE_LIST_SCHEMA_NODE);
119 Set<Module> allModules = this.controllerContext.getAllModules();
120 for (final Module module : allModules) {
121 CompositeNode moduleCompositeNode = this.toModuleCompositeNode(module, moduleSchemaNode);
122 modulesAsData.add(moduleCompositeNode);
125 final DataSchemaNode modulesSchemaNode = controllerContext.getRestconfModuleRestConfSchemaNode(
126 restconfModule, Draft02.RestConfModule.MODULES_CONTAINER_SCHEMA_NODE);
127 QName qName = modulesSchemaNode.getQName();
128 final CompositeNode modulesNode = NodeFactory.createImmutableCompositeNode(qName, null, modulesAsData);
129 return new StructuredData(modulesNode, modulesSchemaNode, null);
133 public StructuredData getAvailableStreams() {
134 Set<String> availableStreams = Notificator.getStreamNames();
136 final List<Node<?>> streamsAsData = new ArrayList<Node<?>>();
137 Module restconfModule = this.getRestconfModule();
138 final DataSchemaNode streamSchemaNode = controllerContext.getRestconfModuleRestConfSchemaNode(
139 restconfModule, Draft02.RestConfModule.STREAM_LIST_SCHEMA_NODE);
140 for (final String streamName : availableStreams) {
141 streamsAsData.add(this.toStreamCompositeNode(streamName, streamSchemaNode));
144 final DataSchemaNode streamsSchemaNode = controllerContext.getRestconfModuleRestConfSchemaNode(
145 restconfModule, Draft02.RestConfModule.STREAMS_CONTAINER_SCHEMA_NODE);
146 QName qName = streamsSchemaNode.getQName();
147 final CompositeNode streamsNode = NodeFactory.createImmutableCompositeNode(qName, null, streamsAsData);
148 return new StructuredData(streamsNode, streamsSchemaNode, null);
152 public StructuredData getModules(final String identifier) {
153 Set<Module> modules = null;
154 MountInstance mountPoint = null;
155 if (identifier.contains(ControllerContext.MOUNT)) {
156 InstanceIdWithSchemaNode mountPointIdentifier =
157 this.controllerContext.toMountPointIdentifier(identifier);
158 mountPoint = mountPointIdentifier.getMountPoint();
159 modules = this.controllerContext.getAllModules(mountPoint);
162 throw new RestconfDocumentedException(
163 "URI has bad format. If modules behind mount point should be showed, URI has to end with " +
164 ControllerContext.MOUNT, ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
167 final List<Node<?>> modulesAsData = new ArrayList<Node<?>>();
168 Module restconfModule = this.getRestconfModule();
169 final DataSchemaNode moduleSchemaNode = controllerContext.getRestconfModuleRestConfSchemaNode(
170 restconfModule, Draft02.RestConfModule.MODULE_LIST_SCHEMA_NODE);
172 for (final Module module : modules) {
173 modulesAsData.add(this.toModuleCompositeNode(module, moduleSchemaNode));
176 final DataSchemaNode modulesSchemaNode = controllerContext.getRestconfModuleRestConfSchemaNode(
177 restconfModule, Draft02.RestConfModule.MODULES_CONTAINER_SCHEMA_NODE);
178 QName qName = modulesSchemaNode.getQName();
179 final CompositeNode modulesNode = NodeFactory.createImmutableCompositeNode(qName, null, modulesAsData);
180 return new StructuredData(modulesNode, modulesSchemaNode, mountPoint);
184 public StructuredData getModule(final String identifier) {
185 final QName moduleNameAndRevision = this.getModuleNameAndRevision(identifier);
186 Module module = null;
187 MountInstance mountPoint = null;
188 if (identifier.contains(ControllerContext.MOUNT)) {
189 InstanceIdWithSchemaNode mountPointIdentifier =
190 this.controllerContext.toMountPointIdentifier(identifier);
191 mountPoint = mountPointIdentifier.getMountPoint();
192 module = this.controllerContext.findModuleByNameAndRevision(mountPoint, moduleNameAndRevision);
195 module = this.controllerContext.findModuleByNameAndRevision(moduleNameAndRevision);
198 if (module == null) {
199 throw new RestconfDocumentedException(
200 "Module with name '" + moduleNameAndRevision.getLocalName() + "' and revision '" +
201 moduleNameAndRevision.getRevision() + "' was not found.",
202 ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT );
205 Module restconfModule = this.getRestconfModule();
206 final DataSchemaNode moduleSchemaNode = controllerContext.getRestconfModuleRestConfSchemaNode(
207 restconfModule, Draft02.RestConfModule.MODULE_LIST_SCHEMA_NODE);
208 final CompositeNode moduleNode = this.toModuleCompositeNode(module, moduleSchemaNode);
209 return new StructuredData(moduleNode, moduleSchemaNode, mountPoint);
213 public StructuredData getOperations() {
214 Set<Module> allModules = this.controllerContext.getAllModules();
215 return this.operationsFromModulesToStructuredData(allModules, null);
219 public StructuredData getOperations(final String identifier) {
220 Set<Module> modules = null;
221 MountInstance mountPoint = null;
222 if (identifier.contains(ControllerContext.MOUNT)) {
223 InstanceIdWithSchemaNode mountPointIdentifier =
224 this.controllerContext.toMountPointIdentifier(identifier);
225 mountPoint = mountPointIdentifier.getMountPoint();
226 modules = this.controllerContext.getAllModules(mountPoint);
229 throw new RestconfDocumentedException(
230 "URI has bad format. If operations behind mount point should be showed, URI has to end with " +
231 ControllerContext.MOUNT, ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
234 return this.operationsFromModulesToStructuredData(modules, mountPoint);
237 private StructuredData operationsFromModulesToStructuredData(final Set<Module> modules,
238 final MountInstance mountPoint) {
239 final List<Node<?>> operationsAsData = new ArrayList<Node<?>>();
240 Module restconfModule = this.getRestconfModule();
241 final DataSchemaNode operationsSchemaNode = controllerContext.getRestconfModuleRestConfSchemaNode(
242 restconfModule, Draft02.RestConfModule.OPERATIONS_CONTAINER_SCHEMA_NODE);
243 QName qName = operationsSchemaNode.getQName();
244 SchemaPath path = operationsSchemaNode.getPath();
245 ContainerSchemaNodeBuilder containerSchemaNodeBuilder =
246 new ContainerSchemaNodeBuilder(Draft02.RestConfModule.NAME, 0, qName, path);
247 final ContainerSchemaNodeBuilder fakeOperationsSchemaNode = containerSchemaNodeBuilder;
248 for (final Module module : modules) {
249 Set<RpcDefinition> rpcs = module.getRpcs();
250 for (final RpcDefinition rpc : rpcs) {
251 QName rpcQName = rpc.getQName();
252 SimpleNode<Object> immutableSimpleNode =
253 NodeFactory.<Object>createImmutableSimpleNode(rpcQName, null, null);
254 operationsAsData.add(immutableSimpleNode);
256 String name = module.getName();
257 LeafSchemaNodeBuilder leafSchemaNodeBuilder = new LeafSchemaNodeBuilder(name, 0, rpcQName, null);
258 final LeafSchemaNodeBuilder fakeRpcSchemaNode = leafSchemaNodeBuilder;
259 fakeRpcSchemaNode.setAugmenting(true);
261 EmptyType instance = EmptyType.getInstance();
262 fakeRpcSchemaNode.setType(instance);
263 fakeOperationsSchemaNode.addChildNode(fakeRpcSchemaNode.build());
267 final CompositeNode operationsNode =
268 NodeFactory.createImmutableCompositeNode(qName, null, operationsAsData);
269 ContainerSchemaNode schemaNode = fakeOperationsSchemaNode.build();
270 return new StructuredData(operationsNode, schemaNode, mountPoint);
273 private Module getRestconfModule() {
274 Module restconfModule = controllerContext.getRestconfModule();
275 if (restconfModule == null) {
276 throw new RestconfDocumentedException(
277 "ietf-restconf module was not found.", ErrorType.APPLICATION,
278 ErrorTag.OPERATION_NOT_SUPPORTED );
281 return restconfModule;
284 private QName getModuleNameAndRevision(final String identifier) {
285 final int mountIndex = identifier.indexOf(ControllerContext.MOUNT);
286 String moduleNameAndRevision = "";
287 if (mountIndex >= 0) {
288 moduleNameAndRevision = identifier.substring(mountIndex + ControllerContext.MOUNT.length());
291 moduleNameAndRevision = identifier;
294 Splitter splitter = Splitter.on("/").omitEmptyStrings();
295 Iterable<String> split = splitter.split(moduleNameAndRevision);
296 final List<String> pathArgs = Lists.<String>newArrayList(split);
297 if (pathArgs.size() < 2) {
298 throw new RestconfDocumentedException(
299 "URI has bad format. End of URI should be in format \'moduleName/yyyy-MM-dd\'",
300 ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
304 final String moduleName = pathArgs.get( 0 );
305 String revision = pathArgs.get(1);
306 final Date moduleRevision = REVISION_FORMAT.parse(revision);
307 return QName.create(null, moduleRevision, moduleName);
309 catch (ParseException e) {
310 throw new RestconfDocumentedException(
311 "URI has bad format. It should be \'moduleName/yyyy-MM-dd\'",
312 ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
316 private CompositeNode toStreamCompositeNode(final String streamName, final DataSchemaNode streamSchemaNode) {
317 final List<Node<?>> streamNodeValues = new ArrayList<Node<?>>();
318 List<DataSchemaNode> instanceDataChildrenByName =
319 this.controllerContext.findInstanceDataChildrenByName(((DataNodeContainer) streamSchemaNode),
321 final DataSchemaNode nameSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null);
322 streamNodeValues.add(NodeFactory.<String>createImmutableSimpleNode(nameSchemaNode.getQName(), null,
325 instanceDataChildrenByName = this.controllerContext.findInstanceDataChildrenByName(
326 ((DataNodeContainer) streamSchemaNode), "description");
327 final DataSchemaNode descriptionSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null);
328 streamNodeValues.add(NodeFactory.<String>createImmutableSimpleNode(descriptionSchemaNode.getQName(), null,
329 "DESCRIPTION_PLACEHOLDER"));
331 instanceDataChildrenByName = this.controllerContext.findInstanceDataChildrenByName(
332 ((DataNodeContainer) streamSchemaNode), "replay-support");
333 final DataSchemaNode replaySupportSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null);
334 streamNodeValues.add(NodeFactory.<Boolean>createImmutableSimpleNode(replaySupportSchemaNode.getQName(), null,
335 Boolean.valueOf(true)));
337 instanceDataChildrenByName = this.controllerContext.findInstanceDataChildrenByName(
338 ((DataNodeContainer) streamSchemaNode), "replay-log-creation-time");
339 final DataSchemaNode replayLogCreationTimeSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null);
340 streamNodeValues.add(NodeFactory.<String>createImmutableSimpleNode(replayLogCreationTimeSchemaNode.getQName(),
343 instanceDataChildrenByName = this.controllerContext.findInstanceDataChildrenByName(
344 ((DataNodeContainer) streamSchemaNode), "events");
345 final DataSchemaNode eventsSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null);
346 streamNodeValues.add(NodeFactory.<String>createImmutableSimpleNode(eventsSchemaNode.getQName(),
349 return NodeFactory.createImmutableCompositeNode(streamSchemaNode.getQName(), null, streamNodeValues);
352 private CompositeNode toModuleCompositeNode(final Module module, final DataSchemaNode moduleSchemaNode) {
353 final List<Node<?>> moduleNodeValues = new ArrayList<Node<?>>();
354 List<DataSchemaNode> instanceDataChildrenByName =
355 this.controllerContext.findInstanceDataChildrenByName(((DataNodeContainer) moduleSchemaNode), "name");
356 final DataSchemaNode nameSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null);
357 moduleNodeValues.add(NodeFactory.<String>createImmutableSimpleNode(nameSchemaNode.getQName(),
358 null, module.getName()));
360 instanceDataChildrenByName = this.controllerContext.findInstanceDataChildrenByName(
361 ((DataNodeContainer) moduleSchemaNode), "revision");
362 final DataSchemaNode revisionSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null);
363 Date _revision = module.getRevision();
364 moduleNodeValues.add(NodeFactory.<String>createImmutableSimpleNode(revisionSchemaNode.getQName(), null,
365 REVISION_FORMAT.format(_revision)));
367 instanceDataChildrenByName = this.controllerContext.findInstanceDataChildrenByName(
368 ((DataNodeContainer) moduleSchemaNode), "namespace");
369 final DataSchemaNode namespaceSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null);
370 moduleNodeValues.add(NodeFactory.<String>createImmutableSimpleNode(namespaceSchemaNode.getQName(), null,
371 module.getNamespace().toString()));
373 instanceDataChildrenByName = this.controllerContext.findInstanceDataChildrenByName(
374 ((DataNodeContainer) moduleSchemaNode), "feature");
375 final DataSchemaNode featureSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null);
376 for (final FeatureDefinition feature : module.getFeatures()) {
377 moduleNodeValues.add(NodeFactory.<String>createImmutableSimpleNode(featureSchemaNode.getQName(), null,
378 feature.getQName().getLocalName()));
381 return NodeFactory.createImmutableCompositeNode(moduleSchemaNode.getQName(), null, moduleNodeValues);
385 public Object getRoot() {
390 public StructuredData invokeRpc(final String identifier, final CompositeNode payload) {
391 final RpcExecutor rpc = this.resolveIdentifierInInvokeRpc(identifier);
392 QName rpcName = rpc.getRpcDefinition().getQName();
393 URI rpcNamespace = rpcName.getNamespace();
394 if (Objects.equal(rpcNamespace.toString(), SAL_REMOTE_NAMESPACE) &&
395 Objects.equal(rpcName.getLocalName(), SAL_REMOTE_RPC_SUBSRCIBE)) {
396 return invokeSalRemoteRpcSubscribeRPC(payload, rpc.getRpcDefinition());
399 validateInput( rpc.getRpcDefinition().getInput(), payload );
401 return callRpc(rpc, payload);
404 private void validateInput(DataSchemaNode inputSchema, CompositeNode payload) {
405 if( inputSchema != null && payload == null )
407 //expected a non null payload
408 throw new RestconfDocumentedException( "Input is required.",
410 ErrorTag.MALFORMED_MESSAGE );
412 else if( inputSchema == null && payload != null )
414 //did not expect any input
415 throw new RestconfDocumentedException( "No input expected.",
417 ErrorTag.MALFORMED_MESSAGE );
421 //TODO: Validate "mandatory" and "config" values here??? Or should those be
422 // validate in a more central location inside MD-SAL core.
426 private StructuredData invokeSalRemoteRpcSubscribeRPC(final CompositeNode payload,
427 final RpcDefinition rpc) {
428 final CompositeNode value = this.normalizeNode(payload, rpc.getInput(), null);
429 final SimpleNode<? extends Object> pathNode = value == null ? null :
430 value.getFirstSimpleByName( QName.create(rpc.getQName(), "path") );
431 final Object pathValue = pathNode == null ? null : pathNode.getValue();
433 if (!(pathValue instanceof InstanceIdentifier)) {
434 throw new RestconfDocumentedException(
435 "Instance identifier was not normalized correctly.",
436 ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED );
439 final InstanceIdentifier pathIdentifier = ((InstanceIdentifier) pathValue);
440 String streamName = null;
441 if (!Iterables.isEmpty(pathIdentifier.getPath())) {
442 String fullRestconfIdentifier = this.controllerContext.toFullRestconfIdentifier(pathIdentifier);
443 streamName = Notificator.createStreamNameFromUri(fullRestconfIdentifier);
446 if (Strings.isNullOrEmpty(streamName)) {
447 throw new RestconfDocumentedException(
448 "Path is empty or contains data node which is not Container or List build-in type.",
449 ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
452 final SimpleNode<String> streamNameNode = NodeFactory.<String>createImmutableSimpleNode(
453 QName.create(rpc.getOutput().getQName(), "stream-name"), null, streamName);
454 final List<Node<?>> output = new ArrayList<Node<?>>();
455 output.add(streamNameNode);
457 final MutableCompositeNode responseData = NodeFactory.createMutableCompositeNode(
458 rpc.getOutput().getQName(), null, output, null, null);
460 if (!Notificator.existListenerFor(pathIdentifier)) {
461 Notificator.createListener(pathIdentifier, streamName);
464 return new StructuredData(responseData, rpc.getOutput(), null);
468 public StructuredData invokeRpc(final String identifier, final String noPayload) {
469 if (StringUtils.isNotBlank(noPayload)) {
470 throw new RestconfDocumentedException(
471 "Content must be empty.", ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
473 return invokeRpc( identifier, (CompositeNode)null );
476 private RpcExecutor resolveIdentifierInInvokeRpc(final String identifier) {
477 String identifierEncoded = null;
478 MountInstance mountPoint = null;
479 if (identifier.contains(ControllerContext.MOUNT)) {
480 // mounted RPC call - look up mount instance.
481 InstanceIdWithSchemaNode mountPointId = controllerContext
482 .toMountPointIdentifier(identifier);
483 mountPoint = mountPointId.getMountPoint();
485 int startOfRemoteRpcName = identifier.lastIndexOf(ControllerContext.MOUNT)
486 + ControllerContext.MOUNT.length() + 1;
487 String remoteRpcName = identifier.substring(startOfRemoteRpcName);
488 identifierEncoded = remoteRpcName;
490 } else if (identifier.indexOf("/") != CHAR_NOT_FOUND) {
491 final String slashErrorMsg = String
492 .format("Identifier %n%s%ncan\'t contain slash "
493 + "character (/).%nIf slash is part of identifier name then use %%2F placeholder.",
495 throw new RestconfDocumentedException(
496 slashErrorMsg, ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
498 identifierEncoded = identifier;
501 final String identifierDecoded = controllerContext.urlPathArgDecode(identifierEncoded);
502 RpcDefinition rpc = controllerContext.getRpcDefinition(identifierDecoded);
505 throw new RestconfDocumentedException(
506 "RPC does not exist.", ErrorType.RPC, ErrorTag.UNKNOWN_ELEMENT );
509 if (mountPoint == null) {
510 return new BrokerRpcExecutor(rpc, broker);
512 return new MountPointRpcExecutor(rpc, mountPoint);
517 private StructuredData callRpc(final RpcExecutor rpcExecutor, final CompositeNode payload) {
518 if (rpcExecutor == null) {
519 throw new RestconfDocumentedException(
520 "RPC does not exist.", ErrorType.RPC, ErrorTag.UNKNOWN_ELEMENT );
523 CompositeNode rpcRequest = null;
524 RpcDefinition rpc = rpcExecutor.getRpcDefinition();
525 QName rpcName = rpc.getQName();
527 if (payload == null) {
528 rpcRequest = NodeFactory.createMutableCompositeNode(rpcName, null, null, null, null);
530 final CompositeNode value = this.normalizeNode(payload, rpc.getInput(), null);
531 List<Node<?>> input = Collections.<Node<?>> singletonList(value);
532 rpcRequest = NodeFactory.createMutableCompositeNode(rpcName, null, input, null, null);
535 RpcResult<CompositeNode> rpcResult = rpcExecutor.invokeRpc(rpcRequest);
537 checkRpcSuccessAndThrowException(rpcResult);
539 if (rpcResult.getResult() == null) {
543 if( rpc.getOutput() == null )
545 return null; //no output, nothing to send back.
548 return new StructuredData(rpcResult.getResult(), rpc.getOutput(), null);
551 private void checkRpcSuccessAndThrowException(RpcResult<CompositeNode> rpcResult) {
552 if (rpcResult.isSuccessful() == false) {
554 Collection<RpcError> rpcErrors = rpcResult.getErrors();
555 if( rpcErrors == null || rpcErrors.isEmpty() ) {
556 throw new RestconfDocumentedException(
557 "The operation was not successful and there were no RPC errors returned",
558 ErrorType.RPC, ErrorTag.OPERATION_FAILED );
561 List<RestconfError> errorList = Lists.newArrayList();
562 for( RpcError rpcError: rpcErrors ) {
563 errorList.add( new RestconfError( rpcError ) );
566 throw new RestconfDocumentedException( errorList );
571 public StructuredData readConfigurationData(final String identifier, UriInfo info) {
572 final InstanceIdWithSchemaNode iiWithData = this.controllerContext.toInstanceIdentifier(identifier);
573 CompositeNode data = null;
574 MountInstance mountPoint = iiWithData.getMountPoint();
575 if (mountPoint != null) {
576 data = broker.readConfigurationDataBehindMountPoint(mountPoint, iiWithData.getInstanceIdentifier());
579 data = broker.readConfigurationData(iiWithData.getInstanceIdentifier());
582 data = pruneDataAtDepth( data, parseDepthParameter( info ) );
583 return new StructuredData(data, iiWithData.getSchemaNode(), iiWithData.getMountPoint());
586 @SuppressWarnings("unchecked")
587 private <T extends Node<?>> T pruneDataAtDepth( T node, Integer depth ) {
588 if( depth == null ) {
592 if( node instanceof CompositeNode ) {
593 ImmutableList.Builder<Node<?>> newChildNodes = ImmutableList.<Node<?>> builder();
595 for( Node<?> childNode: ((CompositeNode)node).getValue() ) {
596 newChildNodes.add( pruneDataAtDepth( childNode, depth - 1 ) );
600 return (T) ImmutableCompositeNode.create( node.getNodeType(), newChildNodes.build() );
607 private Integer parseDepthParameter( UriInfo info ) {
608 String param = info.getQueryParameters( false ).getFirst( "depth" );
609 if( Strings.isNullOrEmpty( param ) || "unbounded".equals( param ) ) {
614 Integer depth = Integer.valueOf( param );
616 throw new RestconfDocumentedException( new RestconfError(
617 ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE, "Invalid depth parameter: " + depth,
618 null, "The depth parameter must be an integer > 1 or \"unbounded\"" ) );
623 catch( NumberFormatException e ) {
624 throw new RestconfDocumentedException( new RestconfError(
625 ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE,
626 "Invalid depth parameter: " + e.getMessage(),
627 null, "The depth parameter must be an integer > 1 or \"unbounded\"" ) );
632 public StructuredData readOperationalData(final String identifier, UriInfo info) {
633 final InstanceIdWithSchemaNode iiWithData = this.controllerContext.toInstanceIdentifier(identifier);
634 CompositeNode data = null;
635 MountInstance mountPoint = iiWithData.getMountPoint();
636 if (mountPoint != null) {
637 data = broker.readOperationalDataBehindMountPoint(mountPoint, iiWithData.getInstanceIdentifier());
640 data = broker.readOperationalData(iiWithData.getInstanceIdentifier());
643 data = pruneDataAtDepth( data, parseDepthParameter( info ) );
644 return new StructuredData(data, iiWithData.getSchemaNode(), mountPoint);
648 public Response updateConfigurationData(final String identifier, final CompositeNode payload) {
649 final InstanceIdWithSchemaNode iiWithData = this.controllerContext.toInstanceIdentifier(identifier);
651 validateInput(iiWithData.getSchemaNode(), payload);
653 MountInstance mountPoint = iiWithData.getMountPoint();
654 final CompositeNode value = this.normalizeNode(payload, iiWithData.getSchemaNode(), mountPoint);
655 RpcResult<TransactionStatus> status = null;
658 if (mountPoint != null) {
659 status = broker.commitConfigurationDataPutBehindMountPoint(
660 mountPoint, iiWithData.getInstanceIdentifier(), value).get();
662 status = broker.commitConfigurationDataPut(iiWithData.getInstanceIdentifier(), value).get();
665 catch( Exception e ) {
666 throw new RestconfDocumentedException( "Error updating data", e );
669 if( status.getResult() == TransactionStatus.COMMITED )
670 return Response.status(Status.OK).build();
672 return Response.status(Status.INTERNAL_SERVER_ERROR).build();
676 public Response createConfigurationData(final String identifier, final CompositeNode payload) {
677 if( payload == null ) {
678 throw new RestconfDocumentedException( "Input is required.",
680 ErrorTag.MALFORMED_MESSAGE );
683 URI payloadNS = this.namespace(payload);
684 if (payloadNS == null) {
685 throw new RestconfDocumentedException(
686 "Data has bad format. Root element node must have namespace (XML format) or module name(JSON format)",
687 ErrorType.PROTOCOL, ErrorTag.UNKNOWN_NAMESPACE );
690 InstanceIdWithSchemaNode iiWithData = null;
691 CompositeNode value = null;
692 if (this.representsMountPointRootData(payload)) {
693 // payload represents mount point data and URI represents path to the mount point
695 if (this.endsWithMountPoint(identifier)) {
696 throw new RestconfDocumentedException(
697 "URI has bad format. URI should be without \"" + ControllerContext.MOUNT +
698 "\" for POST operation.",
699 ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
702 final String completeIdentifier = this.addMountPointIdentifier(identifier);
703 iiWithData = this.controllerContext.toInstanceIdentifier(completeIdentifier);
705 value = this.normalizeNode(payload, iiWithData.getSchemaNode(), iiWithData.getMountPoint());
708 final InstanceIdWithSchemaNode incompleteInstIdWithData =
709 this.controllerContext.toInstanceIdentifier(identifier);
710 final DataNodeContainer parentSchema = (DataNodeContainer) incompleteInstIdWithData.getSchemaNode();
711 MountInstance mountPoint = incompleteInstIdWithData.getMountPoint();
712 final Module module = this.findModule(mountPoint, payload);
713 if (module == null) {
714 throw new RestconfDocumentedException(
715 "Module was not found for \"" + payloadNS + "\"",
716 ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT );
719 String payloadName = this.getName(payload);
720 final DataSchemaNode schemaNode = this.controllerContext.findInstanceDataChildByNameAndNamespace(
721 parentSchema, payloadName, module.getNamespace());
722 value = this.normalizeNode(payload, schemaNode, mountPoint);
724 iiWithData = this.addLastIdentifierFromData(incompleteInstIdWithData, value, schemaNode);
727 RpcResult<TransactionStatus> status = null;
728 MountInstance mountPoint = iiWithData.getMountPoint();
730 if (mountPoint != null) {
731 Future<RpcResult<TransactionStatus>> future =
732 broker.commitConfigurationDataPostBehindMountPoint(
733 mountPoint, iiWithData.getInstanceIdentifier(), value);
734 status = future == null ? null : future.get();
737 Future<RpcResult<TransactionStatus>> future =
738 broker.commitConfigurationDataPost(iiWithData.getInstanceIdentifier(), value);
739 status = future == null ? null : future.get();
742 catch( Exception e ) {
743 throw new RestconfDocumentedException( "Error creating data", e );
746 if (status == null) {
747 return Response.status(Status.ACCEPTED).build();
750 if( status.getResult() == TransactionStatus.COMMITED )
751 return Response.status(Status.NO_CONTENT).build();
753 return Response.status(Status.INTERNAL_SERVER_ERROR).build();
757 public Response createConfigurationData(final CompositeNode payload) {
758 if( payload == null ) {
759 throw new RestconfDocumentedException( "Input is required.",
761 ErrorTag.MALFORMED_MESSAGE );
764 URI payloadNS = this.namespace(payload);
765 if (payloadNS == null) {
766 throw new RestconfDocumentedException(
767 "Data has bad format. Root element node must have namespace (XML format) or module name(JSON format)",
768 ErrorType.PROTOCOL, ErrorTag.UNKNOWN_NAMESPACE );
771 final Module module = this.findModule(null, payload);
772 if (module == null) {
773 throw new RestconfDocumentedException(
774 "Data has bad format. Root element node has incorrect namespace (XML format) or module name(JSON format)",
775 ErrorType.PROTOCOL, ErrorTag.UNKNOWN_NAMESPACE );
778 String payloadName = this.getName(payload);
779 final DataSchemaNode schemaNode = this.controllerContext.findInstanceDataChildByNameAndNamespace(
780 module, payloadName, module.getNamespace());
781 final CompositeNode value = this.normalizeNode(payload, schemaNode, null);
782 final InstanceIdWithSchemaNode iiWithData = this.addLastIdentifierFromData(null, value, schemaNode);
783 RpcResult<TransactionStatus> status = null;
784 MountInstance mountPoint = iiWithData.getMountPoint();
787 if (mountPoint != null) {
788 Future<RpcResult<TransactionStatus>> future =
789 broker.commitConfigurationDataPostBehindMountPoint(
790 mountPoint, iiWithData.getInstanceIdentifier(), value);
791 status = future == null ? null : future.get();
794 Future<RpcResult<TransactionStatus>> future =
795 broker.commitConfigurationDataPost(iiWithData.getInstanceIdentifier(), value);
796 status = future == null ? null : future.get();
799 catch( Exception e ) {
800 throw new RestconfDocumentedException( "Error creating data", e );
803 if (status == null) {
804 return Response.status(Status.ACCEPTED).build();
807 if( status.getResult() == TransactionStatus.COMMITED )
808 return Response.status(Status.NO_CONTENT).build();
810 return Response.status(Status.INTERNAL_SERVER_ERROR).build();
814 public Response deleteConfigurationData(final String identifier) {
815 final InstanceIdWithSchemaNode iiWithData = this.controllerContext.toInstanceIdentifier(identifier);
816 RpcResult<TransactionStatus> status = null;
817 MountInstance mountPoint = iiWithData.getMountPoint();
820 if (mountPoint != null) {
821 status = broker.commitConfigurationDataDeleteBehindMountPoint(
822 mountPoint, iiWithData.getInstanceIdentifier()).get();
825 status = broker.commitConfigurationDataDelete(iiWithData.getInstanceIdentifier()).get();
828 catch( Exception e ) {
829 throw new RestconfDocumentedException( "Error creating data", e );
832 if( status.getResult() == TransactionStatus.COMMITED )
833 return Response.status(Status.OK).build();
835 return Response.status(Status.INTERNAL_SERVER_ERROR).build();
839 public Response subscribeToStream(final String identifier, final UriInfo uriInfo) {
840 final String streamName = Notificator.createStreamNameFromUri(identifier);
841 if (Strings.isNullOrEmpty(streamName)) {
842 throw new RestconfDocumentedException(
843 "Stream name is empty.", ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
846 final ListenerAdapter listener = Notificator.getListenerFor(streamName);
847 if (listener == null) {
848 throw new RestconfDocumentedException(
849 "Stream was not found.", ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT );
852 broker.registerToListenDataChanges(listener);
854 final UriBuilder uriBuilder = uriInfo.getAbsolutePathBuilder();
855 UriBuilder port = uriBuilder.port(WebSocketServer.PORT);
856 final URI uriToWebsocketServer = port.replacePath(streamName).build();
858 return Response.status(Status.OK).location(uriToWebsocketServer).build();
861 private Module findModule(final MountInstance mountPoint, final CompositeNode data) {
862 if (data instanceof CompositeNodeWrapper) {
863 return findModule(mountPoint, (CompositeNodeWrapper)data);
865 else if (data != null) {
866 URI namespace = data.getNodeType().getNamespace();
867 if (mountPoint != null) {
868 return this.controllerContext.findModuleByNamespace(mountPoint, namespace);
871 return this.controllerContext.findModuleByNamespace(namespace);
875 throw new IllegalArgumentException("Unhandled parameter types: " +
876 Arrays.<Object>asList(mountPoint, data).toString());
880 private Module findModule(final MountInstance mountPoint, final CompositeNodeWrapper data) {
881 URI namespace = data.getNamespace();
882 Preconditions.<URI>checkNotNull(namespace);
884 Module module = null;
885 if (mountPoint != null) {
886 module = this.controllerContext.findModuleByNamespace(mountPoint, namespace);
887 if (module == null) {
888 module = this.controllerContext.findModuleByName(mountPoint, namespace.toString());
892 module = this.controllerContext.findModuleByNamespace(namespace);
893 if (module == null) {
894 module = this.controllerContext.findModuleByName(namespace.toString());
901 private InstanceIdWithSchemaNode addLastIdentifierFromData(
902 final InstanceIdWithSchemaNode identifierWithSchemaNode,
903 final CompositeNode data, final DataSchemaNode schemaOfData) {
904 InstanceIdentifier instanceIdentifier = null;
905 if (identifierWithSchemaNode != null) {
906 instanceIdentifier = identifierWithSchemaNode.getInstanceIdentifier();
909 final InstanceIdentifier iiOriginal = instanceIdentifier;
910 InstanceIdentifierBuilder iiBuilder = null;
911 if (iiOriginal == null) {
912 iiBuilder = InstanceIdentifier.builder();
915 iiBuilder = InstanceIdentifier.builder(iiOriginal);
918 if ((schemaOfData instanceof ListSchemaNode)) {
919 HashMap<QName,Object> keys = this.resolveKeysFromData(((ListSchemaNode) schemaOfData), data);
920 iiBuilder.nodeWithKey(schemaOfData.getQName(), keys);
923 iiBuilder.node(schemaOfData.getQName());
926 InstanceIdentifier instance = iiBuilder.toInstance();
927 MountInstance mountPoint = null;
928 if (identifierWithSchemaNode != null) {
929 mountPoint=identifierWithSchemaNode.getMountPoint();
932 return new InstanceIdWithSchemaNode(instance, schemaOfData, mountPoint);
935 private HashMap<QName,Object> resolveKeysFromData(final ListSchemaNode listNode,
936 final CompositeNode dataNode) {
937 final HashMap<QName,Object> keyValues = new HashMap<QName, Object>();
938 List<QName> _keyDefinition = listNode.getKeyDefinition();
939 for (final QName key : _keyDefinition) {
940 SimpleNode<? extends Object> head = null;
941 String localName = key.getLocalName();
942 List<SimpleNode<? extends Object>> simpleNodesByName = dataNode.getSimpleNodesByName(localName);
943 if (simpleNodesByName != null) {
944 head = Iterables.getFirst(simpleNodesByName, null);
947 Object dataNodeKeyValueObject = null;
949 dataNodeKeyValueObject = head.getValue();
952 if (dataNodeKeyValueObject == null) {
953 throw new RestconfDocumentedException(
954 "Data contains list \"" + dataNode.getNodeType().getLocalName() +
955 "\" which does not contain key: \"" + key.getLocalName() + "\"",
956 ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
959 keyValues.put(key, dataNodeKeyValueObject);
965 private boolean endsWithMountPoint(final String identifier) {
966 return identifier.endsWith(ControllerContext.MOUNT) ||
967 identifier.endsWith(ControllerContext.MOUNT + "/");
970 private boolean representsMountPointRootData(final CompositeNode data) {
971 URI namespace = this.namespace(data);
972 return (SchemaContext.NAME.getNamespace().equals( namespace ) /* ||
973 MOUNT_POINT_MODULE_NAME.equals( namespace.toString() )*/ ) &&
974 SchemaContext.NAME.getLocalName().equals( this.localName(data) );
977 private String addMountPointIdentifier(final String identifier) {
978 boolean endsWith = identifier.endsWith("/");
980 return (identifier + ControllerContext.MOUNT);
983 return identifier + "/" + ControllerContext.MOUNT;
986 private CompositeNode normalizeNode(final CompositeNode node, final DataSchemaNode schema,
987 final MountInstance mountPoint) {
988 if (schema == null) {
989 QName nodeType = node == null ? null : node.getNodeType();
990 String localName = nodeType == null ? null : nodeType.getLocalName();
992 throw new RestconfDocumentedException(
993 "Data schema node was not found for " + localName,
994 ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
997 if (!(schema instanceof DataNodeContainer)) {
998 throw new RestconfDocumentedException(
999 "Root element has to be container or list yang datatype.",
1000 ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
1003 if ((node instanceof CompositeNodeWrapper)) {
1004 boolean isChangeAllowed = ((CompositeNodeWrapper) node).isChangeAllowed();
1005 if (isChangeAllowed) {
1007 this.normalizeNode(((CompositeNodeWrapper) node), schema, null, mountPoint);
1009 catch (IllegalArgumentException e) {
1010 throw new RestconfDocumentedException(
1011 e.getMessage(), ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
1015 return ((CompositeNodeWrapper) node).unwrap();
1021 private void normalizeNode(final NodeWrapper<? extends Object> nodeBuilder,
1022 final DataSchemaNode schema, final QName previousAugment,
1023 final MountInstance mountPoint) {
1024 if (schema == null) {
1025 throw new RestconfDocumentedException(
1026 "Data has bad format.\n\"" + nodeBuilder.getLocalName() +
1027 "\" does not exist in yang schema.",
1028 ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
1031 QName currentAugment = null;
1032 if (nodeBuilder.getQname() != null) {
1033 currentAugment = previousAugment;
1036 currentAugment = this.normalizeNodeName(nodeBuilder, schema, previousAugment, mountPoint);
1037 if (nodeBuilder.getQname() == null) {
1038 throw new RestconfDocumentedException(
1039 "Data has bad format.\nIf data is in XML format then namespace for \"" +
1040 nodeBuilder.getLocalName() +
1041 "\" should be \"" + schema.getQName().getNamespace() + "\".\n" +
1042 "If data is in JSON format then module name for \"" + nodeBuilder.getLocalName() +
1043 "\" should be corresponding to namespace \"" +
1044 schema.getQName().getNamespace() + "\".",
1045 ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
1049 if ((nodeBuilder instanceof CompositeNodeWrapper)) {
1050 final List<NodeWrapper<?>> children = ((CompositeNodeWrapper) nodeBuilder).getValues();
1051 for (final NodeWrapper<? extends Object> child : children) {
1052 final List<DataSchemaNode> potentialSchemaNodes =
1053 this.controllerContext.findInstanceDataChildrenByName(
1054 ((DataNodeContainer) schema), child.getLocalName());
1056 if (potentialSchemaNodes.size() > 1 && child.getNamespace() == null) {
1057 StringBuilder builder = new StringBuilder();
1058 for (final DataSchemaNode potentialSchemaNode : potentialSchemaNodes) {
1059 builder.append(" ").append(potentialSchemaNode.getQName().getNamespace().toString())
1063 throw new RestconfDocumentedException(
1064 "Node \"" + child.getLocalName() +
1065 "\" is added as augment from more than one module. " +
1066 "Therefore node must have namespace (XML format) or module name (JSON format)." +
1067 "\nThe node is added as augment from modules with namespaces:\n" + builder,
1068 ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
1071 boolean rightNodeSchemaFound = false;
1072 for (final DataSchemaNode potentialSchemaNode : potentialSchemaNodes) {
1073 if (!rightNodeSchemaFound) {
1074 final QName potentialCurrentAugment =
1075 this.normalizeNodeName(child, potentialSchemaNode, currentAugment, mountPoint);
1076 if (child.getQname() != null ) {
1077 this.normalizeNode(child, potentialSchemaNode, potentialCurrentAugment, mountPoint);
1078 rightNodeSchemaFound = true;
1083 if (!rightNodeSchemaFound) {
1084 throw new RestconfDocumentedException(
1085 "Schema node \"" + child.getLocalName() + "\" was not found in module.",
1086 ErrorType.APPLICATION, ErrorTag.UNKNOWN_ELEMENT );
1090 if ((schema instanceof ListSchemaNode)) {
1091 final List<QName> listKeys = ((ListSchemaNode) schema).getKeyDefinition();
1092 for (final QName listKey : listKeys) {
1093 boolean foundKey = false;
1094 for (final NodeWrapper<? extends Object> child : children) {
1095 if (Objects.equal(child.unwrap().getNodeType().getLocalName(), listKey.getLocalName())) {
1101 throw new RestconfDocumentedException(
1102 "Missing key in URI \"" + listKey.getLocalName() +
1103 "\" of list \"" + schema.getQName().getLocalName() + "\"",
1104 ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
1110 if ((nodeBuilder instanceof SimpleNodeWrapper)) {
1111 final SimpleNodeWrapper simpleNode = ((SimpleNodeWrapper) nodeBuilder);
1112 final Object value = simpleNode.getValue();
1113 Object inputValue = value;
1114 TypeDefinition<? extends Object> typeDefinition = this.typeDefinition(schema);
1115 if ((typeDefinition instanceof IdentityrefTypeDefinition)) {
1116 if ((value instanceof String)) {
1117 inputValue = new IdentityValuesDTO( nodeBuilder.getNamespace().toString(),
1118 (String) value, null, (String) value );
1119 } // else value is already instance of IdentityValuesDTO
1122 Codec<Object,Object> codec = RestCodec.from(typeDefinition, mountPoint);
1123 Object outputValue = codec == null ? null : codec.deserialize(inputValue);
1125 simpleNode.setValue(outputValue);
1128 if ((nodeBuilder instanceof EmptyNodeWrapper)) {
1129 final EmptyNodeWrapper emptyNodeBuilder = ((EmptyNodeWrapper) nodeBuilder);
1130 if ((schema instanceof LeafSchemaNode)) {
1131 emptyNodeBuilder.setComposite(false);
1134 if ((schema instanceof ContainerSchemaNode)) {
1135 // FIXME: Add presence check
1136 emptyNodeBuilder.setComposite(true);
1144 private QName normalizeNodeName(final NodeWrapper<? extends Object> nodeBuilder,
1145 final DataSchemaNode schema, final QName previousAugment,
1146 final MountInstance mountPoint) {
1147 QName validQName = schema.getQName();
1148 QName currentAugment = previousAugment;
1149 if (schema.isAugmenting()) {
1150 currentAugment = schema.getQName();
1152 else if (previousAugment != null &&
1153 !Objects.equal( schema.getQName().getNamespace(), previousAugment.getNamespace())) {
1154 validQName = QName.create(currentAugment, schema.getQName().getLocalName());
1157 String moduleName = null;
1158 if (mountPoint == null) {
1159 moduleName = controllerContext.findModuleNameByNamespace(validQName.getNamespace());
1162 moduleName = controllerContext.findModuleNameByNamespace(mountPoint, validQName.getNamespace());
1165 if (nodeBuilder.getNamespace() == null ||
1166 Objects.equal(nodeBuilder.getNamespace(), validQName.getNamespace()) ||
1167 Objects.equal(nodeBuilder.getNamespace().toString(), moduleName) /*||
1168 Note: this check is wrong - can never be true as it compares a URI with a String
1169 not sure what the intention is so commented out...
1170 Objects.equal(nodeBuilder.getNamespace(), MOUNT_POINT_MODULE_NAME)*/ ) {
1172 nodeBuilder.setQname(validQName);
1175 return currentAugment;
1178 private URI namespace(final CompositeNode data) {
1179 if (data instanceof CompositeNodeWrapper) {
1180 return ((CompositeNodeWrapper)data).getNamespace();
1182 else if (data != null) {
1183 return data.getNodeType().getNamespace();
1186 throw new IllegalArgumentException("Unhandled parameter types: " +
1187 Arrays.<Object>asList(data).toString());
1191 private String localName(final CompositeNode data) {
1192 if (data instanceof CompositeNodeWrapper) {
1193 return ((CompositeNodeWrapper)data).getLocalName();
1195 else if (data != null) {
1196 return data.getNodeType().getLocalName();
1199 throw new IllegalArgumentException("Unhandled parameter types: " +
1200 Arrays.<Object>asList(data).toString());
1204 private String getName(final CompositeNode data) {
1205 if (data instanceof CompositeNodeWrapper) {
1206 return ((CompositeNodeWrapper)data).getLocalName();
1208 else if (data != null) {
1209 return data.getNodeType().getLocalName();
1212 throw new IllegalArgumentException("Unhandled parameter types: " +
1213 Arrays.<Object>asList(data).toString());
1217 private TypeDefinition<? extends Object> _typeDefinition(final LeafSchemaNode node) {
1218 TypeDefinition<?> baseType = node.getType();
1219 while (baseType.getBaseType() != null) {
1220 baseType = baseType.getBaseType();
1226 private TypeDefinition<? extends Object> typeDefinition(final LeafListSchemaNode node) {
1227 TypeDefinition<?> baseType = node.getType();
1228 while (baseType.getBaseType() != null) {
1229 baseType = baseType.getBaseType();
1235 private TypeDefinition<? extends Object> typeDefinition(final DataSchemaNode node) {
1236 if (node instanceof LeafListSchemaNode) {
1237 return typeDefinition((LeafListSchemaNode)node);
1239 else if (node instanceof LeafSchemaNode) {
1240 return _typeDefinition((LeafSchemaNode)node);
1243 throw new IllegalArgumentException("Unhandled parameter types: " +
1244 Arrays.<Object>asList(node).toString());