X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=restconf%2Frestconf-nb-bierman02%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fnetconf%2Fsal%2Frestconf%2Fimpl%2FControllerContext.java;h=39a61379eb4daaa4a139c18afd317172e6fedb09;hb=80f81382d19639366f87cc30c207d8ccbe0ca25f;hp=6890b0d175092a6bb47ba73340b73bfd1c2f767b;hpb=824baf9fe14e31465c58f3842c4cb0aa88b34757;p=netconf.git diff --git a/restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/restconf/impl/ControllerContext.java b/restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/restconf/impl/ControllerContext.java index 6890b0d175..39a61379eb 100644 --- a/restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/restconf/impl/ControllerContext.java +++ b/restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/restconf/impl/ControllerContext.java @@ -7,12 +7,13 @@ */ package org.opendaylight.netconf.sal.restconf.impl; -import com.google.common.base.Optional; import com.google.common.base.Preconditions; import com.google.common.base.Splitter; import com.google.common.base.Strings; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import java.io.Closeable; import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URLDecoder; @@ -23,18 +24,26 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.Date; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.concurrent.atomic.AtomicReference; +import javax.annotation.PreDestroy; +import javax.inject.Inject; +import javax.inject.Singleton; import javax.ws.rs.core.Response.Status; +import org.apache.aries.blueprint.annotation.service.Reference; import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationException; import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationOperation; import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizer; -import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint; -import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService; +import org.opendaylight.mdsal.dom.api.DOMMountPoint; +import org.opendaylight.mdsal.dom.api.DOMMountPointService; +import org.opendaylight.mdsal.dom.api.DOMSchemaService; +import org.opendaylight.mdsal.dom.api.DOMYangTextSourceProvider; +import org.opendaylight.netconf.sal.rest.api.Draft02; import org.opendaylight.netconf.sal.rest.api.Draft02.RestConfModule; import org.opendaylight.restconf.common.context.InstanceIdentifierContext; import org.opendaylight.restconf.common.errors.RestconfDocumentedException; @@ -42,7 +51,9 @@ import org.opendaylight.restconf.common.errors.RestconfError.ErrorTag; import org.opendaylight.restconf.common.errors.RestconfError.ErrorType; import org.opendaylight.restconf.common.util.RestUtil; import org.opendaylight.yangtools.concepts.Codec; +import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.Revision; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.InstanceIdentifierBuilder; @@ -50,7 +61,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.model.api.AnyXmlSchemaNode; -import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode; +import org.opendaylight.yangtools.yang.model.api.CaseSchemaNode; import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode; import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; @@ -70,15 +81,13 @@ import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class ControllerContext implements SchemaContextListener { +@Singleton +public final class ControllerContext implements SchemaContextListener, Closeable { // FIXME: this should be in md-sal somewhere public static final String MOUNT = "yang-ext:mount"; private static final Logger LOG = LoggerFactory.getLogger(ControllerContext.class); - // FIXME: this should be the current instance which is mutated - private static final ControllerContext INSTANCE = new ControllerContext(); - private static final String NULL_VALUE = "null"; private static final String MOUNT_MODULE = "yang-ext"; @@ -91,26 +100,42 @@ public class ControllerContext implements SchemaContextListener { private final AtomicReference> qnameToRpc = new AtomicReference<>(Collections.emptyMap()); - // FIXME; these three should be final + private final DOMMountPointService mountService; + private final DOMYangTextSourceProvider yangTextSourceProvider; + private final ListenerRegistration listenerRegistration; private volatile SchemaContext globalSchema; - private volatile DOMMountPointService mountService; - private DataNormalizer dataNormalizer; + private volatile DataNormalizer dataNormalizer; + @Inject + public ControllerContext(final @Reference DOMSchemaService schemaService, + final @Reference DOMMountPointService mountService, final @Reference DOMSchemaService domSchemaService) { + this.mountService = mountService; + this.yangTextSourceProvider = domSchemaService.getExtensions().getInstance(DOMYangTextSourceProvider.class); - public void setGlobalSchema(final SchemaContext globalSchema) { - this.globalSchema = globalSchema; - this.dataNormalizer = new DataNormalizer(globalSchema); + onGlobalContextUpdated(schemaService.getGlobalContext()); + listenerRegistration = schemaService.registerSchemaContextListener(this); } - public void setMountService(final DOMMountPointService mountService) { - this.mountService = mountService; + /** + * Factory method. + * + * @deprecated Just use the + * {@link #ControllerContext(DOMSchemaService, DOMMountPointService, DOMSchemaService)} + * constructor instead. + */ + @Deprecated + public static ControllerContext newInstance(final DOMSchemaService schemaService, + final DOMMountPointService mountService, final DOMSchemaService domSchemaService) { + return new ControllerContext(schemaService, mountService, domSchemaService); } - private ControllerContext() { + private void setGlobalSchema(final SchemaContext globalSchema) { + this.globalSchema = globalSchema; + this.dataNormalizer = new DataNormalizer(globalSchema); } - public static ControllerContext getInstance() { - return INSTANCE; + public DOMYangTextSourceProvider getYangTextSourceProvider() { + return yangTextSourceProvider; } private void checkPreconditions() { @@ -119,6 +144,12 @@ public class ControllerContext implements SchemaContextListener { } } + @Override + @PreDestroy + public void close() { + listenerRegistration.close(); + } + public void setSchemas(final SchemaContext schemas) { onGlobalContextUpdated(schemas); } @@ -158,15 +189,15 @@ public class ControllerContext implements SchemaContextListener { } final InstanceIdentifierBuilder builder = YangInstanceIdentifier.builder(); - final Module latestModule = this.globalSchema.findModuleByName(startModule, null); + final Set latestModule = this.globalSchema.findModules(startModule); - if (latestModule == null) { + if (latestModule.isEmpty()) { throw new RestconfDocumentedException("The module named '" + startModule + "' does not exist.", ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT); } final InstanceIdentifierContext iiWithSchemaNode = - collectPathArguments(builder, pathArgs, latestModule, null, toMountPointIdentifier); + collectPathArguments(builder, pathArgs, latestModule.iterator().next(), null, toMountPointIdentifier); if (iiWithSchemaNode == null) { throw new RestconfDocumentedException("URI has bad format", ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE); @@ -199,55 +230,52 @@ public class ControllerContext implements SchemaContextListener { public Module findModuleByName(final String moduleName) { checkPreconditions(); - Preconditions.checkArgument((moduleName != null) && !moduleName.isEmpty()); - return this.globalSchema.findModuleByName(moduleName, null); + Preconditions.checkArgument(moduleName != null && !moduleName.isEmpty()); + return this.globalSchema.findModules(moduleName).stream().findFirst().orElse(null); } public Module findModuleByName(final DOMMountPoint mountPoint, final String moduleName) { - Preconditions.checkArgument((moduleName != null) && (mountPoint != null)); + Preconditions.checkArgument(moduleName != null && mountPoint != null); final SchemaContext mountPointSchema = mountPoint.getSchemaContext(); if (mountPointSchema == null) { return null; } - return mountPointSchema.findModuleByName(moduleName, null); + return mountPointSchema.findModules(moduleName).stream().findFirst().orElse(null); } public Module findModuleByNamespace(final URI namespace) { checkPreconditions(); Preconditions.checkArgument(namespace != null); - return this.globalSchema.findModuleByNamespaceAndRevision(namespace, null); + return this.globalSchema.findModules(namespace).stream().findFirst().orElse(null); } public Module findModuleByNamespace(final DOMMountPoint mountPoint, final URI namespace) { - Preconditions.checkArgument((namespace != null) && (mountPoint != null)); + Preconditions.checkArgument(namespace != null && mountPoint != null); final SchemaContext mountPointSchema = mountPoint.getSchemaContext(); if (mountPointSchema == null) { return null; } - return mountPointSchema.findModuleByNamespaceAndRevision(namespace, null); + return mountPointSchema.findModules(namespace).stream().findFirst().orElse(null); } - public Module findModuleByNameAndRevision(final QName module) { + public Module findModuleByNameAndRevision(final String name, final Revision revision) { checkPreconditions(); - Preconditions - .checkArgument((module != null) && (module.getLocalName() != null) && (module.getRevision() != null)); + Preconditions.checkArgument(name != null && revision != null); - return this.globalSchema.findModuleByName(module.getLocalName(), module.getRevision()); + return this.globalSchema.findModule(name, revision).orElse(null); } - public Module findModuleByNameAndRevision(final DOMMountPoint mountPoint, final QName module) { + public Module findModuleByNameAndRevision(final DOMMountPoint mountPoint, final String name, + final Revision revision) { checkPreconditions(); - Preconditions - .checkArgument((module != null) && (module.getLocalName() != null) && (module.getRevision() != null) - && (mountPoint != null)); + Preconditions.checkArgument(name != null && revision != null && mountPoint != null); final SchemaContext schemaContext = mountPoint.getSchemaContext(); - return schemaContext == null ? null : schemaContext.findModuleByName(module.getLocalName(), - module.getRevision()); + return schemaContext == null ? null : schemaContext.findModule(name, revision).orElse(null); } public DataNodeContainer getDataNodeContainerFor(final YangInstanceIdentifier path) { @@ -256,13 +284,12 @@ public class ControllerContext implements SchemaContextListener { final Iterable elements = path.getPathArguments(); final PathArgument head = elements.iterator().next(); final QName startQName = head.getNodeType(); - final Module initialModule = this.globalSchema.findModuleByNamespaceAndRevision(startQName.getNamespace(), - startQName.getRevision()); + final Module initialModule = this.globalSchema.findModule(startQName.getModule()).orElse(null); DataNodeContainer node = initialModule; for (final PathArgument element : elements) { final QName _nodeType = element.getNodeType(); final DataSchemaNode potentialNode = childByQName(node, _nodeType); - if ((potentialNode == null) || !isListOrContainer(potentialNode)) { + if (potentialNode == null || !isListOrContainer(potentialNode)) { return null; } node = (DataNodeContainer) potentialNode; @@ -284,14 +311,13 @@ public class ControllerContext implements SchemaContextListener { } else { schemaContext = this.globalSchema; } - final Module initialModule = schemaContext.findModuleByNamespaceAndRevision(startQName.getNamespace(), - startQName.getRevision()); + final Module initialModule = schemaContext.findModule(startQName.getModule()).orElse(null); DataNodeContainer node = initialModule; for (final PathArgument element : elements) { if (!(element instanceof AugmentationIdentifier)) { final QName _nodeType = element.getNodeType(); final DataSchemaNode potentialNode = childByQName(node, _nodeType); - if (!((element instanceof NodeIdentifier) && (potentialNode instanceof ListSchemaNode)) + if (!(element instanceof NodeIdentifier && potentialNode instanceof ListSchemaNode) && !(potentialNode instanceof ChoiceSchemaNode)) { builder.append(convertToRestconfIdentifier(element, potentialNode, mount)); if (potentialNode instanceof DataNodeContainer) { @@ -339,7 +365,7 @@ public class ControllerContext implements SchemaContextListener { } private static CharSequence toRestconfIdentifier(final SchemaContext context, final QName qname) { - final Module schema = context.findModuleByNamespaceAndRevision(qname.getNamespace(), qname.getRevision()); + final Module schema = context.findModule(qname.getModule()).orElse(null); return schema == null ? null : schema.getName() + ':' + qname.getLocalName(); } @@ -370,7 +396,7 @@ public class ControllerContext implements SchemaContextListener { } public Module getRestconfModule() { - return findModuleByNameAndRevision(RestConfModule.IETF_RESTCONF_QNAME); + return findModuleByNameAndRevision(Draft02.RestConfModule.NAME, Revision.of(Draft02.RestConfModule.REVISION)); } public DataSchemaNode getRestconfModuleErrorsSchemaNode() { @@ -413,33 +439,33 @@ public class ControllerContext implements SchemaContextListener { if (RestConfModule.OPERATIONS_CONTAINER_SCHEMA_NODE.equals(schemaNodeName)) { final List instances = findInstanceDataChildrenByName( - ((DataNodeContainer) restconfContainer), RestConfModule.OPERATIONS_CONTAINER_SCHEMA_NODE); + (DataNodeContainer) restconfContainer, RestConfModule.OPERATIONS_CONTAINER_SCHEMA_NODE); return Iterables.getFirst(instances, null); } else if (RestConfModule.STREAMS_CONTAINER_SCHEMA_NODE.equals(schemaNodeName)) { final List instances = findInstanceDataChildrenByName( - ((DataNodeContainer) restconfContainer), RestConfModule.STREAMS_CONTAINER_SCHEMA_NODE); + (DataNodeContainer) restconfContainer, RestConfModule.STREAMS_CONTAINER_SCHEMA_NODE); return Iterables.getFirst(instances, null); } else if (RestConfModule.STREAM_LIST_SCHEMA_NODE.equals(schemaNodeName)) { List instances = findInstanceDataChildrenByName( - ((DataNodeContainer) restconfContainer), RestConfModule.STREAMS_CONTAINER_SCHEMA_NODE); + (DataNodeContainer) restconfContainer, RestConfModule.STREAMS_CONTAINER_SCHEMA_NODE); final DataSchemaNode modules = Iterables.getFirst(instances, null); - instances = findInstanceDataChildrenByName(((DataNodeContainer) modules), + instances = findInstanceDataChildrenByName((DataNodeContainer) modules, RestConfModule.STREAM_LIST_SCHEMA_NODE); return Iterables.getFirst(instances, null); } else if (RestConfModule.MODULES_CONTAINER_SCHEMA_NODE.equals(schemaNodeName)) { final List instances = findInstanceDataChildrenByName( - ((DataNodeContainer) restconfContainer), RestConfModule.MODULES_CONTAINER_SCHEMA_NODE); + (DataNodeContainer) restconfContainer, RestConfModule.MODULES_CONTAINER_SCHEMA_NODE); return Iterables.getFirst(instances, null); } else if (RestConfModule.MODULE_LIST_SCHEMA_NODE.equals(schemaNodeName)) { List instances = findInstanceDataChildrenByName( - ((DataNodeContainer) restconfContainer), RestConfModule.MODULES_CONTAINER_SCHEMA_NODE); + (DataNodeContainer) restconfContainer, RestConfModule.MODULES_CONTAINER_SCHEMA_NODE); final DataSchemaNode modules = Iterables.getFirst(instances, null); - instances = findInstanceDataChildrenByName(((DataNodeContainer) modules), + instances = findInstanceDataChildrenByName((DataNodeContainer) modules, RestConfModule.MODULE_LIST_SCHEMA_NODE); return Iterables.getFirst(instances, null); } else if (RestConfModule.STREAMS_CONTAINER_SCHEMA_NODE.equals(schemaNodeName)) { final List instances = findInstanceDataChildrenByName( - ((DataNodeContainer) restconfContainer), RestConfModule.STREAMS_CONTAINER_SCHEMA_NODE); + (DataNodeContainer) restconfContainer, RestConfModule.STREAMS_CONTAINER_SCHEMA_NODE); return Iterables.getFirst(instances, null); } @@ -447,7 +473,7 @@ public class ControllerContext implements SchemaContextListener { } private static DataSchemaNode childByQName(final ChoiceSchemaNode container, final QName name) { - for (final ChoiceCaseNode caze : container.getCases()) { + for (final CaseSchemaNode caze : container.getCases().values()) { final DataSchemaNode ret = childByQName(caze, name); if (ret != null) { return ret; @@ -457,7 +483,7 @@ public class ControllerContext implements SchemaContextListener { return null; } - private static DataSchemaNode childByQName(final ChoiceCaseNode container, final QName name) { + private static DataSchemaNode childByQName(final CaseSchemaNode container, final QName name) { return container.getDataChildByName(name); } @@ -479,8 +505,8 @@ public class ControllerContext implements SchemaContextListener { private static DataSchemaNode childByQName(final Object container, final QName name) { - if (container instanceof ChoiceCaseNode) { - return childByQName((ChoiceCaseNode) container, name); + if (container instanceof CaseSchemaNode) { + return childByQName((CaseSchemaNode) container, name); } else if (container instanceof ChoiceSchemaNode) { return childByQName((ChoiceSchemaNode) container, name); } else if (container instanceof ContainerSchemaNode) { @@ -493,7 +519,7 @@ public class ControllerContext implements SchemaContextListener { return childByQName((Module) container, name); } else { throw new IllegalArgumentException("Unhandled parameter types: " - + Arrays.asList(container, name).toString()); + + Arrays.asList(container, name).toString()); } } @@ -501,8 +527,8 @@ public class ControllerContext implements SchemaContextListener { final DataSchemaNode ret = container.getDataChildByName(name); if (ret == null) { for (final DataSchemaNode node : container.getChildNodes()) { - if ((node instanceof ChoiceSchemaNode)) { - final ChoiceSchemaNode choiceNode = ((ChoiceSchemaNode) node); + if (node instanceof ChoiceSchemaNode) { + final ChoiceSchemaNode choiceNode = (ChoiceSchemaNode) node; final DataSchemaNode childByQName = childByQName(choiceNode, name); if (childByQName != null) { return childByQName; @@ -513,28 +539,35 @@ public class ControllerContext implements SchemaContextListener { return ret; } - private static String toUriString(final Object object, final LeafSchemaNode leafNode, final DOMMountPoint mount) + private String toUriString(final Object object, final LeafSchemaNode leafNode, final DOMMountPoint mount) throws UnsupportedEncodingException { - final Codec codec = RestCodec.from(leafNode.getType(), mount); + final Codec codec = RestCodec.from(leafNode.getType(), mount, this); // FIXME: UrlEncoder looks up a well-known charset, we need something that will use it directly return object == null ? "" : URLEncoder.encode(codec.serialize(object).toString(), URI_ENCODING_CHARSET.name()); } + @SuppressFBWarnings(value = "RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE", justification = "Unrecognised NullableDecl") private InstanceIdentifierContext collectPathArguments(final InstanceIdentifierBuilder builder, final List strings, final DataNodeContainer parentNode, final DOMMountPoint mountPoint, final boolean returnJustMountPoint) { - Preconditions.>checkNotNull(strings); + Preconditions.checkNotNull(strings); if (parentNode == null) { return null; } if (strings.isEmpty()) { - return createContext(builder.build(), ((DataSchemaNode) parentNode), + return createContext(builder.build(), (DataSchemaNode) parentNode, mountPoint,mountPoint != null ? mountPoint.getSchemaContext() : this.globalSchema); } final String head = strings.iterator().next(); + + if (head.isEmpty()) { + final List remaining = strings.subList(1, strings.size()); + return collectPathArguments(builder, remaining, parentNode, mountPoint, returnJustMountPoint); + } + final String nodeName = toNodeName(head); final String moduleName = toModuleName(head); @@ -567,7 +600,7 @@ public class ControllerContext implements SchemaContextListener { ErrorType.APPLICATION, ErrorTag.UNKNOWN_ELEMENT); } - if (returnJustMountPoint || (strings.size() == 1)) { + if (returnJustMountPoint || strings.size() == 1) { final YangInstanceIdentifier instance = YangInstanceIdentifier.builder().build(); return new InstanceIdentifierContext<>(instance, mountPointSchema, mount,mountPointSchema); } @@ -579,22 +612,21 @@ public class ControllerContext implements SchemaContextListener { ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE); } - final Module moduleBehindMountPoint = - mountPointSchema.findModuleByName(moduleNameBehindMountPoint, null); - if (moduleBehindMountPoint == null) { + final Iterator it = mountPointSchema.findModules(moduleNameBehindMountPoint).iterator(); + if (!it.hasNext()) { throw new RestconfDocumentedException("\"" + moduleNameBehindMountPoint + "\" module does not exist in mount point.", ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT); } final List subList = strings.subList(1, strings.size()); - return collectPathArguments(YangInstanceIdentifier.builder(), subList, moduleBehindMountPoint, mount, + return collectPathArguments(YangInstanceIdentifier.builder(), subList, it.next(), mount, returnJustMountPoint); } Module module = null; if (mountPoint == null) { checkPreconditions(); - module = this.globalSchema.findModuleByName(moduleName, null); + module = this.globalSchema.findModules(moduleName).stream().findFirst().orElse(null); if (module == null) { throw new RestconfDocumentedException("\"" + moduleName + "\" module does not exist.", ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT); @@ -602,7 +634,7 @@ public class ControllerContext implements SchemaContextListener { } else { final SchemaContext schemaContext = mountPoint.getSchemaContext(); if (schemaContext != null) { - module = schemaContext.findModuleByName(moduleName, null); + module = schemaContext.findModules(moduleName).stream().findFirst().orElse(null); } else { module = null; } @@ -614,14 +646,13 @@ public class ControllerContext implements SchemaContextListener { targetNode = findInstanceDataChildByNameAndNamespace(parentNode, nodeName, module.getNamespace()); - if ((targetNode == null) && (parentNode instanceof Module)) { + if (targetNode == null && parentNode instanceof Module) { final RpcDefinition rpc; if (mountPoint == null) { - rpc = ControllerContext.getInstance().getRpcDefinition(head, module.getRevision()); + rpc = getRpcDefinition(head, module.getRevision()); } else { final String rpcName = toNodeName(head); - ControllerContext.getInstance(); - rpc = ControllerContext.getRpcDefinition(module, rpcName); + rpc = getRpcDefinition(module, rpcName); } if (rpc != null) { return new InstanceIdentifierContext<>(builder.build(), rpc, mountPoint, @@ -666,10 +697,10 @@ public class ControllerContext implements SchemaContextListener { } int consumed = 1; - if ((targetNode instanceof ListSchemaNode)) { - final ListSchemaNode listNode = ((ListSchemaNode) targetNode); + if (targetNode instanceof ListSchemaNode) { + final ListSchemaNode listNode = (ListSchemaNode) targetNode; final int keysSize = listNode.getKeyDefinition().size(); - if ((strings.size() - consumed) < keysSize) { + if (strings.size() - consumed < keysSize) { throw new RestconfDocumentedException("Missing key for list \"" + listNode.getQName().getLocalName() + "\".", ErrorType.PROTOCOL, ErrorTag.DATA_MISSING); } @@ -697,9 +728,9 @@ public class ControllerContext implements SchemaContextListener { builder.node(targetNode.getQName()); } - if ((targetNode instanceof DataNodeContainer)) { + if (targetNode instanceof DataNodeContainer) { final List remaining = strings.subList(consumed, strings.size()); - return collectPathArguments(builder, remaining, ((DataNodeContainer) targetNode), mountPoint, + return collectPathArguments(builder, remaining, (DataNodeContainer) targetNode, mountPoint, returnJustMountPoint); } @@ -748,38 +779,37 @@ public class ControllerContext implements SchemaContextListener { final Iterable choiceNodes = Iterables.filter(container.getChildNodes(), ChoiceSchemaNode.class); - final Iterable> map = Iterables.transform(choiceNodes, ChoiceSchemaNode::getCases); - for (final ChoiceCaseNode caze : Iterables.concat(map)) { + final Iterable> map = Iterables.transform(choiceNodes, + choice -> choice.getCases().values()); + for (final CaseSchemaNode caze : Iterables.concat(map)) { collectInstanceDataNodeContainers(potentialSchemaNodes, caze, name); } } public static boolean isInstantiatedDataSchema(final DataSchemaNode node) { - return (node instanceof LeafSchemaNode) || (node instanceof LeafListSchemaNode) - || (node instanceof ContainerSchemaNode) || (node instanceof ListSchemaNode) - || (node instanceof AnyXmlSchemaNode); + return node instanceof LeafSchemaNode || node instanceof LeafListSchemaNode + || node instanceof ContainerSchemaNode || node instanceof ListSchemaNode + || node instanceof AnyXmlSchemaNode; } private void addKeyValue(final HashMap map, final DataSchemaNode node, final String uriValue, final DOMMountPoint mountPoint) { Preconditions.checkNotNull(uriValue); - Preconditions.checkArgument((node instanceof LeafSchemaNode)); + Preconditions.checkArgument(node instanceof LeafSchemaNode); + final SchemaContext schemaContext = mountPoint == null ? this.globalSchema : mountPoint.getSchemaContext(); final String urlDecoded = urlPathArgDecode(uriValue); TypeDefinition typedef = ((LeafSchemaNode) node).getType(); final TypeDefinition baseType = RestUtil.resolveBaseTypeFrom(typedef); if (baseType instanceof LeafrefTypeDefinition) { - typedef = SchemaContextUtil.getBaseTypeForLeafRef((LeafrefTypeDefinition) baseType, this.globalSchema, - node); + typedef = SchemaContextUtil.getBaseTypeForLeafRef((LeafrefTypeDefinition) baseType, schemaContext, node); } - final Codec codec = RestCodec.from(typedef, mountPoint); + final Codec codec = RestCodec.from(typedef, mountPoint, this); Object decoded = codec.deserialize(urlDecoded); String additionalInfo = ""; if (decoded == null) { - if ((typedef instanceof IdentityrefTypeDefinition)) { - final SchemaContext schemaContext = - mountPoint == null ? this.globalSchema : mountPoint.getSchemaContext(); - decoded = toQName(schemaContext, urlDecoded, null); + if (typedef instanceof IdentityrefTypeDefinition) { + decoded = toQName(schemaContext, urlDecoded); additionalInfo = "For key which is of type identityref it should be in format module_name:identity_name."; } @@ -821,23 +851,37 @@ public class ControllerContext implements SchemaContextListener { return str.substring(idx + 1); } - private QName toQName(final SchemaContext schemaContext, final String name, final Date revisionDate) { + private QName toQName(final SchemaContext schemaContext, final String name, + final java.util.Optional revisionDate) { checkPreconditions(); final String module = toModuleName(name); final String node = toNodeName(name); - final Module m = schemaContext.findModuleByName(module, revisionDate); + final Module m = schemaContext.findModule(module, revisionDate).orElse(null); return m == null ? null : QName.create(m.getQNameModule(), node); } + private QName toQName(final SchemaContext schemaContext, final String name) { + checkPreconditions(); + final String module = toModuleName(name); + final String node = toNodeName(name); + final Set modules = schemaContext.findModules(module); + return modules.isEmpty() ? null : QName.create(modules.iterator().next().getQNameModule(), node); + } + private static boolean isListOrContainer(final DataSchemaNode node) { - return (node instanceof ListSchemaNode) || (node instanceof ContainerSchemaNode); + return node instanceof ListSchemaNode || node instanceof ContainerSchemaNode; } - public RpcDefinition getRpcDefinition(final String name, final Date revisionDate) { + public RpcDefinition getRpcDefinition(final String name, final java.util.Optional revisionDate) { final QName validName = toQName(this.globalSchema, name, revisionDate); return validName == null ? null : this.qnameToRpc.get().get(validName); } + public RpcDefinition getRpcDefinition(final String name) { + final QName validName = toQName(this.globalSchema, name); + return validName == null ? null : this.qnameToRpc.get().get(validName); + } + private static RpcDefinition getRpcDefinition(final Module module, final String rpcName) { final QName rpcQName = QName.create(module.getQNameModule(), rpcName); for (final RpcDefinition rpcDefinition : module.getRpcs()) { @@ -874,7 +918,7 @@ public class ControllerContext implements SchemaContextListener { return decodedPathArgs; } catch (final UnsupportedEncodingException e) { throw new RestconfDocumentedException("Invalid URL path '" + strings + "': " + e.getMessage(), - ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE); + ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE, e); } } @@ -884,7 +928,7 @@ public class ControllerContext implements SchemaContextListener { return URLDecoder.decode(pathArg, URI_ENCODING_CHARSET.name()); } catch (final UnsupportedEncodingException e) { throw new RestconfDocumentedException("Invalid URL path arg '" + pathArg + "': " + e.getMessage(), - ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE); + ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE, e); } } @@ -895,10 +939,10 @@ public class ControllerContext implements SchemaContextListener { final DOMMountPoint mount) { if (argument instanceof NodeIdentifier) { return convertToRestconfIdentifier((NodeIdentifier) argument, mount); - } else if ((argument instanceof NodeIdentifierWithPredicates) && (node instanceof ListSchemaNode)) { + } else if (argument instanceof NodeIdentifierWithPredicates && node instanceof ListSchemaNode) { return convertToRestconfIdentifierWithPredicates((NodeIdentifierWithPredicates) argument, (ListSchemaNode) node, mount); - } else if ((argument != null) && (node != null)) { + } else if (argument != null && node != null) { throw new IllegalArgumentException("Conversion of generic path argument is not supported"); } else { throw new IllegalArgumentException("Unhandled parameter types: " + Arrays.asList(argument, node)); @@ -978,5 +1022,4 @@ public class ControllerContext implements SchemaContextListener { public DataNormalizationOperation getRootOperation() { return this.dataNormalizer.getRootOperation(); } - }