X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-rest-connector%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fsal%2Frestconf%2Fimpl%2FRestconfImpl.java;h=5f5b9bafe10239dc9eb3df60e6435b916b54bd8a;hp=20e27c8a143e41e3630fc3943278405d7c8becc9;hb=06e889c9c78457590b6a0b62d89a6b9f44242a9f;hpb=ddaf5bf1e47671e5e9ddf65e9456b7c582fb381e diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.java index 20e27c8a14..5f5b9bafe1 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.java @@ -19,6 +19,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.util.concurrent.CheckedFuture; +import com.google.common.util.concurrent.Futures; import java.math.BigInteger; import java.net.URI; import java.net.URISyntaxException; @@ -50,6 +51,7 @@ import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint; import org.opendaylight.controller.md.sal.dom.api.DOMRpcException; import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult; import org.opendaylight.controller.md.sal.dom.api.DOMRpcService; +import org.opendaylight.controller.md.sal.dom.spi.DefaultDOMRpcResult; import org.opendaylight.controller.sal.rest.api.Draft02; import org.opendaylight.controller.sal.rest.api.RestconfService; import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorTag; @@ -65,7 +67,6 @@ import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.QNameModule; import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.data.api.CompositeNode; -import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode; import org.opendaylight.yangtools.yang.data.api.Node; import org.opendaylight.yangtools.yang.data.api.SimpleNode; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; @@ -74,6 +75,7 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdent import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; +import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild; import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode; import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode; import org.opendaylight.yangtools.yang.data.api.schema.MapNode; @@ -83,9 +85,11 @@ import org.opendaylight.yangtools.yang.data.composite.node.schema.cnsn.parser.Cn import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode; import org.opendaylight.yangtools.yang.data.impl.NodeFactory; import org.opendaylight.yangtools.yang.data.impl.schema.Builders; +import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes; import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder; import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder; import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.ListNodeBuilder; +import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder; import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode; import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; @@ -469,7 +473,7 @@ public class RestconfImpl implements RestconfService { instanceDataChildrenByName = ControllerContext.findInstanceDataChildrenByName( ((DataNodeContainer) streamSchemaNode), "events"); final DataSchemaNode eventsSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null); - streamNodeValues.add(NodeFactory. createImmutableSimpleNode(eventsSchemaNode.getQName(), null, "")); + streamNodeValues.add(NodeFactory.createImmutableSimpleNode(eventsSchemaNode.getQName(), null, "")); return NodeFactory.createImmutableCompositeNode(streamSchemaNode.getQName(), null, streamNodeValues); } @@ -523,6 +527,7 @@ public class RestconfImpl implements RestconfService { @Override public NormalizedNodeContext invokeRpc(final String identifier, final NormalizedNodeContext payload, final UriInfo uriInfo) { final SchemaPath type = payload.getInstanceIdentifierContext().getSchemaNode().getPath(); + final URI namespace = payload.getInstanceIdentifierContext().getSchemaNode().getQName().getNamespace(); final CheckedFuture response; final DOMMountPoint mountPoint = payload.getInstanceIdentifierContext().getMountPoint(); final SchemaContext schemaContext; @@ -534,22 +539,24 @@ public class RestconfImpl implements RestconfService { schemaContext = mountPoint.getSchemaContext(); response = mountRpcServices.get().invokeRpc(type, payload.getData()); } else { - response = broker.invokeRpc(type, payload.getData()); + if (namespace.toString().equals(SAL_REMOTE_NAMESPACE)) { + response = invokeSalRemoteRpcSubscribeRPC(payload); + } else { + response = broker.invokeRpc(type, payload.getData()); + } schemaContext = controllerContext.getGlobalSchema(); } final DOMRpcResult result = checkRpcResponse(response); - DataSchemaNode resultNodeSchema = null; - NormalizedNode resultData = null; + RpcDefinition resultNodeSchema = null; + final NormalizedNode resultData = result.getResult(); if (result != null && result.getResult() != null) { - resultData = result.getResult(); - final ContainerSchemaNode rpcDataSchemaNode = SchemaContextUtil.getRpcDataSchema(schemaContext, type); - resultNodeSchema = rpcDataSchemaNode.getDataChildByName(result.getResult().getNodeType()); + resultNodeSchema = (RpcDefinition) payload.getInstanceIdentifierContext().getSchemaNode(); } - return new NormalizedNodeContext(new InstanceIdentifierContext(null, resultNodeSchema, mountPoint, - schemaContext), resultData); + return new NormalizedNodeContext(new InstanceIdentifierContext(null, + resultNodeSchema, mountPoint, schemaContext), resultData); } private DOMRpcResult checkRpcResponse(final CheckedFuture response) { @@ -592,7 +599,7 @@ public class RestconfImpl implements RestconfService { } } - private void validateInput(final DataSchemaNode inputSchema, final NormalizedNodeContext payload) { + private void validateInput(final SchemaNode inputSchema, final NormalizedNodeContext payload) { if (inputSchema != null && payload.getData() == null) { // expected a non null payload throw new RestconfDocumentedException("Input is required.", ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE); @@ -631,16 +638,12 @@ public class RestconfImpl implements RestconfService { // } } - /** - * @deprecated method wil be removed for Lithium release - */ - @Deprecated - private StructuredData invokeSalRemoteRpcSubscribeRPC(final CompositeNode payload, final RpcDefinition rpc, - final boolean prettyPrint) { - final CompositeNode value = this.normalizeNode(payload, rpc.getInput(), null); - final SimpleNode pathNode = value == null ? null : value.getFirstSimpleByName(QName.create( - rpc.getQName(), "path")); - final Object pathValue = pathNode == null ? null : pathNode.getValue(); + private CheckedFuture invokeSalRemoteRpcSubscribeRPC(final NormalizedNodeContext payload) { + final ContainerNode value = (ContainerNode) payload.getData(); + final QName rpcQName = payload.getInstanceIdentifierContext().getSchemaNode().getQName(); + final Optional> path = value.getChild(new NodeIdentifier( + QName.create(payload.getInstanceIdentifierContext().getSchemaNode().getQName(), "path"))); + final Object pathValue = path.isPresent() ? path.get().getValue() : null; if (!(pathValue instanceof YangInstanceIdentifier)) { throw new RestconfDocumentedException("Instance identifier was not normalized correctly.", @@ -665,23 +668,24 @@ public class RestconfImpl implements RestconfService { if (Strings.isNullOrEmpty(streamName)) { throw new RestconfDocumentedException( - "Path is empty or contains data node which is not Container or List build-in type.", + "Path is empty or contains value node which is not Container or List build-in type.", ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE); } - final SimpleNode streamNameNode = NodeFactory. createImmutableSimpleNode( - QName.create(rpc.getOutput().getQName(), "stream-name"), null, streamName); - final List> output = new ArrayList>(); - output.add(streamNameNode); + final QName outputQname = QName.create(rpcQName, "output"); + final QName streamNameQname = QName.create(rpcQName, "stream-name"); - final MutableCompositeNode responseData = NodeFactory.createMutableCompositeNode(rpc.getOutput().getQName(), - null, output, null, null); + final ContainerNode output = ImmutableContainerNodeBuilder.create().withNodeIdentifier(new NodeIdentifier(outputQname)) + .withChild(ImmutableNodes.leafNode(streamNameQname, streamName)).build(); if (!Notificator.existListenerFor(streamName)) { - Notificator.createListener(pathIdentifier, streamName); + final YangInstanceIdentifier normalizedPathIdentifier = controllerContext.toNormalized(pathIdentifier); + Notificator.createListener(normalizedPathIdentifier, streamName); } - return new StructuredData(responseData, rpc.getOutput(), null, prettyPrint); + final DOMRpcResult defaultDOMRpcResult = new DefaultDOMRpcResult(output); + + return Futures.immediateCheckedFuture(defaultDOMRpcResult); } @Override @@ -727,7 +731,7 @@ public class RestconfImpl implements RestconfService { if (rpc.getInput() != null) { // FIXME : find a correct Error from specification - throw new IllegalStateException("RPC " + rpc + " needs input value!"); + throw new IllegalStateException("RPC " + rpc + " does'n need input value!"); } final CheckedFuture response; @@ -866,15 +870,17 @@ public class RestconfImpl implements RestconfService { final InstanceIdentifierContext iiWithData = controllerContext.toInstanceIdentifier(identifier); final DOMMountPoint mountPoint = iiWithData.getMountPoint(); NormalizedNode data = null; - YangInstanceIdentifier normalizedII; + final YangInstanceIdentifier normalizedII = iiWithData.getInstanceIdentifier(); if (mountPoint != null) { - normalizedII = new DataNormalizer(mountPoint.getSchemaContext()).toNormalized(iiWithData - .getInstanceIdentifier()); data = broker.readConfigurationData(mountPoint, normalizedII); } else { - normalizedII = controllerContext.toNormalized(iiWithData.getInstanceIdentifier()); data = broker.readConfigurationData(normalizedII); } + if(data == null) { + throw new RestconfDocumentedException( + "Request could not be completed because the relevant data model content does not exist.", + ErrorType.APPLICATION, ErrorTag.DATA_MISSING); + } return new NormalizedNodeContext(iiWithData, data); } @@ -925,16 +931,17 @@ public class RestconfImpl implements RestconfService { final InstanceIdentifierContext iiWithData = controllerContext.toInstanceIdentifier(identifier); final DOMMountPoint mountPoint = iiWithData.getMountPoint(); NormalizedNode data = null; - YangInstanceIdentifier normalizedII; + final YangInstanceIdentifier normalizedII = iiWithData.getInstanceIdentifier(); if (mountPoint != null) { - normalizedII = new DataNormalizer(mountPoint.getSchemaContext()).toNormalized(iiWithData - .getInstanceIdentifier()); data = broker.readOperationalData(mountPoint, normalizedII); } else { - normalizedII = controllerContext.toNormalized(iiWithData.getInstanceIdentifier()); data = broker.readOperationalData(normalizedII); } - + if(data == null) { + throw new RestconfDocumentedException( + "Request could not be completed because the relevant data model content does not exist.", + ErrorType.APPLICATION, ErrorTag.DATA_MISSING); + } return new NormalizedNodeContext(iiWithData, data); } @@ -946,7 +953,8 @@ public class RestconfImpl implements RestconfService { @Override public Response updateConfigurationData(final String identifier, final NormalizedNodeContext payload) { Preconditions.checkNotNull(identifier); - final InstanceIdentifierContext iiWithData = controllerContext.toInstanceIdentifier(identifier); + final InstanceIdentifierContext iiWithData = + (InstanceIdentifierContext) payload.getInstanceIdentifierContext(); validateInput(iiWithData.getSchemaNode(), payload); validateTopLevelNodeName(payload, iiWithData.getInstanceIdentifier()); @@ -1056,7 +1064,7 @@ public class RestconfImpl implements RestconfService { * if key values or key count in payload and URI isn't equal * */ - private void validateListKeysEqualityInPayloadAndUri(final InstanceIdentifierContext iiWithData, + private void validateListKeysEqualityInPayloadAndUri(final InstanceIdentifierContext iiWithData, final NormalizedNode payload) { if (iiWithData.getSchemaNode() instanceof ListSchemaNode) { final List keyDefinitions = ((ListSchemaNode) iiWithData.getSchemaNode()).getKeyDefinition(); @@ -1152,43 +1160,7 @@ public class RestconfImpl implements RestconfService { @Override public Response createConfigurationData(final String identifier, final NormalizedNodeContext payload, final UriInfo uriInfo) { - if (payload == null) { - throw new RestconfDocumentedException("Input is required.", ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE); - } - - final URI payloadNS = payload.getData().getNodeType().getNamespace(); - if (payloadNS == null) { - throw new RestconfDocumentedException( - "Data has bad format. Root element node must have namespace (XML format) or module name(JSON format)", - ErrorType.PROTOCOL, ErrorTag.UNKNOWN_NAMESPACE); - } - - final DOMMountPoint mountPoint = payload.getInstanceIdentifierContext().getMountPoint(); - - final InstanceIdentifierContext iiWithData = mountPoint != null - ? controllerContext.toMountPointIdentifier(identifier) - : controllerContext.toInstanceIdentifier(identifier); - final YangInstanceIdentifier normalizedII = iiWithData.getInstanceIdentifier(); - - try { - if (mountPoint != null) { - broker.commitConfigurationDataPost(mountPoint, normalizedII, payload.getData()); - } else { - broker.commitConfigurationDataPost(normalizedII, payload.getData()); - } - } catch(final RestconfDocumentedException e) { - throw e; - } catch (final Exception e) { - throw new RestconfDocumentedException("Error creating data", e); - } - - - final ResponseBuilder responseBuilder = Response.status(Status.NO_CONTENT); - final URI location = resolveLocation(uriInfo, "config", mountPoint, normalizedII); - if (location != null) { - responseBuilder.location(location); - } - return responseBuilder.build(); + return createConfigurationData(payload, uriInfo); } // FIXME create RestconfIdetifierHelper and move this method there @@ -1235,9 +1207,9 @@ public class RestconfImpl implements RestconfService { } final DOMMountPoint mountPoint = payload.getInstanceIdentifierContext().getMountPoint(); - final InstanceIdentifierContext iiWithData = payload.getInstanceIdentifierContext(); + final InstanceIdentifierContext iiWithData = (InstanceIdentifierContext) payload.getInstanceIdentifierContext(); final YangInstanceIdentifier normalizedII = iiWithData.getInstanceIdentifier(); - + final YangInstanceIdentifier resultII; try { if (mountPoint != null) { broker.commitConfigurationDataPost(mountPoint, normalizedII, payload.getData()); @@ -1252,6 +1224,7 @@ public class RestconfImpl implements RestconfService { } final ResponseBuilder responseBuilder = Response.status(Status.NO_CONTENT); + // FIXME: Provide path to result. final URI location = resolveLocation(uriInfo, "", mountPoint, normalizedII); if (location != null) { responseBuilder.location(location); @@ -1273,17 +1246,14 @@ public class RestconfImpl implements RestconfService { @Override public Response deleteConfigurationData(final String identifier) { - final InstanceIdentifierContext iiWithData = controllerContext.toInstanceIdentifier(identifier); + final InstanceIdentifierContext iiWithData = controllerContext.toInstanceIdentifier(identifier); final DOMMountPoint mountPoint = iiWithData.getMountPoint(); - YangInstanceIdentifier normalizedII; + final YangInstanceIdentifier normalizedII = iiWithData.getInstanceIdentifier(); try { if (mountPoint != null) { - normalizedII = new DataNormalizer(mountPoint.getSchemaContext()).toNormalized(iiWithData - .getInstanceIdentifier()); broker.commitConfigurationDataDelete(mountPoint, normalizedII); } else { - normalizedII = controllerContext.toNormalized(iiWithData.getInstanceIdentifier()); broker.commitConfigurationDataDelete(normalizedII).get(); } } catch (final Exception e) { @@ -1341,8 +1311,8 @@ public class RestconfImpl implements RestconfService { } catch (final NullPointerException e) { WebSocketServer.createInstance(NOTIFICATION_PORT); } - final UriBuilder port = uriBuilder.port(notificationPort); - final URI uriToWebsocketServer = port.replacePath(streamName).build(); + final UriBuilder uriToWebsocketServerBuilder = uriBuilder.port(notificationPort).scheme("ws"); + final URI uriToWebsocketServer = uriToWebsocketServerBuilder.replacePath(streamName).build(); return Response.status(Status.OK).location(uriToWebsocketServer).build(); } @@ -1354,15 +1324,16 @@ public class RestconfImpl implements RestconfService { * contains value * @return enum object if its string value is equal to {@code paramName}. In other cases null. */ - private T parseEnumTypeParameter(final CompositeNode compNode, final Class classDescriptor, + private T parseEnumTypeParameter(final ContainerNode value, final Class classDescriptor, final String paramName) { final QNameModule salRemoteAugment = QNameModule.create(NAMESPACE_EVENT_SUBSCRIPTION_AUGMENT, EVENT_SUBSCRIPTION_AUGMENT_REVISION); - final SimpleNode simpleNode = compNode.getFirstSimpleByName(QName.create(salRemoteAugment, paramName)); - if (simpleNode == null) { + final Optional> enumNode = value.getChild(new NodeIdentifier( + QName.create(salRemoteAugment, paramName))); + if (!enumNode.isPresent()) { return null; } - final Object rawValue = simpleNode.getValue(); + final Object rawValue = enumNode.get().getValue(); if (!(rawValue instanceof String)) { return null; } @@ -1517,7 +1488,7 @@ public class RestconfImpl implements RestconfService { * || MOUNT_POINT_MODULE_NAME .equals( namespace . * toString( ) ) */) - && SchemaContext.NAME.getLocalName().equals(localName(data)); + && SchemaContext.NAME.getLocalName().equals(localName(data)); } private String addMountPointIdentifier(final String identifier) { @@ -1960,8 +1931,47 @@ public class RestconfImpl implements RestconfService { protected MapEntryNode toModuleEntryNode(final Module module, final DataSchemaNode moduleSchemaNode) { Preconditions.checkArgument(moduleSchemaNode instanceof ListSchemaNode, - "moduleSchemaNode has to be of type ListSchemaNode"); final ListSchemaNode listModuleSchemaNode = (ListSchemaNode) moduleSchemaNode; final DataContainerNodeAttrBuilder moduleNodeValues = Builders .mapEntryBuilder(listModuleSchemaNode); List instanceDataChildrenByName = ControllerContext.findInstanceDataChildrenByName( (listModuleSchemaNode), "name"); final DataSchemaNode nameSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null); Preconditions.checkState(nameSchemaNode instanceof LeafSchemaNode); moduleNodeValues.withChild(Builders.leafBuilder((LeafSchemaNode) nameSchemaNode).withValue(module.getName()) .build()); instanceDataChildrenByName = ControllerContext.findInstanceDataChildrenByName( (listModuleSchemaNode), "revision"); final DataSchemaNode revisionSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null); Preconditions.checkState(revisionSchemaNode instanceof LeafSchemaNode); final String revision = REVISION_FORMAT.format(module.getRevision()); moduleNodeValues.withChild(Builders.leafBuilder((LeafSchemaNode) revisionSchemaNode).withValue(revision) .build()); instanceDataChildrenByName = ControllerContext.findInstanceDataChildrenByName( (listModuleSchemaNode), "namespace"); final DataSchemaNode namespaceSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null); Preconditions.checkState(namespaceSchemaNode instanceof LeafSchemaNode); moduleNodeValues.withChild(Builders.leafBuilder((LeafSchemaNode) namespaceSchemaNode) .withValue(module.getNamespace().toString()).build()); instanceDataChildrenByName = ControllerContext.findInstanceDataChildrenByName( (listModuleSchemaNode), "feature"); final DataSchemaNode featureSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null); Preconditions.checkState(featureSchemaNode instanceof LeafListSchemaNode); final ListNodeBuilder> featuresBuilder = Builders .leafSetBuilder((LeafListSchemaNode) featureSchemaNode); for (final FeatureDefinition feature : module.getFeatures()) { featuresBuilder.withChild(Builders.leafSetEntryBuilder(((LeafListSchemaNode) featureSchemaNode)) .withValue(feature.getQName().getLocalName()).build()); } moduleNodeValues.withChild(featuresBuilder.build()); - return moduleNodeValues.build(); } + "moduleSchemaNode has to be of type ListSchemaNode"); + final ListSchemaNode listModuleSchemaNode = (ListSchemaNode) moduleSchemaNode; + final DataContainerNodeAttrBuilder moduleNodeValues = Builders + .mapEntryBuilder(listModuleSchemaNode); + + List instanceDataChildrenByName = ControllerContext.findInstanceDataChildrenByName( + (listModuleSchemaNode), "name"); + final DataSchemaNode nameSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null); + Preconditions.checkState(nameSchemaNode instanceof LeafSchemaNode); + moduleNodeValues.withChild(Builders.leafBuilder((LeafSchemaNode) nameSchemaNode).withValue(module.getName()) + .build()); + + instanceDataChildrenByName = ControllerContext.findInstanceDataChildrenByName( + (listModuleSchemaNode), "revision"); + final DataSchemaNode revisionSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null); + Preconditions.checkState(revisionSchemaNode instanceof LeafSchemaNode); + final String revision = REVISION_FORMAT.format(module.getRevision()); + moduleNodeValues.withChild(Builders.leafBuilder((LeafSchemaNode) revisionSchemaNode).withValue(revision) + .build()); + + instanceDataChildrenByName = ControllerContext.findInstanceDataChildrenByName( + (listModuleSchemaNode), "namespace"); + final DataSchemaNode namespaceSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null); + Preconditions.checkState(namespaceSchemaNode instanceof LeafSchemaNode); + moduleNodeValues.withChild(Builders.leafBuilder((LeafSchemaNode) namespaceSchemaNode) + .withValue(module.getNamespace().toString()).build()); + + instanceDataChildrenByName = ControllerContext.findInstanceDataChildrenByName( + (listModuleSchemaNode), "feature"); + final DataSchemaNode featureSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null); + Preconditions.checkState(featureSchemaNode instanceof LeafListSchemaNode); + final ListNodeBuilder> featuresBuilder = Builders + .leafSetBuilder((LeafListSchemaNode) featureSchemaNode); + for (final FeatureDefinition feature : module.getFeatures()) { + featuresBuilder.withChild(Builders.leafSetEntryBuilder(((LeafListSchemaNode) featureSchemaNode)) + .withValue(feature.getQName().getLocalName()).build()); + } + moduleNodeValues.withChild(featuresBuilder.build()); + + return moduleNodeValues.build(); + } protected MapEntryNode toStreamEntryNode(final String streamName, final DataSchemaNode streamSchemaNode) { Preconditions.checkArgument(streamSchemaNode instanceof ListSchemaNode,