From: Jakub Toth Date: Fri, 22 Apr 2016 09:49:40 +0000 (+0200) Subject: Bug 5526 - Implementations of services X-Git-Tag: release/boron~117 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=710ecac2a947d10790c32fabfc2f076f29094a62;p=netconf.git Bug 5526 - Implementations of services * used soft reference for schema context for holding the current schema * util classes for static methodes and constants for implementations of services Change-Id: I5ddccc91feaf3ebfd7f8b40c2f954c4506995622 Signed-off-by: Jakub Toth --- diff --git a/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/rest/impl/services/Draft11ServicesWrapperImpl.java b/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/rest/impl/services/Draft11ServicesWrapperImpl.java new file mode 100644 index 0000000000..375788a121 --- /dev/null +++ b/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/rest/impl/services/Draft11ServicesWrapperImpl.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.restconf.rest.impl.services; + +import javax.ws.rs.core.UriInfo; +import org.opendaylight.netconf.md.sal.rest.schema.SchemaExportContext; +import org.opendaylight.netconf.sal.restconf.impl.NormalizedNodeContext; +import org.opendaylight.restconf.rest.api.schema.context.SchemaContextHandler; +import org.opendaylight.restconf.rest.api.services.Draft11ServicesWrapper; +import org.opendaylight.restconf.rest.api.services.RestconfModulesService; +import org.opendaylight.restconf.rest.api.services.RestconfOperationsService; +import org.opendaylight.restconf.rest.api.services.RestconfStreamsService; +import org.opendaylight.restconf.rest.api.services.schema.RestconfSchemaService; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; + +/** + * Implementation of {@link Draft11ServicesWrapper} + * + */ +public class Draft11ServicesWrapperImpl implements Draft11ServicesWrapper { + + private final RestconfModulesService delegRestModSer; + private final RestconfOperationsService delegRestOpsSer; + private final RestconfStreamsService delegRestStrsSer; + private final RestconfSchemaService delegRestSchSer; + + /** + * Creating delegates to all implemented services + * + * @param schemaContextHandler + * - for handling {@link SchemaContext} + */ + public Draft11ServicesWrapperImpl(final SchemaContextHandler schemaContextHandler) { + this.delegRestModSer = new RestconfModulesServiceImpl(schemaContextHandler); + this.delegRestOpsSer = new RestconfOperationsServiceImpl(schemaContextHandler); + this.delegRestStrsSer = new RestconfStreamsServiceImpl(schemaContextHandler); + this.delegRestSchSer = new RestconfSchemaServiceImpl(schemaContextHandler); + } + + @Override + public NormalizedNodeContext getModules(final UriInfo uriInfo) { + return this.delegRestModSer.getModules(uriInfo); + } + + @Override + public NormalizedNodeContext getModules(final String identifier, final UriInfo uriInfo) { + return this.delegRestModSer.getModules(identifier, uriInfo); + } + + @Override + public NormalizedNodeContext getModule(final String identifier, final UriInfo uriInfo) { + return this.delegRestModSer.getModules(identifier, uriInfo); + } + + @Override + public NormalizedNodeContext getOperations(final UriInfo uriInfo) { + return this.delegRestOpsSer.getOperations(uriInfo); + } + + @Override + public NormalizedNodeContext getOperations(final String identifier, final UriInfo uriInfo) { + return this.delegRestOpsSer.getOperations(identifier, uriInfo); + } + + @Override + public NormalizedNodeContext getAvailableStreams(final UriInfo uriInfo) { + return this.delegRestStrsSer.getAvailableStreams(uriInfo); + } + + @Override + public SchemaExportContext getSchema(final String mountAndModuleId) { + return this.delegRestSchSer.getSchema(mountAndModuleId); + } + +} diff --git a/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/rest/impl/services/RestconfModulesServiceImpl.java b/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/rest/impl/services/RestconfModulesServiceImpl.java new file mode 100644 index 0000000000..8ff0b02a4a --- /dev/null +++ b/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/rest/impl/services/RestconfModulesServiceImpl.java @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.restconf.rest.impl.services; + +import com.google.common.base.Preconditions; +import java.util.Collections; +import java.util.Set; +import javax.ws.rs.core.UriInfo; +import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint; +import org.opendaylight.netconf.sal.restconf.impl.InstanceIdentifierContext; +import org.opendaylight.netconf.sal.restconf.impl.NormalizedNodeContext; +import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException; +import org.opendaylight.netconf.sal.restconf.impl.RestconfError.ErrorTag; +import org.opendaylight.netconf.sal.restconf.impl.RestconfError.ErrorType; +import org.opendaylight.restconf.Draft11; +import org.opendaylight.restconf.rest.api.schema.context.SchemaContextHandler; +import org.opendaylight.restconf.rest.api.services.RestconfModulesService; +import org.opendaylight.restconf.utils.RestconfConstants; +import org.opendaylight.restconf.utils.mapping.RestconfMappingNodeUtil; +import org.opendaylight.restconf.utils.parser.ParserIdentifier; +import org.opendaylight.restconf.utils.schema.context.RestconfSchemaUtil; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; +import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; +import org.opendaylight.yangtools.yang.data.api.schema.MapNode; +import org.opendaylight.yangtools.yang.data.impl.schema.Builders; +import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder; +import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Implementation of {@link RestconfModulesService} + */ +public class RestconfModulesServiceImpl implements RestconfModulesService { + + private static final Logger LOG = LoggerFactory.getLogger(RestconfModulesServiceImpl.class); + private final SchemaContextHandler schemaContextHandler; + + /** + * Set {@link SchemaContextHandler} for getting actual {@link SchemaContext} + * + * @param schemaContextHandler + * - handling schema context + */ + public RestconfModulesServiceImpl(final SchemaContextHandler schemaContextHandler) { + this.schemaContextHandler = schemaContextHandler; + } + + @Override + public NormalizedNodeContext getModules(final UriInfo uriInfo) { + final SchemaContextRef schemaContextRef = new SchemaContextRef(this.schemaContextHandler.getSchemaContext()); + return getModules(schemaContextRef.getModules(), schemaContextRef, null); + } + + @Override + public NormalizedNodeContext getModules(final String identifier, final UriInfo uriInfo) { + Preconditions.checkNotNull(identifier); + if (!identifier.contains(RestconfConstants.MOUNT)) { + final String errMsg = "URI has bad format. If modules behind mount point should be showed," + + " URI has to end with " + RestconfConstants.MOUNT; + LOG.debug(errMsg + " for " + identifier); + throw new RestconfDocumentedException(errMsg, ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE); + } + final SchemaContextRef schemaContextRef = new SchemaContextRef(this.schemaContextHandler.getSchemaContext()); + final DOMMountPoint mountPoint = ParserIdentifier.toInstanceIdentifier(identifier).getMountPoint(); + return getModules(schemaContextRef.getModules(mountPoint), schemaContextRef, mountPoint); + } + + + @Override + public NormalizedNodeContext getModule(final String identifier, final UriInfo uriInfo) { + Preconditions.checkNotNull(identifier); + final SchemaContextRef schemaContextRef = new SchemaContextRef(this.schemaContextHandler.getSchemaContext()); + final QName moduleQname = ParserIdentifier.makeQNameFromIdentifier(identifier); + Module module = null; + DOMMountPoint mountPoint = null; + if (identifier.contains(RestconfConstants.MOUNT)) { + mountPoint = ParserIdentifier.toInstanceIdentifier(identifier).getMountPoint(); + module = schemaContextRef.findModuleInMountPointByQName(mountPoint, moduleQname); + } else { + module = schemaContextRef.findModuleByQName(moduleQname); + } + + if (module == null) { + final String errMsg = "Module with name '" + moduleQname.getLocalName() + "' and revision '" + + moduleQname.getRevision() + "' was not found."; + LOG.debug(errMsg); + throw new RestconfDocumentedException(errMsg, ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT); + } + + final Set modules = Collections.singleton(module); + final MapNode moduleMap = RestconfMappingNodeUtil + .restconfMappingNode(schemaContextRef.getRestconfModule(), modules); + final DataSchemaNode moduleSchemaNode = RestconfSchemaUtil.getRestconfSchemaNode( + schemaContextRef.getRestconfModule(), Draft11.RestconfModule.MODULE_LIST_SCHEMA_NODE); + Preconditions.checkState(moduleSchemaNode instanceof ListSchemaNode); + return new NormalizedNodeContext( + new InstanceIdentifierContext<>(null, moduleSchemaNode, mountPoint, schemaContextRef.get()), moduleMap); + } + + /** + * Get {@link NormalizedNodeContext} from set of modules. Used by + * {@link #getModules(UriInfo)} and {@link #getModules(String, UriInfo)} + * + * @param modules + * - all modules + * @param schemaContextRef + * - schema context reference + * @param mountPoint + * - mount point + * @return {@link NormalizedNodeContext} + */ + private NormalizedNodeContext getModules(final Set modules, final SchemaContextRef schemaContextRef, + final DOMMountPoint mountPoint) { + final Module restconfModule = schemaContextRef.getRestconfModule(); + Preconditions.checkNotNull(restconfModule); + + final MapNode mapNodes = RestconfMappingNodeUtil.restconfMappingNode(restconfModule, modules); + final DataSchemaNode schemaNode = RestconfSchemaUtil.getRestconfSchemaNode(restconfModule, + Draft11.RestconfModule.MODULES_CONTAINER_SCHEMA_NODE); + Preconditions.checkState(schemaNode instanceof ContainerSchemaNode); + final DataContainerNodeAttrBuilder modulContainerSchemaNodeBuilder = Builders + .containerBuilder((ContainerSchemaNode) schemaNode); + modulContainerSchemaNodeBuilder.withChild(mapNodes); + + return new NormalizedNodeContext( + new InstanceIdentifierContext<>(null, schemaNode, mountPoint, schemaContextRef.get()), + modulContainerSchemaNodeBuilder.build()); + } +} diff --git a/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/rest/impl/services/RestconfOperationsServiceImpl.java b/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/rest/impl/services/RestconfOperationsServiceImpl.java new file mode 100644 index 0000000000..09a35302e5 --- /dev/null +++ b/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/rest/impl/services/RestconfOperationsServiceImpl.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.restconf.rest.impl.services; + +import javax.ws.rs.core.UriInfo; +import org.opendaylight.netconf.sal.restconf.impl.NormalizedNodeContext; +import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException; +import org.opendaylight.restconf.rest.api.schema.context.SchemaContextHandler; +import org.opendaylight.restconf.rest.api.services.RestconfOperationsService; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; + +/** + * Implementation of {@link RestconfOperationsService} + * + */ +public class RestconfOperationsServiceImpl implements RestconfOperationsService { + + private final SchemaContextHandler schemaContextHandler; + + /** + * Set {@link SchemaContextHandler} for getting actual {@link SchemaContext} + * + * @param schemaContextHandler + * - handling schema context + */ + public RestconfOperationsServiceImpl(final SchemaContextHandler schemaContextHandler) { + this.schemaContextHandler = schemaContextHandler; + } + + @Override + public NormalizedNodeContext getOperations(final UriInfo uriInfo) { + throw new RestconfDocumentedException("Not yet implemented.", new UnsupportedOperationException()); + } + + + @Override + public NormalizedNodeContext getOperations(final String identifier, final UriInfo uriInfo) { + throw new RestconfDocumentedException("Not yet implemented.", new UnsupportedOperationException()); + } + +} diff --git a/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/rest/impl/services/RestconfSchemaServiceImpl.java b/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/rest/impl/services/RestconfSchemaServiceImpl.java new file mode 100644 index 0000000000..bf30b76f3f --- /dev/null +++ b/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/rest/impl/services/RestconfSchemaServiceImpl.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.restconf.rest.impl.services; + +import org.opendaylight.netconf.md.sal.rest.schema.SchemaExportContext; +import org.opendaylight.restconf.rest.api.schema.context.SchemaContextHandler; +import org.opendaylight.restconf.rest.api.services.schema.RestconfSchemaService; +import org.opendaylight.restconf.utils.parser.ParserIdentifier; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; + +/** + * Implementation of {@link RestconfSchemaService}. + * + */ +public class RestconfSchemaServiceImpl implements RestconfSchemaService { + + private final SchemaContextHandler schemaContextHandler; + + /** + * Set {@link SchemaContextHandler} for getting actual {@link SchemaContext} + * . + * + * @param schemaContextHandler + * - handling schema context + */ + public RestconfSchemaServiceImpl(final SchemaContextHandler schemaContextHandler) { + this.schemaContextHandler = schemaContextHandler; + } + + @Override + public SchemaExportContext getSchema(final String identifier) { + final SchemaContextRef schemaContextRef = new SchemaContextRef(this.schemaContextHandler.getSchemaContext()); + return ParserIdentifier.toSchemaExportContextFromIdentifier(schemaContextRef.get(), identifier); + } +} diff --git a/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/rest/impl/services/RestconfStreamsServiceImpl.java b/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/rest/impl/services/RestconfStreamsServiceImpl.java new file mode 100644 index 0000000000..1b6365285a --- /dev/null +++ b/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/rest/impl/services/RestconfStreamsServiceImpl.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.restconf.rest.impl.services; + +import com.google.common.base.Preconditions; +import java.util.Set; +import javax.ws.rs.core.UriInfo; +import org.opendaylight.netconf.sal.restconf.impl.InstanceIdentifierContext; +import org.opendaylight.netconf.sal.restconf.impl.NormalizedNodeContext; +import org.opendaylight.netconf.sal.streams.listeners.Notificator; +import org.opendaylight.restconf.Draft11; +import org.opendaylight.restconf.rest.api.schema.context.SchemaContextHandler; +import org.opendaylight.restconf.rest.api.services.RestconfStreamsService; +import org.opendaylight.restconf.utils.mapping.RestconfMappingNodeUtil; +import org.opendaylight.restconf.utils.schema.context.RestconfSchemaUtil; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; +import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; +import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode; +import org.opendaylight.yangtools.yang.data.api.schema.MapNode; +import org.opendaylight.yangtools.yang.data.impl.schema.Builders; +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.model.api.ContainerSchemaNode; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; + +/** + * Implementation of {@link RestconfStreamsService} + * + */ +public class RestconfStreamsServiceImpl implements RestconfStreamsService { + + private final SchemaContextHandler schemaContextHandler; + + /** + * Set {@link SchemaContextHandler} for getting actual {@link SchemaContext} + * . + * + * @param schemaContextHandler + * - handling schema context + */ + public RestconfStreamsServiceImpl(final SchemaContextHandler schemaContextHandler) { + this.schemaContextHandler = schemaContextHandler; + } + + @Override + public NormalizedNodeContext getAvailableStreams(final UriInfo uriInfo) { + final SchemaContextRef schemaContextRef = new SchemaContextRef(this.schemaContextHandler.getSchemaContext()); + final Set availableStreams = Notificator.getStreamNames(); + + final DataSchemaNode streamListSchemaNode = RestconfSchemaUtil.getRestconfSchemaNode( + schemaContextRef.getRestconfModule(), Draft11.MonitoringModule.STREAM_LIST_SCHEMA_NODE); + Preconditions.checkState(streamListSchemaNode instanceof ListSchemaNode); + final CollectionNodeBuilder listStreamBuilder = Builders + .mapBuilder((ListSchemaNode) streamListSchemaNode); + + for (final String streamValue : availableStreams) { + listStreamBuilder.withChild(RestconfMappingNodeUtil.toStreamEntryNode(streamValue, streamListSchemaNode)); + } + + final DataSchemaNode streamContSchemaNode = RestconfSchemaUtil.getRestconfSchemaNode( + schemaContextRef.getRestconfModule(), Draft11.MonitoringModule.STREAMS_CONTAINER_SCHEMA_NODE); + Preconditions.checkState(streamContSchemaNode instanceof ContainerSchemaNode); + final DataContainerNodeAttrBuilder streamsContainerBuilder = Builders + .containerBuilder((ContainerSchemaNode) streamContSchemaNode); + + streamsContainerBuilder.withChild(listStreamBuilder.build()); + + return new NormalizedNodeContext( + new InstanceIdentifierContext<>(null, streamContSchemaNode, null, schemaContextRef.get()), + streamsContainerBuilder.build()); + } +} diff --git a/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/rest/impl/services/SchemaContextRef.java b/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/rest/impl/services/SchemaContextRef.java new file mode 100644 index 0000000000..b4a385e49d --- /dev/null +++ b/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/rest/impl/services/SchemaContextRef.java @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.restconf.rest.impl.services; + +import java.lang.ref.SoftReference; +import java.net.URI; +import java.util.Date; +import java.util.Set; +import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint; +import org.opendaylight.restconf.Draft11; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; + +/** + * This class creates {@link SoftReference} of actual {@link SchemaContext} + * object and even if the {@link SchemaContext} changes, this will be sticks + * reference to the old {@link SchemaContext} and provides work with the old + * {@link SchemaContext}. + * + */ +final class SchemaContextRef { + + private final SoftReference schemaContextRef; + + /** + * Create {@link SoftReference} of actual {@link SchemaContext} + * + * @param schemaContext + * - actual {@link SchemaContext} + */ + public SchemaContextRef(final SchemaContext schemaContext) { + this.schemaContextRef = new SoftReference(schemaContext); + } + + /** + * Get {@link SchemaContext} from reference + * + * @return {@link SchemaContext} + */ + public SchemaContext get() { + return this.schemaContextRef.get(); + } + + /** + * Get all modules like {@link Set} of {@link Module} from + * {@link SchemaContext} + * + * @return {@link Set} of {@link Module} + */ + public Set getModules() { + return get().getModules(); + } + + /** + * Get all modules like {@link Set} of {@link Module} from + * {@link SchemaContext} of {@link DOMMountPoint} + * + * @param mountPoint + * - mount point + * + * @return {@link Set} of {@link Module} + */ + public Set getModules(final DOMMountPoint mountPoint) { + final SchemaContext schemaContext = mountPoint == null ? null : mountPoint.getSchemaContext(); + return schemaContext == null ? null : schemaContext.getModules(); + } + + /** + * Get {@link Module} by ietf-restconf qname from + * {@link Draft09.RestconfModule} + * + * @return {@link Module} + */ + public Module getRestconfModule() { + return this.findModuleByNamespaceAndRevision(Draft11.RestconfModule.IETF_RESTCONF_QNAME.getNamespace(), + Draft11.RestconfModule.IETF_RESTCONF_QNAME.getRevision()); + } + + /** + * Find {@link Module} in {@link SchemaContext} by {@link URI} and + * {@link Date} + * + * @param namespace + * - namespace of module + * @param revision + * - revision of module + * @return {@link Module} + */ + public Module findModuleByNamespaceAndRevision(final URI namespace, final Date revision) { + return this.get().findModuleByNamespaceAndRevision(namespace, revision); + } + + + /** + * Find {@link Module} in {@link SchemaContext} of {@link DOMMountPoint} by + * {@link QName} of {@link Module} + * + * @param mountPoint + * - mount point + * @param qname + * - {@link QName} of module + * @return {@link Module} + */ + public Module findModuleInMountPointByQName(final DOMMountPoint mountPoint, final QName moduleQname) { + final SchemaContext schemaContext = mountPoint == null ? null : mountPoint.getSchemaContext(); + return schemaContext == null ? null + : schemaContext.findModuleByName(moduleQname.getLocalName(), moduleQname.getRevision()); + } + + /** + * Find {@link Module} in {@link SchemaContext} by {@link QName} + * + * @param moduleQname + * - {@link QName} of module + * @return {@link Module} + */ + public Module findModuleByQName(final QName moduleQname) { + return this.findModuleByNameAndRevision(moduleQname.getLocalName(), moduleQname.getRevision()); + } + + /** + * Find {@link Module} in {@link SchemaContext} by {@link String} localName + * and {@link Date} revision. + * + * @param localName + * - local name of module + * @param revision + * - revision of module + * @return {@link Module} + */ + public Module findModuleByNameAndRevision(final String localName, final Date revision) { + return this.get().findModuleByName(localName, revision); + } + +} diff --git a/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/utils/RestconfConstants.java b/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/utils/RestconfConstants.java index d9888a962b..bef0be9dfc 100644 --- a/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/utils/RestconfConstants.java +++ b/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/utils/RestconfConstants.java @@ -7,16 +7,21 @@ */ package org.opendaylight.restconf.utils; +import com.google.common.base.Splitter; +import java.text.SimpleDateFormat; + /** * Util class for Restconf constants. * */ -public class RestconfConstants { +public final class RestconfConstants { public static final String XML = "+xml"; public static final String JSON = "+json"; - + public static final String MOUNT = "yang-ext:mount"; public static final String IDENTIFIER = "identifier"; + public static final SimpleDateFormat REVISION_FORMAT = new SimpleDateFormat("yyyy-MM-dd"); + public static final Splitter SLASH_SPLITTER = Splitter.on("/"); private RestconfConstants() { throw new UnsupportedOperationException("Util class"); diff --git a/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/utils/mapping/RestconfMappingNodeConstants.java b/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/utils/mapping/RestconfMappingNodeConstants.java new file mode 100644 index 0000000000..6938af487e --- /dev/null +++ b/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/utils/mapping/RestconfMappingNodeConstants.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.restconf.utils.mapping; + +/** + * Util class for constants of mapping node + * + */ +public final class RestconfMappingNodeConstants { + + public static final String NAME = "name"; + public static final String REVISION = "revision"; + public static final String NAMESPACE = "namespace"; + public static final String FEATURE = "feature"; + public static final String DESCRIPTION = "description"; + public static final String REPLAY_SUPPORT = "replay-support"; + public static final String REPLAY_LOG = "replay-log-creation-time"; + public static final String EVENTS = "events"; + + private RestconfMappingNodeConstants() { + throw new UnsupportedOperationException("Util class."); + } +} diff --git a/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/utils/mapping/RestconfMappingNodeUtil.java b/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/utils/mapping/RestconfMappingNodeUtil.java new file mode 100644 index 0000000000..939f3ac755 --- /dev/null +++ b/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/utils/mapping/RestconfMappingNodeUtil.java @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.restconf.utils.mapping; + +import com.google.common.base.Preconditions; +import java.util.Collection; +import java.util.Set; +import org.opendaylight.restconf.Draft11; +import org.opendaylight.restconf.utils.RestconfConstants; +import org.opendaylight.restconf.utils.schema.context.RestconfSchemaUtil; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates; +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; +import org.opendaylight.yangtools.yang.data.impl.schema.Builders; +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.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.FeatureDefinition; +import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode; +import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; +import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; +import org.opendaylight.yangtools.yang.model.api.Module; + +/** + * Util class for mapping nodes + * + */ +public final class RestconfMappingNodeUtil { + + private RestconfMappingNodeUtil() { + throw new UnsupportedOperationException("Util class"); + } + + /** + * Mapping {@link Module} from {@link Set} of {@link Module} to + * {@link ListSchemaNode} of {@link Module} list. + * + * @param restconfModule + * - restconf module + * @param modules + * - all modules + * @return {@link MapNode} + */ + public static MapNode restconfMappingNode(final Module restconfModule, final Set modules) { + final DataSchemaNode modulListSchemaNode = RestconfSchemaUtil.getRestconfSchemaNode(restconfModule, + Draft11.RestconfModule.MODULE_LIST_SCHEMA_NODE); + Preconditions.checkState(modulListSchemaNode instanceof ListSchemaNode); + + final CollectionNodeBuilder listModuleBuilder = Builders + .mapBuilder((ListSchemaNode) modulListSchemaNode); + for (final Module module : modules) { + listModuleBuilder.withChild(toModuleEntryNode(module, modulListSchemaNode)); + } + return listModuleBuilder.build(); + } + + /** + * Mapping {@link MapEntryNode} entries of {@link Module} to + * {@link ListSchemaNode}. + * + * @param module + * - module for mapping + * @param modulListSchemaNode + * - mapped {@link DataSchemaNode} + * @return {@link MapEntryNode} + */ + private static MapEntryNode toModuleEntryNode(final Module module, final DataSchemaNode modulListSchemaNode) { + final ListSchemaNode listSchemaNode = (ListSchemaNode) modulListSchemaNode; + final Collection childListSchemaNode = listSchemaNode.getChildNodes(); + final DataContainerNodeAttrBuilder moduleNodeValues = Builders + .mapEntryBuilder(listSchemaNode); + + // MODULE NAME SCHEMA NODE + fillListWithLeaf(listSchemaNode, moduleNodeValues, RestconfMappingNodeConstants.NAME, module.getName()); + + // MODULE REVISION SCHEMA NODE + fillListWithLeaf(listSchemaNode, moduleNodeValues, RestconfMappingNodeConstants.REVISION, + RestconfConstants.REVISION_FORMAT.format(module.getRevision())); + + // MODULE NAMESPACE SCHEMA NODE + fillListWithLeaf(listSchemaNode, moduleNodeValues, RestconfMappingNodeConstants.NAMESPACE, + module.getNamespace().toString()); + + // MODULE FEATURES SCHEMA NODES + final DataSchemaNode schemaNode = RestconfSchemaUtil.findSchemaNodeInCollection(childListSchemaNode, + RestconfMappingNodeConstants.FEATURE); + Preconditions.checkState(schemaNode instanceof LeafListSchemaNode); + final ListNodeBuilder> featureBuilder = Builders + .leafSetBuilder((LeafListSchemaNode) schemaNode); + for (final FeatureDefinition feature : module.getFeatures()) { + featureBuilder.withChild(Builders.leafSetEntryBuilder((LeafListSchemaNode) schemaNode) + .withValue(feature.getQName().getLocalName()).build()); + } + moduleNodeValues.withChild(featureBuilder.build()); + + return moduleNodeValues.build(); + } + + /** + * Mapping {@link MapEntryNode} stream entries of stream to + * {@link ListSchemaNode} + * + * @param streamName + * - stream name + * @param streamListSchemaNode + * - mapped {@link DataSchemaNode} + * @return {@link MapEntryNode} + */ + public static MapEntryNode toStreamEntryNode(final String streamName, final DataSchemaNode streamListSchemaNode) { + Preconditions.checkState(streamListSchemaNode instanceof ListSchemaNode); + final ListSchemaNode listStreamSchemaNode = (ListSchemaNode) streamListSchemaNode; + final DataContainerNodeAttrBuilder streamNodeValues = Builders + .mapEntryBuilder(listStreamSchemaNode); + + // STREAM NAME + fillListWithLeaf(listStreamSchemaNode, streamNodeValues, RestconfMappingNodeConstants.NAME, streamName); + + // STREAM DESCRIPTION + fillListWithLeaf(listStreamSchemaNode, streamNodeValues, RestconfMappingNodeConstants.DESCRIPTION, + RestconfMappingStreamConstants.DESCRIPTION); + + // STREAM REPLAY_SUPPORT + fillListWithLeaf(listStreamSchemaNode, streamNodeValues, RestconfMappingNodeConstants.REPLAY_SUPPORT, + RestconfMappingStreamConstants.REPLAY_SUPPORT); + + // STREAM REPLAY_LOG + fillListWithLeaf(listStreamSchemaNode, streamNodeValues, RestconfMappingNodeConstants.REPLAY_LOG, + RestconfMappingStreamConstants.REPLAY_LOG); + + // STREAM EVENTS + fillListWithLeaf(listStreamSchemaNode, streamNodeValues, RestconfMappingNodeConstants.EVENTS, + RestconfMappingStreamConstants.EVENTS); + + return streamNodeValues.build(); + } + + /** + * Method for filling {@link ListSchemaNode} with {@link LeafSchemaNode} + * + * @param listStreamSchemaNode + * - {@link ListSchemaNode} + * @param streamNodeValues + * - filled {@link DataContainerNodeAttrBuilder} + * @param nameSchemaNode + * - name of mapped leaf + * @param value + * - value for mapped node + */ + private static void fillListWithLeaf( + final ListSchemaNode listStreamSchemaNode, + final DataContainerNodeAttrBuilder streamNodeValues, + final String nameSchemaNode, final Object value) { + final DataSchemaNode schemaNode = RestconfSchemaUtil + .findSchemaNodeInCollection(listStreamSchemaNode.getChildNodes(), nameSchemaNode); + Preconditions.checkState(schemaNode instanceof LeafSchemaNode); + streamNodeValues.withChild(Builders.leafBuilder((LeafSchemaNode) schemaNode).withValue(value).build()); + } +} diff --git a/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/utils/mapping/RestconfMappingStreamConstants.java b/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/utils/mapping/RestconfMappingStreamConstants.java new file mode 100644 index 0000000000..912dac456b --- /dev/null +++ b/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/utils/mapping/RestconfMappingStreamConstants.java @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.restconf.utils.mapping; + +/** + * Util class for mapping entry stream + * + */ +public final class RestconfMappingStreamConstants { + + public static final String DESCRIPTION = "DESCRIPTION_PLACEHOLDER"; + public static final Boolean REPLAY_SUPPORT = Boolean.valueOf(true); + public static final String REPLAY_LOG = ""; + public static final String EVENTS = ""; + + private RestconfMappingStreamConstants() { + throw new UnsupportedOperationException("Util class"); + } +} diff --git a/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/utils/parser/ParserIdentifier.java b/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/utils/parser/ParserIdentifier.java new file mode 100644 index 0000000000..355b9a31d5 --- /dev/null +++ b/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/utils/parser/ParserIdentifier.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.restconf.utils.parser; + +import com.google.common.base.Splitter; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import java.text.ParseException; +import java.util.Date; +import java.util.Iterator; +import java.util.List; +import org.opendaylight.netconf.md.sal.rest.schema.SchemaExportContext; +import org.opendaylight.netconf.sal.restconf.impl.InstanceIdentifierContext; +import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException; +import org.opendaylight.netconf.sal.restconf.impl.RestconfError.ErrorTag; +import org.opendaylight.netconf.sal.restconf.impl.RestconfError.ErrorType; +import org.opendaylight.restconf.utils.RestconfConstants; +import org.opendaylight.restconf.utils.validation.RestconfValidation; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Util class for parsing identifier + * + */ +public final class ParserIdentifier { + + private static final Logger LOG = LoggerFactory.getLogger(ParserIdentifier.class); + + public static InstanceIdentifierContext toInstanceIdentifier(final String identifier) { + throw new UnsupportedOperationException("Not yet implemented"); + } + + /** + * Make a {@link QName} from identifier + * + * @param identifier + * - path parameter + * @return {@link QName} + */ + public static QName makeQNameFromIdentifier(final String identifier) { + final int mountIndex = identifier.indexOf(RestconfConstants.MOUNT); + String moduleNameAndRevision = ""; + if (mountIndex >= 0) { + moduleNameAndRevision = identifier.substring(mountIndex + RestconfConstants.MOUNT.length()); + } else { + moduleNameAndRevision = identifier; + } + + final Splitter splitter = Splitter.on("/").omitEmptyStrings(); + final Iterable split = splitter.split(moduleNameAndRevision); + final List pathArgs = Lists. newArrayList(split); + if (pathArgs.size() < 2) { + LOG.debug("URI has bad format. It should be \'moduleName/yyyy-MM-dd\' " + identifier); + throw new RestconfDocumentedException( + "URI has bad format. End of URI should be in format \'moduleName/yyyy-MM-dd\'", ErrorType.PROTOCOL, + ErrorTag.INVALID_VALUE); + } + + try { + final String moduleName = pathArgs.get(0); + final String revision = pathArgs.get(1); + final Date moduleRevision = RestconfConstants.REVISION_FORMAT.parse(revision); + + return QName.create(null, moduleRevision, moduleName); + } catch (final ParseException e) { + LOG.debug("URI has bad format. It should be \'moduleName/yyyy-MM-dd\' " + identifier); + throw new RestconfDocumentedException("URI has bad format. It should be \'moduleName/yyyy-MM-dd\'", + ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE); + } + } + + /** + * Parsing {@link Module} module by {@link String} module name and + * {@link Date} revision and from the parsed module create + * {@link SchemaExportContext} + * + * @param schemaContext + * - {@link SchemaContext} + * @param identifier + * - path parameter + * @return {@link SchemaExportContext} + */ + public static SchemaExportContext toSchemaExportContextFromIdentifier(final SchemaContext schemaContext, + final String identifier) { + final Iterable pathComponents = RestconfConstants.SLASH_SPLITTER.split(identifier); + final Iterator componentIter = pathComponents.iterator(); + if (!Iterables.contains(pathComponents, RestconfConstants.MOUNT)) { + final String moduleName = RestconfValidation.validateAndGetModulName(componentIter); + final Date revision = RestconfValidation.validateAndGetRevision(componentIter); + final Module module = schemaContext.findModuleByName(moduleName, revision); + return new SchemaExportContext(schemaContext, module); + } else { + final StringBuilder pathBuilder = new StringBuilder(); + while (componentIter.hasNext()) { + final String current = componentIter.next(); + if (pathBuilder.length() != 0) { + pathBuilder.append("/"); + } + pathBuilder.append(current); + if (RestconfConstants.MOUNT.equals(current)) { + break; + } + } + final InstanceIdentifierContext mountPoint = ParserIdentifier + .toInstanceIdentifier(pathBuilder.toString()); + final String moduleName = RestconfValidation.validateAndGetModulName(componentIter); + final Date revision = RestconfValidation.validateAndGetRevision(componentIter); + final Module module = mountPoint.getSchemaContext().findModuleByName(moduleName, revision); + return new SchemaExportContext(mountPoint.getSchemaContext(), module); + } + } +} diff --git a/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/utils/schema/context/RestconfSchemaUtil.java b/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/utils/schema/context/RestconfSchemaUtil.java new file mode 100644 index 0000000000..fbeb7d9383 --- /dev/null +++ b/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/utils/schema/context/RestconfSchemaUtil.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.restconf.utils.schema.context; + +import com.google.common.base.Preconditions; +import java.util.Collection; +import java.util.Set; +import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException; +import org.opendaylight.netconf.sal.restconf.impl.RestconfError.ErrorTag; +import org.opendaylight.netconf.sal.restconf.impl.RestconfError.ErrorType; +import org.opendaylight.restconf.Draft11; +import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.GroupingDefinition; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.SchemaNode; + +/** + * Util class for finding {@link DataSchemaNode}. + * + */ +public final class RestconfSchemaUtil { + + private RestconfSchemaUtil() { + throw new UnsupportedOperationException("Util class"); + } + + /** + * Get {@link DataSchemaNode} from {@link Module} Restconf module by + * {@link String} schema node name. + * + * @param restconfModule + * - restconf module + * @param schemaNodeName + * - schema node name + * @return {@link DataSchemaNode} + */ + public static DataSchemaNode getRestconfSchemaNode(final Module restconfModule, final String schemaNodeName) { + + final Set groupings = restconfModule.getGroupings(); + final GroupingDefinition restGroup = findSchemaNodeInCollection(groupings, + Draft11.RestconfModule.RESTCONF_GROUPING_SCHEMA_NODE); + final Collection childNodes = restGroup.getChildNodes(); + final DataSchemaNode restCont = childNodes.iterator().next(); + + return findSchemaNode(restCont, schemaNodeName); + } + + /** + * Find specific {@link DataSchemaNode} child in {@link DataNodeContainer} + * by {@link String} schema node name. + * + * @param restCont + * - restconf container + * @param schemaNodeName + * - schema node name + * @return {@link DataSchemaNode} + */ + private static DataSchemaNode findSchemaNode(final DataSchemaNode restCont, final String schemaNodeName) { + switch (schemaNodeName) { + //MODULES + case Draft11.RestconfModule.MODULE_LIST_SCHEMA_NODE: + final DataSchemaNode moduleListSchNode = findSchemaNodeInCollection( + ((DataNodeContainer) findSchemaNode(restCont, + Draft11.RestconfModule.MODULES_CONTAINER_SCHEMA_NODE)).getChildNodes(), + Draft11.RestconfModule.MODULE_LIST_SCHEMA_NODE); + Preconditions.checkNotNull(moduleListSchNode); + return moduleListSchNode; + case Draft11.RestconfModule.MODULES_CONTAINER_SCHEMA_NODE: + final DataSchemaNode modulesContSchNode = findSchemaNodeInCollection(((DataNodeContainer) restCont).getChildNodes(), + Draft11.RestconfModule.MODULES_CONTAINER_SCHEMA_NODE); + Preconditions.checkNotNull(modulesContSchNode); + return modulesContSchNode; + + //STREAMS + case Draft11.MonitoringModule.STREAM_LIST_SCHEMA_NODE: + final DataSchemaNode streamListSchNode = findSchemaNodeInCollection( + ((DataNodeContainer) findSchemaNode(restCont, + Draft11.MonitoringModule.STREAMS_CONTAINER_SCHEMA_NODE)).getChildNodes(), + Draft11.MonitoringModule.STREAM_LIST_SCHEMA_NODE); + Preconditions.checkNotNull(streamListSchNode); + return streamListSchNode; + case Draft11.MonitoringModule.STREAMS_CONTAINER_SCHEMA_NODE: + final DataSchemaNode streamsContSchNode = findSchemaNodeInCollection( + ((DataNodeContainer) restCont).getChildNodes(), + Draft11.MonitoringModule.STREAMS_CONTAINER_SCHEMA_NODE); + Preconditions.checkNotNull(streamsContSchNode); + return streamsContSchNode; + default: + throw new RestconfDocumentedException("Schema node " + schemaNodeName + " does not exist in module.", + ErrorType.PROTOCOL, ErrorTag.DATA_MISSING); + } + } + + /** + * Find child of {@link SchemaNode} in {@link Collection} by {@link String} + * schema node name. + * + * @param + * - child of SchemaNode + * @param collection + * - child of node + * @param schemaNodeName + * - schema node name + * @return {@link SchemaNode} + */ + public static T findSchemaNodeInCollection(final Collection collection, + final String schemaNodeName) { + for (final T child : collection) { + if (child.getQName().getLocalName().equals(schemaNodeName)) { + return child; + } + } + throw new RestconfDocumentedException("Schema node " + schemaNodeName + " does not exist in module.", + ErrorType.PROTOCOL, ErrorTag.DATA_MISSING); + } + +} diff --git a/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/utils/validation/RestconfValidation.java b/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/utils/validation/RestconfValidation.java new file mode 100644 index 0000000000..d688a8f9a6 --- /dev/null +++ b/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/utils/validation/RestconfValidation.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.restconf.utils.validation; + +import java.text.ParseException; +import java.util.Date; +import java.util.Iterator; +import org.opendaylight.netconf.md.sal.rest.common.RestconfValidationUtils; +import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException; +import org.opendaylight.netconf.sal.restconf.impl.RestconfError.ErrorTag; +import org.opendaylight.netconf.sal.restconf.impl.RestconfError.ErrorType; +import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil; + +/** + * Util class for validations + * + */ +public final class RestconfValidation { + + private RestconfValidation() { + throw new UnsupportedOperationException("Util class."); + } + + /** + * Validation and parsing of revision. + * + * @param revisionDate + * - iterator + * @return {@link Date} + */ + public static Date validateAndGetRevision(final Iterator revisionDate) { + RestconfValidationUtils.checkDocumentedError(revisionDate.hasNext(), ErrorType.PROTOCOL, + ErrorTag.INVALID_VALUE, "Revision date must be supplied."); + try { + return SimpleDateFormatUtil.getRevisionFormat().parse(revisionDate.next()); + } catch (final ParseException e) { + throw new RestconfDocumentedException("Supplied revision is not in expected date format YYYY-mm-dd", e); + } + } + + /** + * Validation of name. + * + * @param moduleName + * - iterator + * @return {@link String} + */ + public static String validateAndGetModulName(final Iterator moduleName) { + RestconfValidationUtils.checkDocumentedError(moduleName.hasNext(), ErrorType.PROTOCOL, + ErrorTag.INVALID_VALUE, "Module name must be supplied."); + return moduleName.next(); + } + +}