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;
11 import com.google.common.base.Objects;
12 import com.google.common.base.Preconditions;
13 import com.google.common.base.Splitter;
14 import com.google.common.base.Strings;
15 import com.google.common.collect.ImmutableList;
16 import com.google.common.collect.Iterables;
17 import com.google.common.collect.Lists;
19 import java.text.ParseException;
20 import java.text.SimpleDateFormat;
21 import java.util.ArrayList;
22 import java.util.Arrays;
23 import java.util.Collection;
24 import java.util.Collections;
25 import java.util.Date;
26 import java.util.HashMap;
27 import java.util.List;
29 import java.util.concurrent.Future;
30 import javax.ws.rs.core.Response;
31 import javax.ws.rs.core.Response.Status;
32 import javax.ws.rs.core.UriBuilder;
33 import javax.ws.rs.core.UriInfo;
34 import org.apache.commons.lang3.StringUtils;
35 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
36 import org.opendaylight.controller.sal.core.api.mount.MountInstance;
37 import org.opendaylight.controller.sal.rest.api.Draft02;
38 import org.opendaylight.controller.sal.rest.api.RestconfService;
39 import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorTag;
40 import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorType;
41 import org.opendaylight.controller.sal.restconf.rpc.impl.BrokerRpcExecutor;
42 import org.opendaylight.controller.sal.restconf.rpc.impl.MountPointRpcExecutor;
43 import org.opendaylight.controller.sal.restconf.rpc.impl.RpcExecutor;
44 import org.opendaylight.controller.sal.streams.listeners.ListenerAdapter;
45 import org.opendaylight.controller.sal.streams.listeners.Notificator;
46 import org.opendaylight.controller.sal.streams.websockets.WebSocketServer;
47 import org.opendaylight.yangtools.concepts.Codec;
48 import org.opendaylight.yangtools.yang.common.QName;
49 import org.opendaylight.yangtools.yang.common.RpcError;
50 import org.opendaylight.yangtools.yang.common.RpcResult;
51 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
52 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
53 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.InstanceIdentifierBuilder;
54 import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode;
55 import org.opendaylight.yangtools.yang.data.api.Node;
56 import org.opendaylight.yangtools.yang.data.api.SimpleNode;
57 import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
58 import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
59 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
60 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
61 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
62 import org.opendaylight.yangtools.yang.model.api.FeatureDefinition;
63 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
64 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
65 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
66 import org.opendaylight.yangtools.yang.model.api.Module;
67 import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
68 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
69 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
70 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
71 import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
72 import org.opendaylight.yangtools.yang.model.util.EmptyType;
73 import org.opendaylight.yangtools.yang.parser.builder.impl.ContainerSchemaNodeBuilder;
74 import org.opendaylight.yangtools.yang.parser.builder.impl.LeafSchemaNodeBuilder;
76 public class RestconfImpl implements RestconfService {
77 private final static RestconfImpl INSTANCE = new RestconfImpl();
79 private static final int CHAR_NOT_FOUND = -1;
81 private final static String MOUNT_POINT_MODULE_NAME = "ietf-netconf";
83 private final static SimpleDateFormat REVISION_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
85 private final static String SAL_REMOTE_NAMESPACE = "urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote";
87 private final static String SAL_REMOTE_RPC_SUBSRCIBE = "create-data-change-event-subscription";
89 private BrokerFacade broker;
91 private ControllerContext controllerContext;
93 public void setBroker(final BrokerFacade broker) {
97 public void setControllerContext(final ControllerContext controllerContext) {
98 this.controllerContext = controllerContext;
101 private RestconfImpl() {
104 public static RestconfImpl getInstance() {
109 public StructuredData getModules() {
110 final Module restconfModule = this.getRestconfModule();
112 final List<Node<?>> modulesAsData = new ArrayList<Node<?>>();
113 final DataSchemaNode moduleSchemaNode = controllerContext.getRestconfModuleRestConfSchemaNode(
114 restconfModule, Draft02.RestConfModule.MODULE_LIST_SCHEMA_NODE);
116 Set<Module> allModules = this.controllerContext.getAllModules();
117 for (final Module module : allModules) {
118 CompositeNode moduleCompositeNode = this.toModuleCompositeNode(module, moduleSchemaNode);
119 modulesAsData.add(moduleCompositeNode);
122 final DataSchemaNode modulesSchemaNode = controllerContext.getRestconfModuleRestConfSchemaNode(
123 restconfModule, Draft02.RestConfModule.MODULES_CONTAINER_SCHEMA_NODE);
124 QName qName = modulesSchemaNode.getQName();
125 final CompositeNode modulesNode = NodeFactory.createImmutableCompositeNode(qName, null, modulesAsData);
126 return new StructuredData(modulesNode, modulesSchemaNode, null);
130 public StructuredData getAvailableStreams() {
131 Set<String> availableStreams = Notificator.getStreamNames();
133 final List<Node<?>> streamsAsData = new ArrayList<Node<?>>();
134 Module restconfModule = this.getRestconfModule();
135 final DataSchemaNode streamSchemaNode = controllerContext.getRestconfModuleRestConfSchemaNode(
136 restconfModule, Draft02.RestConfModule.STREAM_LIST_SCHEMA_NODE);
137 for (final String streamName : availableStreams) {
138 streamsAsData.add(this.toStreamCompositeNode(streamName, streamSchemaNode));
141 final DataSchemaNode streamsSchemaNode = controllerContext.getRestconfModuleRestConfSchemaNode(
142 restconfModule, Draft02.RestConfModule.STREAMS_CONTAINER_SCHEMA_NODE);
143 QName qName = streamsSchemaNode.getQName();
144 final CompositeNode streamsNode = NodeFactory.createImmutableCompositeNode(qName, null, streamsAsData);
145 return new StructuredData(streamsNode, streamsSchemaNode, null);
149 public StructuredData getModules(final String identifier) {
150 Set<Module> modules = null;
151 MountInstance mountPoint = null;
152 if (identifier.contains(ControllerContext.MOUNT)) {
153 InstanceIdWithSchemaNode mountPointIdentifier =
154 this.controllerContext.toMountPointIdentifier(identifier);
155 mountPoint = mountPointIdentifier.getMountPoint();
156 modules = this.controllerContext.getAllModules(mountPoint);
159 throw new RestconfDocumentedException(
160 "URI has bad format. If modules behind mount point should be showed, URI has to end with " +
161 ControllerContext.MOUNT, ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
164 final List<Node<?>> modulesAsData = new ArrayList<Node<?>>();
165 Module restconfModule = this.getRestconfModule();
166 final DataSchemaNode moduleSchemaNode = controllerContext.getRestconfModuleRestConfSchemaNode(
167 restconfModule, Draft02.RestConfModule.MODULE_LIST_SCHEMA_NODE);
169 for (final Module module : modules) {
170 modulesAsData.add(this.toModuleCompositeNode(module, moduleSchemaNode));
173 final DataSchemaNode modulesSchemaNode = controllerContext.getRestconfModuleRestConfSchemaNode(
174 restconfModule, Draft02.RestConfModule.MODULES_CONTAINER_SCHEMA_NODE);
175 QName qName = modulesSchemaNode.getQName();
176 final CompositeNode modulesNode = NodeFactory.createImmutableCompositeNode(qName, null, modulesAsData);
177 return new StructuredData(modulesNode, modulesSchemaNode, mountPoint);
181 public StructuredData getModule(final String identifier) {
182 final QName moduleNameAndRevision = this.getModuleNameAndRevision(identifier);
183 Module module = null;
184 MountInstance mountPoint = null;
185 if (identifier.contains(ControllerContext.MOUNT)) {
186 InstanceIdWithSchemaNode mountPointIdentifier =
187 this.controllerContext.toMountPointIdentifier(identifier);
188 mountPoint = mountPointIdentifier.getMountPoint();
189 module = this.controllerContext.findModuleByNameAndRevision(mountPoint, moduleNameAndRevision);
192 module = this.controllerContext.findModuleByNameAndRevision(moduleNameAndRevision);
195 if (module == null) {
196 throw new RestconfDocumentedException(
197 "Module with name '" + moduleNameAndRevision.getLocalName() + "' and revision '" +
198 moduleNameAndRevision.getRevision() + "' was not found.",
199 ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT );
202 Module restconfModule = this.getRestconfModule();
203 final DataSchemaNode moduleSchemaNode = controllerContext.getRestconfModuleRestConfSchemaNode(
204 restconfModule, Draft02.RestConfModule.MODULE_LIST_SCHEMA_NODE);
205 final CompositeNode moduleNode = this.toModuleCompositeNode(module, moduleSchemaNode);
206 return new StructuredData(moduleNode, moduleSchemaNode, mountPoint);
210 public StructuredData getOperations() {
211 Set<Module> allModules = this.controllerContext.getAllModules();
212 return this.operationsFromModulesToStructuredData(allModules, null);
216 public StructuredData getOperations(final String identifier) {
217 Set<Module> modules = null;
218 MountInstance mountPoint = null;
219 if (identifier.contains(ControllerContext.MOUNT)) {
220 InstanceIdWithSchemaNode mountPointIdentifier =
221 this.controllerContext.toMountPointIdentifier(identifier);
222 mountPoint = mountPointIdentifier.getMountPoint();
223 modules = this.controllerContext.getAllModules(mountPoint);
226 throw new RestconfDocumentedException(
227 "URI has bad format. If operations behind mount point should be showed, URI has to end with " +
228 ControllerContext.MOUNT, ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
231 return this.operationsFromModulesToStructuredData(modules, mountPoint);
234 private StructuredData operationsFromModulesToStructuredData(final Set<Module> modules,
235 final MountInstance mountPoint) {
236 final List<Node<?>> operationsAsData = new ArrayList<Node<?>>();
237 Module restconfModule = this.getRestconfModule();
238 final DataSchemaNode operationsSchemaNode = controllerContext.getRestconfModuleRestConfSchemaNode(
239 restconfModule, Draft02.RestConfModule.OPERATIONS_CONTAINER_SCHEMA_NODE);
240 QName qName = operationsSchemaNode.getQName();
241 SchemaPath path = operationsSchemaNode.getPath();
242 ContainerSchemaNodeBuilder containerSchemaNodeBuilder =
243 new ContainerSchemaNodeBuilder(Draft02.RestConfModule.NAME, 0, qName, path);
244 final ContainerSchemaNodeBuilder fakeOperationsSchemaNode = containerSchemaNodeBuilder;
245 for (final Module module : modules) {
246 Set<RpcDefinition> rpcs = module.getRpcs();
247 for (final RpcDefinition rpc : rpcs) {
248 QName rpcQName = rpc.getQName();
249 SimpleNode<Object> immutableSimpleNode =
250 NodeFactory.<Object>createImmutableSimpleNode(rpcQName, null, null);
251 operationsAsData.add(immutableSimpleNode);
253 String name = module.getName();
254 LeafSchemaNodeBuilder leafSchemaNodeBuilder = new LeafSchemaNodeBuilder(name, 0, rpcQName,
255 SchemaPath.create(true, QName.create("dummy")));
256 final LeafSchemaNodeBuilder fakeRpcSchemaNode = leafSchemaNodeBuilder;
257 fakeRpcSchemaNode.setAugmenting(true);
259 EmptyType instance = EmptyType.getInstance();
260 fakeRpcSchemaNode.setType(instance);
261 fakeOperationsSchemaNode.addChildNode(fakeRpcSchemaNode.build());
265 final CompositeNode operationsNode =
266 NodeFactory.createImmutableCompositeNode(qName, null, operationsAsData);
267 ContainerSchemaNode schemaNode = fakeOperationsSchemaNode.build();
268 return new StructuredData(operationsNode, schemaNode, mountPoint);
271 private Module getRestconfModule() {
272 Module restconfModule = controllerContext.getRestconfModule();
273 if (restconfModule == null) {
274 throw new RestconfDocumentedException(
275 "ietf-restconf module was not found.", ErrorType.APPLICATION,
276 ErrorTag.OPERATION_NOT_SUPPORTED );
279 return restconfModule;
282 private QName getModuleNameAndRevision(final String identifier) {
283 final int mountIndex = identifier.indexOf(ControllerContext.MOUNT);
284 String moduleNameAndRevision = "";
285 if (mountIndex >= 0) {
286 moduleNameAndRevision = identifier.substring(mountIndex + ControllerContext.MOUNT.length());
289 moduleNameAndRevision = identifier;
292 Splitter splitter = Splitter.on("/").omitEmptyStrings();
293 Iterable<String> split = splitter.split(moduleNameAndRevision);
294 final List<String> pathArgs = Lists.<String>newArrayList(split);
295 if (pathArgs.size() < 2) {
296 throw new RestconfDocumentedException(
297 "URI has bad format. End of URI should be in format \'moduleName/yyyy-MM-dd\'",
298 ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
302 final String moduleName = pathArgs.get( 0 );
303 String revision = pathArgs.get(1);
304 final Date moduleRevision = REVISION_FORMAT.parse(revision);
305 return QName.create(null, moduleRevision, moduleName);
307 catch (ParseException e) {
308 throw new RestconfDocumentedException(
309 "URI has bad format. It should be \'moduleName/yyyy-MM-dd\'",
310 ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
314 private CompositeNode toStreamCompositeNode(final String streamName, final DataSchemaNode streamSchemaNode) {
315 final List<Node<?>> streamNodeValues = new ArrayList<Node<?>>();
316 List<DataSchemaNode> instanceDataChildrenByName =
317 this.controllerContext.findInstanceDataChildrenByName(((DataNodeContainer) streamSchemaNode),
319 final DataSchemaNode nameSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null);
320 streamNodeValues.add(NodeFactory.<String>createImmutableSimpleNode(nameSchemaNode.getQName(), null,
323 instanceDataChildrenByName = this.controllerContext.findInstanceDataChildrenByName(
324 ((DataNodeContainer) streamSchemaNode), "description");
325 final DataSchemaNode descriptionSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null);
326 streamNodeValues.add(NodeFactory.<String>createImmutableSimpleNode(descriptionSchemaNode.getQName(), null,
327 "DESCRIPTION_PLACEHOLDER"));
329 instanceDataChildrenByName = this.controllerContext.findInstanceDataChildrenByName(
330 ((DataNodeContainer) streamSchemaNode), "replay-support");
331 final DataSchemaNode replaySupportSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null);
332 streamNodeValues.add(NodeFactory.<Boolean>createImmutableSimpleNode(replaySupportSchemaNode.getQName(), null,
333 Boolean.valueOf(true)));
335 instanceDataChildrenByName = this.controllerContext.findInstanceDataChildrenByName(
336 ((DataNodeContainer) streamSchemaNode), "replay-log-creation-time");
337 final DataSchemaNode replayLogCreationTimeSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null);
338 streamNodeValues.add(NodeFactory.<String>createImmutableSimpleNode(replayLogCreationTimeSchemaNode.getQName(),
341 instanceDataChildrenByName = this.controllerContext.findInstanceDataChildrenByName(
342 ((DataNodeContainer) streamSchemaNode), "events");
343 final DataSchemaNode eventsSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null);
344 streamNodeValues.add(NodeFactory.<String>createImmutableSimpleNode(eventsSchemaNode.getQName(),
347 return NodeFactory.createImmutableCompositeNode(streamSchemaNode.getQName(), null, streamNodeValues);
350 private CompositeNode toModuleCompositeNode(final Module module, final DataSchemaNode moduleSchemaNode) {
351 final List<Node<?>> moduleNodeValues = new ArrayList<Node<?>>();
352 List<DataSchemaNode> instanceDataChildrenByName =
353 this.controllerContext.findInstanceDataChildrenByName(((DataNodeContainer) moduleSchemaNode), "name");
354 final DataSchemaNode nameSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null);
355 moduleNodeValues.add(NodeFactory.<String>createImmutableSimpleNode(nameSchemaNode.getQName(),
356 null, module.getName()));
358 instanceDataChildrenByName = this.controllerContext.findInstanceDataChildrenByName(
359 ((DataNodeContainer) moduleSchemaNode), "revision");
360 final DataSchemaNode revisionSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null);
361 Date _revision = module.getRevision();
362 moduleNodeValues.add(NodeFactory.<String>createImmutableSimpleNode(revisionSchemaNode.getQName(), null,
363 REVISION_FORMAT.format(_revision)));
365 instanceDataChildrenByName = this.controllerContext.findInstanceDataChildrenByName(
366 ((DataNodeContainer) moduleSchemaNode), "namespace");
367 final DataSchemaNode namespaceSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null);
368 moduleNodeValues.add(NodeFactory.<String>createImmutableSimpleNode(namespaceSchemaNode.getQName(), null,
369 module.getNamespace().toString()));
371 instanceDataChildrenByName = this.controllerContext.findInstanceDataChildrenByName(
372 ((DataNodeContainer) moduleSchemaNode), "feature");
373 final DataSchemaNode featureSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null);
374 for (final FeatureDefinition feature : module.getFeatures()) {
375 moduleNodeValues.add(NodeFactory.<String>createImmutableSimpleNode(featureSchemaNode.getQName(), null,
376 feature.getQName().getLocalName()));
379 return NodeFactory.createImmutableCompositeNode(moduleSchemaNode.getQName(), null, moduleNodeValues);
383 public Object getRoot() {
388 public StructuredData invokeRpc(final String identifier, final CompositeNode payload) {
389 final RpcExecutor rpc = this.resolveIdentifierInInvokeRpc(identifier);
390 QName rpcName = rpc.getRpcDefinition().getQName();
391 URI rpcNamespace = rpcName.getNamespace();
392 if (Objects.equal(rpcNamespace.toString(), SAL_REMOTE_NAMESPACE) &&
393 Objects.equal(rpcName.getLocalName(), SAL_REMOTE_RPC_SUBSRCIBE)) {
394 return invokeSalRemoteRpcSubscribeRPC(payload, rpc.getRpcDefinition());
397 validateInput( rpc.getRpcDefinition().getInput(), payload );
399 return callRpc(rpc, payload);
402 private void validateInput(DataSchemaNode inputSchema, CompositeNode payload) {
403 if( inputSchema != null && payload == null )
405 //expected a non null payload
406 throw new RestconfDocumentedException( "Input is required.",
408 ErrorTag.MALFORMED_MESSAGE );
410 else if( inputSchema == null && payload != null )
412 //did not expect any input
413 throw new RestconfDocumentedException( "No input expected.",
415 ErrorTag.MALFORMED_MESSAGE );
419 //TODO: Validate "mandatory" and "config" values here??? Or should those be
420 // validate in a more central location inside MD-SAL core.
424 private StructuredData invokeSalRemoteRpcSubscribeRPC(final CompositeNode payload,
425 final RpcDefinition rpc) {
426 final CompositeNode value = this.normalizeNode(payload, rpc.getInput(), null);
427 final SimpleNode<? extends Object> pathNode = value == null ? null :
428 value.getFirstSimpleByName( QName.create(rpc.getQName(), "path") );
429 final Object pathValue = pathNode == null ? null : pathNode.getValue();
431 if (!(pathValue instanceof InstanceIdentifier)) {
432 throw new RestconfDocumentedException(
433 "Instance identifier was not normalized correctly.",
434 ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED );
437 final InstanceIdentifier pathIdentifier = ((InstanceIdentifier) pathValue);
438 String streamName = null;
439 if (!Iterables.isEmpty(pathIdentifier.getPath())) {
440 String fullRestconfIdentifier = this.controllerContext.toFullRestconfIdentifier(pathIdentifier);
441 streamName = Notificator.createStreamNameFromUri(fullRestconfIdentifier);
444 if (Strings.isNullOrEmpty(streamName)) {
445 throw new RestconfDocumentedException(
446 "Path is empty or contains data node which is not Container or List build-in type.",
447 ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
450 final SimpleNode<String> streamNameNode = NodeFactory.<String>createImmutableSimpleNode(
451 QName.create(rpc.getOutput().getQName(), "stream-name"), null, streamName);
452 final List<Node<?>> output = new ArrayList<Node<?>>();
453 output.add(streamNameNode);
455 final MutableCompositeNode responseData = NodeFactory.createMutableCompositeNode(
456 rpc.getOutput().getQName(), null, output, null, null);
458 if (!Notificator.existListenerFor(pathIdentifier)) {
459 Notificator.createListener(pathIdentifier, streamName);
462 return new StructuredData(responseData, rpc.getOutput(), null);
466 public StructuredData invokeRpc(final String identifier, final String noPayload) {
467 if (StringUtils.isNotBlank(noPayload)) {
468 throw new RestconfDocumentedException(
469 "Content must be empty.", ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
471 return invokeRpc( identifier, (CompositeNode)null );
474 private RpcExecutor resolveIdentifierInInvokeRpc(final String identifier) {
475 String identifierEncoded = null;
476 MountInstance mountPoint = null;
477 if (identifier.contains(ControllerContext.MOUNT)) {
478 // mounted RPC call - look up mount instance.
479 InstanceIdWithSchemaNode mountPointId = controllerContext
480 .toMountPointIdentifier(identifier);
481 mountPoint = mountPointId.getMountPoint();
483 int startOfRemoteRpcName = identifier.lastIndexOf(ControllerContext.MOUNT)
484 + ControllerContext.MOUNT.length() + 1;
485 String remoteRpcName = identifier.substring(startOfRemoteRpcName);
486 identifierEncoded = remoteRpcName;
488 } else if (identifier.indexOf("/") != CHAR_NOT_FOUND) {
489 final String slashErrorMsg = String
490 .format("Identifier %n%s%ncan\'t contain slash "
491 + "character (/).%nIf slash is part of identifier name then use %%2F placeholder.",
493 throw new RestconfDocumentedException(
494 slashErrorMsg, ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
496 identifierEncoded = identifier;
499 final String identifierDecoded = controllerContext.urlPathArgDecode(identifierEncoded);
500 RpcDefinition rpc = controllerContext.getRpcDefinition(identifierDecoded);
503 throw new RestconfDocumentedException(
504 "RPC does not exist.", ErrorType.RPC, ErrorTag.UNKNOWN_ELEMENT );
507 if (mountPoint == null) {
508 return new BrokerRpcExecutor(rpc, broker);
510 return new MountPointRpcExecutor(rpc, mountPoint);
515 private StructuredData callRpc(final RpcExecutor rpcExecutor, final CompositeNode payload) {
516 if (rpcExecutor == null) {
517 throw new RestconfDocumentedException(
518 "RPC does not exist.", ErrorType.RPC, ErrorTag.UNKNOWN_ELEMENT );
521 CompositeNode rpcRequest = null;
522 RpcDefinition rpc = rpcExecutor.getRpcDefinition();
523 QName rpcName = rpc.getQName();
525 if (payload == null) {
526 rpcRequest = NodeFactory.createMutableCompositeNode(rpcName, null, null, null, null);
528 final CompositeNode value = this.normalizeNode(payload, rpc.getInput(), null);
529 List<Node<?>> input = Collections.<Node<?>> singletonList(value);
530 rpcRequest = NodeFactory.createMutableCompositeNode(rpcName, null, input, null, null);
533 RpcResult<CompositeNode> rpcResult = rpcExecutor.invokeRpc(rpcRequest);
535 checkRpcSuccessAndThrowException(rpcResult);
537 if (rpcResult.getResult() == null) {
541 if( rpc.getOutput() == null )
543 return null; //no output, nothing to send back.
546 return new StructuredData(rpcResult.getResult(), rpc.getOutput(), null);
549 private void checkRpcSuccessAndThrowException(RpcResult<CompositeNode> rpcResult) {
550 if (rpcResult.isSuccessful() == false) {
552 Collection<RpcError> rpcErrors = rpcResult.getErrors();
553 if( rpcErrors == null || rpcErrors.isEmpty() ) {
554 throw new RestconfDocumentedException(
555 "The operation was not successful and there were no RPC errors returned",
556 ErrorType.RPC, ErrorTag.OPERATION_FAILED );
559 List<RestconfError> errorList = Lists.newArrayList();
560 for( RpcError rpcError: rpcErrors ) {
561 errorList.add( new RestconfError( rpcError ) );
564 throw new RestconfDocumentedException( errorList );
569 public StructuredData readConfigurationData(final String identifier, UriInfo info) {
570 final InstanceIdWithSchemaNode iiWithData = this.controllerContext.toInstanceIdentifier(identifier);
571 CompositeNode data = null;
572 MountInstance mountPoint = iiWithData.getMountPoint();
573 if (mountPoint != null) {
574 data = broker.readConfigurationDataBehindMountPoint(mountPoint, iiWithData.getInstanceIdentifier());
577 data = broker.readConfigurationData(iiWithData.getInstanceIdentifier());
580 data = pruneDataAtDepth( data, parseDepthParameter( info ) );
581 return new StructuredData(data, iiWithData.getSchemaNode(), iiWithData.getMountPoint());
584 @SuppressWarnings("unchecked")
585 private <T extends Node<?>> T pruneDataAtDepth( T node, Integer depth ) {
586 if( depth == null ) {
590 if( node instanceof CompositeNode ) {
591 ImmutableList.Builder<Node<?>> newChildNodes = ImmutableList.<Node<?>> builder();
593 for( Node<?> childNode: ((CompositeNode)node).getValue() ) {
594 newChildNodes.add( pruneDataAtDepth( childNode, depth - 1 ) );
598 return (T) ImmutableCompositeNode.create( node.getNodeType(), newChildNodes.build() );
605 private Integer parseDepthParameter( UriInfo info ) {
606 String param = info.getQueryParameters( false ).getFirst( "depth" );
607 if( Strings.isNullOrEmpty( param ) || "unbounded".equals( param ) ) {
612 Integer depth = Integer.valueOf( param );
614 throw new RestconfDocumentedException( new RestconfError(
615 ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE, "Invalid depth parameter: " + depth,
616 null, "The depth parameter must be an integer > 1 or \"unbounded\"" ) );
621 catch( NumberFormatException e ) {
622 throw new RestconfDocumentedException( new RestconfError(
623 ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE,
624 "Invalid depth parameter: " + e.getMessage(),
625 null, "The depth parameter must be an integer > 1 or \"unbounded\"" ) );
630 public StructuredData readOperationalData(final String identifier, UriInfo info) {
631 final InstanceIdWithSchemaNode iiWithData = this.controllerContext.toInstanceIdentifier(identifier);
632 CompositeNode data = null;
633 MountInstance mountPoint = iiWithData.getMountPoint();
634 if (mountPoint != null) {
635 data = broker.readOperationalDataBehindMountPoint(mountPoint, iiWithData.getInstanceIdentifier());
638 data = broker.readOperationalData(iiWithData.getInstanceIdentifier());
641 data = pruneDataAtDepth( data, parseDepthParameter( info ) );
642 return new StructuredData(data, iiWithData.getSchemaNode(), mountPoint);
646 public Response updateConfigurationData(final String identifier, final CompositeNode payload) {
647 final InstanceIdWithSchemaNode iiWithData = this.controllerContext.toInstanceIdentifier(identifier);
649 validateInput(iiWithData.getSchemaNode(), payload);
651 MountInstance mountPoint = iiWithData.getMountPoint();
652 final CompositeNode value = this.normalizeNode(payload, iiWithData.getSchemaNode(), mountPoint);
653 RpcResult<TransactionStatus> status = null;
656 if (mountPoint != null) {
657 status = broker.commitConfigurationDataPutBehindMountPoint(
658 mountPoint, iiWithData.getInstanceIdentifier(), value).get();
660 status = broker.commitConfigurationDataPut(iiWithData.getInstanceIdentifier(), value).get();
663 catch( Exception e ) {
664 throw new RestconfDocumentedException( "Error updating data", e );
667 if( status.getResult() == TransactionStatus.COMMITED )
668 return Response.status(Status.OK).build();
670 return Response.status(Status.INTERNAL_SERVER_ERROR).build();
674 public Response createConfigurationData(final String identifier, final CompositeNode payload) {
675 if( payload == null ) {
676 throw new RestconfDocumentedException( "Input is required.",
678 ErrorTag.MALFORMED_MESSAGE );
681 URI payloadNS = this.namespace(payload);
682 if (payloadNS == null) {
683 throw new RestconfDocumentedException(
684 "Data has bad format. Root element node must have namespace (XML format) or module name(JSON format)",
685 ErrorType.PROTOCOL, ErrorTag.UNKNOWN_NAMESPACE );
688 InstanceIdWithSchemaNode iiWithData = null;
689 CompositeNode value = null;
690 if (this.representsMountPointRootData(payload)) {
691 // payload represents mount point data and URI represents path to the mount point
693 if (this.endsWithMountPoint(identifier)) {
694 throw new RestconfDocumentedException(
695 "URI has bad format. URI should be without \"" + ControllerContext.MOUNT +
696 "\" for POST operation.",
697 ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
700 final String completeIdentifier = this.addMountPointIdentifier(identifier);
701 iiWithData = this.controllerContext.toInstanceIdentifier(completeIdentifier);
703 value = this.normalizeNode(payload, iiWithData.getSchemaNode(), iiWithData.getMountPoint());
706 final InstanceIdWithSchemaNode incompleteInstIdWithData =
707 this.controllerContext.toInstanceIdentifier(identifier);
708 final DataNodeContainer parentSchema = (DataNodeContainer) incompleteInstIdWithData.getSchemaNode();
709 MountInstance mountPoint = incompleteInstIdWithData.getMountPoint();
710 final Module module = this.findModule(mountPoint, payload);
711 if (module == null) {
712 throw new RestconfDocumentedException(
713 "Module was not found for \"" + payloadNS + "\"",
714 ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT );
717 String payloadName = this.getName(payload);
718 final DataSchemaNode schemaNode = this.controllerContext.findInstanceDataChildByNameAndNamespace(
719 parentSchema, payloadName, module.getNamespace());
720 value = this.normalizeNode(payload, schemaNode, mountPoint);
722 iiWithData = this.addLastIdentifierFromData(incompleteInstIdWithData, value, schemaNode);
725 RpcResult<TransactionStatus> status = null;
726 MountInstance mountPoint = iiWithData.getMountPoint();
728 if (mountPoint != null) {
729 Future<RpcResult<TransactionStatus>> future =
730 broker.commitConfigurationDataPostBehindMountPoint(
731 mountPoint, iiWithData.getInstanceIdentifier(), value);
732 status = future == null ? null : future.get();
735 Future<RpcResult<TransactionStatus>> future =
736 broker.commitConfigurationDataPost(iiWithData.getInstanceIdentifier(), value);
737 status = future == null ? null : future.get();
740 catch( Exception e ) {
741 throw new RestconfDocumentedException( "Error creating data", e );
744 if (status == null) {
745 return Response.status(Status.ACCEPTED).build();
748 if( status.getResult() == TransactionStatus.COMMITED )
749 return Response.status(Status.NO_CONTENT).build();
751 return Response.status(Status.INTERNAL_SERVER_ERROR).build();
755 public Response createConfigurationData(final CompositeNode payload) {
756 if( payload == null ) {
757 throw new RestconfDocumentedException( "Input is required.",
759 ErrorTag.MALFORMED_MESSAGE );
762 URI payloadNS = this.namespace(payload);
763 if (payloadNS == null) {
764 throw new RestconfDocumentedException(
765 "Data has bad format. Root element node must have namespace (XML format) or module name(JSON format)",
766 ErrorType.PROTOCOL, ErrorTag.UNKNOWN_NAMESPACE );
769 final Module module = this.findModule(null, payload);
770 if (module == null) {
771 throw new RestconfDocumentedException(
772 "Data has bad format. Root element node has incorrect namespace (XML format) or module name(JSON format)",
773 ErrorType.PROTOCOL, ErrorTag.UNKNOWN_NAMESPACE );
776 String payloadName = this.getName(payload);
777 final DataSchemaNode schemaNode = this.controllerContext.findInstanceDataChildByNameAndNamespace(
778 module, payloadName, module.getNamespace());
779 final CompositeNode value = this.normalizeNode(payload, schemaNode, null);
780 final InstanceIdWithSchemaNode iiWithData = this.addLastIdentifierFromData(null, value, schemaNode);
781 RpcResult<TransactionStatus> status = null;
782 MountInstance mountPoint = iiWithData.getMountPoint();
785 if (mountPoint != null) {
786 Future<RpcResult<TransactionStatus>> future =
787 broker.commitConfigurationDataPostBehindMountPoint(
788 mountPoint, iiWithData.getInstanceIdentifier(), value);
789 status = future == null ? null : future.get();
792 Future<RpcResult<TransactionStatus>> future =
793 broker.commitConfigurationDataPost(iiWithData.getInstanceIdentifier(), value);
794 status = future == null ? null : future.get();
797 catch( Exception e ) {
798 throw new RestconfDocumentedException( "Error creating data", e );
801 if (status == null) {
802 return Response.status(Status.ACCEPTED).build();
805 if( status.getResult() == TransactionStatus.COMMITED )
806 return Response.status(Status.NO_CONTENT).build();
808 return Response.status(Status.INTERNAL_SERVER_ERROR).build();
812 public Response deleteConfigurationData(final String identifier) {
813 final InstanceIdWithSchemaNode iiWithData = this.controllerContext.toInstanceIdentifier(identifier);
814 RpcResult<TransactionStatus> status = null;
815 MountInstance mountPoint = iiWithData.getMountPoint();
818 if (mountPoint != null) {
819 status = broker.commitConfigurationDataDeleteBehindMountPoint(
820 mountPoint, iiWithData.getInstanceIdentifier()).get();
823 status = broker.commitConfigurationDataDelete(iiWithData.getInstanceIdentifier()).get();
826 catch( Exception e ) {
827 throw new RestconfDocumentedException( "Error creating data", e );
830 if( status.getResult() == TransactionStatus.COMMITED )
831 return Response.status(Status.OK).build();
833 return Response.status(Status.INTERNAL_SERVER_ERROR).build();
837 public Response subscribeToStream(final String identifier, final UriInfo uriInfo) {
838 final String streamName = Notificator.createStreamNameFromUri(identifier);
839 if (Strings.isNullOrEmpty(streamName)) {
840 throw new RestconfDocumentedException(
841 "Stream name is empty.", ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
844 final ListenerAdapter listener = Notificator.getListenerFor(streamName);
845 if (listener == null) {
846 throw new RestconfDocumentedException(
847 "Stream was not found.", ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT );
850 broker.registerToListenDataChanges(listener);
852 final UriBuilder uriBuilder = uriInfo.getAbsolutePathBuilder();
853 UriBuilder port = uriBuilder.port(WebSocketServer.PORT);
854 final URI uriToWebsocketServer = port.replacePath(streamName).build();
856 return Response.status(Status.OK).location(uriToWebsocketServer).build();
859 private Module findModule(final MountInstance mountPoint, final CompositeNode data) {
860 if (data instanceof CompositeNodeWrapper) {
861 return findModule(mountPoint, (CompositeNodeWrapper)data);
863 else if (data != null) {
864 URI namespace = data.getNodeType().getNamespace();
865 if (mountPoint != null) {
866 return this.controllerContext.findModuleByNamespace(mountPoint, namespace);
869 return this.controllerContext.findModuleByNamespace(namespace);
873 throw new IllegalArgumentException("Unhandled parameter types: " +
874 Arrays.<Object>asList(mountPoint, data).toString());
878 private Module findModule(final MountInstance mountPoint, final CompositeNodeWrapper data) {
879 URI namespace = data.getNamespace();
880 Preconditions.<URI>checkNotNull(namespace);
882 Module module = null;
883 if (mountPoint != null) {
884 module = this.controllerContext.findModuleByNamespace(mountPoint, namespace);
885 if (module == null) {
886 module = this.controllerContext.findModuleByName(mountPoint, namespace.toString());
890 module = this.controllerContext.findModuleByNamespace(namespace);
891 if (module == null) {
892 module = this.controllerContext.findModuleByName(namespace.toString());
899 private InstanceIdWithSchemaNode addLastIdentifierFromData(
900 final InstanceIdWithSchemaNode identifierWithSchemaNode,
901 final CompositeNode data, final DataSchemaNode schemaOfData) {
902 InstanceIdentifier instanceIdentifier = null;
903 if (identifierWithSchemaNode != null) {
904 instanceIdentifier = identifierWithSchemaNode.getInstanceIdentifier();
907 final InstanceIdentifier iiOriginal = instanceIdentifier;
908 InstanceIdentifierBuilder iiBuilder = null;
909 if (iiOriginal == null) {
910 iiBuilder = InstanceIdentifier.builder();
913 iiBuilder = InstanceIdentifier.builder(iiOriginal);
916 if ((schemaOfData instanceof ListSchemaNode)) {
917 HashMap<QName,Object> keys = this.resolveKeysFromData(((ListSchemaNode) schemaOfData), data);
918 iiBuilder.nodeWithKey(schemaOfData.getQName(), keys);
921 iiBuilder.node(schemaOfData.getQName());
924 InstanceIdentifier instance = iiBuilder.toInstance();
925 MountInstance mountPoint = null;
926 if (identifierWithSchemaNode != null) {
927 mountPoint=identifierWithSchemaNode.getMountPoint();
930 return new InstanceIdWithSchemaNode(instance, schemaOfData, mountPoint);
933 private HashMap<QName,Object> resolveKeysFromData(final ListSchemaNode listNode,
934 final CompositeNode dataNode) {
935 final HashMap<QName,Object> keyValues = new HashMap<QName, Object>();
936 List<QName> _keyDefinition = listNode.getKeyDefinition();
937 for (final QName key : _keyDefinition) {
938 SimpleNode<? extends Object> head = null;
939 String localName = key.getLocalName();
940 List<SimpleNode<? extends Object>> simpleNodesByName = dataNode.getSimpleNodesByName(localName);
941 if (simpleNodesByName != null) {
942 head = Iterables.getFirst(simpleNodesByName, null);
945 Object dataNodeKeyValueObject = null;
947 dataNodeKeyValueObject = head.getValue();
950 if (dataNodeKeyValueObject == null) {
951 throw new RestconfDocumentedException(
952 "Data contains list \"" + dataNode.getNodeType().getLocalName() +
953 "\" which does not contain key: \"" + key.getLocalName() + "\"",
954 ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
957 keyValues.put(key, dataNodeKeyValueObject);
963 private boolean endsWithMountPoint(final String identifier) {
964 return identifier.endsWith(ControllerContext.MOUNT) ||
965 identifier.endsWith(ControllerContext.MOUNT + "/");
968 private boolean representsMountPointRootData(final CompositeNode data) {
969 URI namespace = this.namespace(data);
970 return (SchemaContext.NAME.getNamespace().equals( namespace ) /* ||
971 MOUNT_POINT_MODULE_NAME.equals( namespace.toString() )*/ ) &&
972 SchemaContext.NAME.getLocalName().equals( this.localName(data) );
975 private String addMountPointIdentifier(final String identifier) {
976 boolean endsWith = identifier.endsWith("/");
978 return (identifier + ControllerContext.MOUNT);
981 return identifier + "/" + ControllerContext.MOUNT;
984 private CompositeNode normalizeNode(final CompositeNode node, final DataSchemaNode schema,
985 final MountInstance mountPoint) {
986 if (schema == null) {
987 QName nodeType = node == null ? null : node.getNodeType();
988 String localName = nodeType == null ? null : nodeType.getLocalName();
990 throw new RestconfDocumentedException(
991 "Data schema node was not found for " + localName,
992 ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
995 if (!(schema instanceof DataNodeContainer)) {
996 throw new RestconfDocumentedException(
997 "Root element has to be container or list yang datatype.",
998 ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
1001 if ((node instanceof CompositeNodeWrapper)) {
1002 boolean isChangeAllowed = ((CompositeNodeWrapper) node).isChangeAllowed();
1003 if (isChangeAllowed) {
1005 this.normalizeNode(((CompositeNodeWrapper) node), schema, null, mountPoint);
1007 catch (IllegalArgumentException e) {
1008 throw new RestconfDocumentedException(
1009 e.getMessage(), ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
1013 return ((CompositeNodeWrapper) node).unwrap();
1019 private void normalizeNode(final NodeWrapper<? extends Object> nodeBuilder,
1020 final DataSchemaNode schema, final QName previousAugment,
1021 final MountInstance mountPoint) {
1022 if (schema == null) {
1023 throw new RestconfDocumentedException(
1024 "Data has bad format.\n\"" + nodeBuilder.getLocalName() +
1025 "\" does not exist in yang schema.",
1026 ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
1029 QName currentAugment = null;
1030 if (nodeBuilder.getQname() != null) {
1031 currentAugment = previousAugment;
1034 currentAugment = this.normalizeNodeName(nodeBuilder, schema, previousAugment, mountPoint);
1035 if (nodeBuilder.getQname() == null) {
1036 throw new RestconfDocumentedException(
1037 "Data has bad format.\nIf data is in XML format then namespace for \"" +
1038 nodeBuilder.getLocalName() +
1039 "\" should be \"" + schema.getQName().getNamespace() + "\".\n" +
1040 "If data is in JSON format then module name for \"" + nodeBuilder.getLocalName() +
1041 "\" should be corresponding to namespace \"" +
1042 schema.getQName().getNamespace() + "\".",
1043 ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
1047 if ((nodeBuilder instanceof CompositeNodeWrapper)) {
1048 final List<NodeWrapper<?>> children = ((CompositeNodeWrapper) nodeBuilder).getValues();
1049 for (final NodeWrapper<? extends Object> child : children) {
1050 final List<DataSchemaNode> potentialSchemaNodes =
1051 this.controllerContext.findInstanceDataChildrenByName(
1052 ((DataNodeContainer) schema), child.getLocalName());
1054 if (potentialSchemaNodes.size() > 1 && child.getNamespace() == null) {
1055 StringBuilder builder = new StringBuilder();
1056 for (final DataSchemaNode potentialSchemaNode : potentialSchemaNodes) {
1057 builder.append(" ").append(potentialSchemaNode.getQName().getNamespace().toString())
1061 throw new RestconfDocumentedException(
1062 "Node \"" + child.getLocalName() +
1063 "\" is added as augment from more than one module. " +
1064 "Therefore node must have namespace (XML format) or module name (JSON format)." +
1065 "\nThe node is added as augment from modules with namespaces:\n" + builder,
1066 ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
1069 boolean rightNodeSchemaFound = false;
1070 for (final DataSchemaNode potentialSchemaNode : potentialSchemaNodes) {
1071 if (!rightNodeSchemaFound) {
1072 final QName potentialCurrentAugment =
1073 this.normalizeNodeName(child, potentialSchemaNode, currentAugment, mountPoint);
1074 if (child.getQname() != null ) {
1075 this.normalizeNode(child, potentialSchemaNode, potentialCurrentAugment, mountPoint);
1076 rightNodeSchemaFound = true;
1081 if (!rightNodeSchemaFound) {
1082 throw new RestconfDocumentedException(
1083 "Schema node \"" + child.getLocalName() + "\" was not found in module.",
1084 ErrorType.APPLICATION, ErrorTag.UNKNOWN_ELEMENT );
1088 if ((schema instanceof ListSchemaNode)) {
1089 final List<QName> listKeys = ((ListSchemaNode) schema).getKeyDefinition();
1090 for (final QName listKey : listKeys) {
1091 boolean foundKey = false;
1092 for (final NodeWrapper<? extends Object> child : children) {
1093 if (Objects.equal(child.unwrap().getNodeType().getLocalName(), listKey.getLocalName())) {
1099 throw new RestconfDocumentedException(
1100 "Missing key in URI \"" + listKey.getLocalName() +
1101 "\" of list \"" + schema.getQName().getLocalName() + "\"",
1102 ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
1108 if ((nodeBuilder instanceof SimpleNodeWrapper)) {
1109 final SimpleNodeWrapper simpleNode = ((SimpleNodeWrapper) nodeBuilder);
1110 final Object value = simpleNode.getValue();
1111 Object inputValue = value;
1112 TypeDefinition<? extends Object> typeDefinition = this.typeDefinition(schema);
1113 if ((typeDefinition instanceof IdentityrefTypeDefinition)) {
1114 if ((value instanceof String)) {
1115 inputValue = new IdentityValuesDTO( nodeBuilder.getNamespace().toString(),
1116 (String) value, null, (String) value );
1117 } // else value is already instance of IdentityValuesDTO
1120 Codec<Object,Object> codec = RestCodec.from(typeDefinition, mountPoint);
1121 Object outputValue = codec == null ? null : codec.deserialize(inputValue);
1123 simpleNode.setValue(outputValue);
1126 if ((nodeBuilder instanceof EmptyNodeWrapper)) {
1127 final EmptyNodeWrapper emptyNodeBuilder = ((EmptyNodeWrapper) nodeBuilder);
1128 if ((schema instanceof LeafSchemaNode)) {
1129 emptyNodeBuilder.setComposite(false);
1132 if ((schema instanceof ContainerSchemaNode)) {
1133 // FIXME: Add presence check
1134 emptyNodeBuilder.setComposite(true);
1142 private QName normalizeNodeName(final NodeWrapper<? extends Object> nodeBuilder,
1143 final DataSchemaNode schema, final QName previousAugment,
1144 final MountInstance mountPoint) {
1145 QName validQName = schema.getQName();
1146 QName currentAugment = previousAugment;
1147 if (schema.isAugmenting()) {
1148 currentAugment = schema.getQName();
1150 else if (previousAugment != null &&
1151 !Objects.equal( schema.getQName().getNamespace(), previousAugment.getNamespace())) {
1152 validQName = QName.create(currentAugment, schema.getQName().getLocalName());
1155 String moduleName = null;
1156 if (mountPoint == null) {
1157 moduleName = controllerContext.findModuleNameByNamespace(validQName.getNamespace());
1160 moduleName = controllerContext.findModuleNameByNamespace(mountPoint, validQName.getNamespace());
1163 if (nodeBuilder.getNamespace() == null ||
1164 Objects.equal(nodeBuilder.getNamespace(), validQName.getNamespace()) ||
1165 Objects.equal(nodeBuilder.getNamespace().toString(), moduleName) /*||
1166 Note: this check is wrong - can never be true as it compares a URI with a String
1167 not sure what the intention is so commented out...
1168 Objects.equal(nodeBuilder.getNamespace(), MOUNT_POINT_MODULE_NAME)*/ ) {
1170 nodeBuilder.setQname(validQName);
1173 return currentAugment;
1176 private URI namespace(final CompositeNode data) {
1177 if (data instanceof CompositeNodeWrapper) {
1178 return ((CompositeNodeWrapper)data).getNamespace();
1180 else if (data != null) {
1181 return data.getNodeType().getNamespace();
1184 throw new IllegalArgumentException("Unhandled parameter types: " +
1185 Arrays.<Object>asList(data).toString());
1189 private String localName(final CompositeNode data) {
1190 if (data instanceof CompositeNodeWrapper) {
1191 return ((CompositeNodeWrapper)data).getLocalName();
1193 else if (data != null) {
1194 return data.getNodeType().getLocalName();
1197 throw new IllegalArgumentException("Unhandled parameter types: " +
1198 Arrays.<Object>asList(data).toString());
1202 private String getName(final CompositeNode data) {
1203 if (data instanceof CompositeNodeWrapper) {
1204 return ((CompositeNodeWrapper)data).getLocalName();
1206 else if (data != null) {
1207 return data.getNodeType().getLocalName();
1210 throw new IllegalArgumentException("Unhandled parameter types: " +
1211 Arrays.<Object>asList(data).toString());
1215 private TypeDefinition<? extends Object> _typeDefinition(final LeafSchemaNode node) {
1216 TypeDefinition<?> baseType = node.getType();
1217 while (baseType.getBaseType() != null) {
1218 baseType = baseType.getBaseType();
1224 private TypeDefinition<? extends Object> typeDefinition(final LeafListSchemaNode node) {
1225 TypeDefinition<?> baseType = node.getType();
1226 while (baseType.getBaseType() != null) {
1227 baseType = baseType.getBaseType();
1233 private TypeDefinition<? extends Object> typeDefinition(final DataSchemaNode node) {
1234 if (node instanceof LeafListSchemaNode) {
1235 return typeDefinition((LeafListSchemaNode)node);
1237 else if (node instanceof LeafSchemaNode) {
1238 return _typeDefinition((LeafSchemaNode)node);
1241 throw new IllegalArgumentException("Unhandled parameter types: " +
1242 Arrays.<Object>asList(node).toString());