import org.opendaylight.netconf.sal.restconf.impl.PATCHContext;
import org.opendaylight.netconf.sal.restconf.impl.PATCHStatusContext;
import org.opendaylight.restconf.base.services.api.RestconfOperationsService;
-import org.opendaylight.restconf.base.services.api.RestconfStreamsService;
import org.opendaylight.restconf.restful.services.api.RestconfDataService;
import org.opendaylight.restconf.restful.services.api.RestconfInvokeOperationsService;
/**
* @deprecated do not use this method. It will be replaced by
- * {@link RestconfStreamsService#getAvailableStreams(UriInfo)}
+ * {@link RestconfDataService#readData(String, UriInfo)}
*/
@Deprecated
@GET
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
-import java.util.Collection;
import java.util.Date;
import java.util.Map;
import java.util.Map.Entry;
-import java.util.Random;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.regex.Pattern;
import org.json.JSONObject;
import org.json.XML;
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.dom.api.DOMDataChangeListener;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException;
+import org.opendaylight.restconf.Draft18.MonitoringModule;
+import org.opendaylight.restconf.handlers.SchemaContextHandler;
+import org.opendaylight.restconf.handlers.TransactionChainHandler;
+import org.opendaylight.restconf.parser.IdentifierCodec;
import org.opendaylight.yang.gen.v1.urn.sal.restconf.event.subscription.rev140708.NotificationOutputTypeGrouping.NotificationOutputType;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.common.QName;
private Date start = null;
private Date stop = null;
private String filter = null;
+ private TransactionChainHandler transactionChainHandler;
+ private SchemaContextHandler schemaHandler;
/**
* Creates new {@link ListenerAdapter} listener specified by path and stream
textContent.append(qName.getLocalName());
}
- /**
- * Generates new prefix which consists of four random characters <a-z>.
- *
- * @param prefixes
- * Collection of prefixes.
- * @return New prefix which consists of four random characters <a-z>.
- */
- private static String generateNewPrefix(final Collection<String> prefixes) {
- StringBuilder result = null;
- final Random random = new Random();
- do {
- result = new StringBuilder();
- for (int i = 0; i < 4; i++) {
- final int randomNumber = 0x61 + (Math.abs(random.nextInt()) % 26);
- result.append(Character.toChars(randomNumber));
- }
- } while (prefixes.contains(result.toString()));
-
- return result.toString();
- }
-
/**
* Gets path pointed to data in data store.
*
}
/**
- * Removes all subscribers and unregisters event bus change recorder form event bus.
+ * Removes all subscribers and unregisters event bus change recorder form
+ * event bus and delete data in DS
*/
public void close() throws Exception {
+ final DOMDataWriteTransaction wTx = this.transactionChainHandler.get().newWriteOnlyTransaction();
+ wTx.delete(LogicalDatastoreType.OPERATIONAL, IdentifierCodec.deserialize(MonitoringModule.PATH_TO_STREAM_WITHOUT_KEY
+ + this.path.getLastPathArgument().getNodeType().getLocalName(), this.schemaHandler.get()));
+ wTx.submit().checkedGet();
+
this.subscribers = new ConcurrentSet<>();
this.registration.close();
this.registration = null;
this.filter = filter;
}
+ /**
+ * Get output type
+ *
+ * @return outputType
+ */
+ public String getOutputType() {
+ return this.outputType.getName();
+ }
+
+ /**
+ * Transaction chain to delete data in DS on close()
+ *
+ * @param transactionChainHandler
+ * - creating new write transaction to delete data on close
+ * @param schemaHandler
+ * - for getting schema to deserialize
+ * {@link MonitoringModule#PATH_TO_STREAM_WITHOUT_KEY} to
+ * {@link YangInstanceIdentifier}
+ */
+ public void setCloseVars(final TransactionChainHandler transactionChainHandler,
+ final SchemaContextHandler schemaHandler) {
+ this.transactionChainHandler = transactionChainHandler;
+ this.schemaHandler = schemaHandler;
+ }
+
}
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.json.JSONObject;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
import org.opendaylight.controller.md.sal.dom.api.DOMNotificationListener;
import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException;
+import org.opendaylight.restconf.Draft18.MonitoringModule;
+import org.opendaylight.restconf.handlers.SchemaContextHandler;
+import org.opendaylight.restconf.handlers.TransactionChainHandler;
+import org.opendaylight.restconf.parser.IdentifierCodec;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
private DOMNotification notification;
private ListenerRegistration<DOMNotificationListener> registration;
private Set<Channel> subscribers = new ConcurrentSet<>();
+ private TransactionChainHandler transactionChainHandler;
+ private SchemaContextHandler schemaHandler;
/**
* Set path of listener and stream name, register event bus.
}
/**
- * Reset lists, close registration and unregister bus event.
+ * Reset lists, close registration and unregister bus event and delete data in DS.
*/
public void close() {
+ final DOMDataWriteTransaction wTx = this.transactionChainHandler.get().newWriteOnlyTransaction();
+ wTx.delete(LogicalDatastoreType.OPERATIONAL,
+ IdentifierCodec.deserialize(
+ MonitoringModule.PATH_TO_STREAM_WITHOUT_KEY + this.path.getLastComponent().getLocalName(),
+ this.schemaHandler.get()));
+ try {
+ wTx.submit().checkedGet();
+ } catch (final TransactionCommitFailedException e) {
+ throw new RestconfDocumentedException("Problem while deleting data from DS.", e);
+ }
+
this.subscribers = new ConcurrentSet<>();
this.registration.close();
this.registration = null;
this.stop = stop;
this.filter = filter;
}
+
+ /**
+ * Get outputType of listenere
+ *
+ * @return the outputType
+ */
+ public String getOutputType() {
+ return this.outputType;
+ }
+
+ /**
+ * Transaction chain to delete data in DS on close()
+ *
+ * @param transactionChainHandler
+ * - creating new write transaction to delete data on close
+ * @param schemaHandler
+ * - for getting schema to deserialize
+ * {@link MonitoringModule#PATH_TO_STREAM_WITHOUT_KEY} to
+ * {@link YangInstanceIdentifier}
+ */
+ public void setCloseVars(final TransactionChainHandler transactionChainHandler,
+ final SchemaContextHandler schemaHandler) {
+ this.transactionChainHandler = transactionChainHandler;
+ this.schemaHandler = schemaHandler;
+
+ }
}
public static final String NAME = "ietf-restconf-monitoring";
public static final String NAMESPACE = "urn:ietf:params:xml:ns:yang:ietf-restconf-monitoring";
public static final String REVISION = "2016-08-15";
+ public static final String PATH_TO_STREAM_WITHOUT_KEY =
+ "ietf-restconf-monitoring:restconf-state/streams/stream=";
+ public static final String PATH_TO_STREAMS = "ietf-restconf-monitoring:restconf-state/streams";
public static Date DATE = null;
public static URI URI_MODULE = null;
public static final String LEAF_LOCATION_ACCESS_NAME = "location";
public static final QName LEAF_LOCATION_ACCESS_QNAME = QName.create(MODULE_QNAME, LEAF_LOCATION_ACCESS_NAME);
- // TODO remove after implement ietf-restconf monitoring
- public static final String STREAMS_CONTAINER_SCHEMA_NODE = "streams";
- public static final String STREAM_LIST_SCHEMA_NODE = "stream";
-
/**
* Constants for capabilities
*/
* Wrapper for all base services:
* <ul>
* <li>{@link RestconfOperationsService}
- * <li>{@link RestconfStreamsService}
* <li>{@link RestconfSchemaService}
* </ul>
*
*/
-public interface BaseServicesWrapper extends RestconfOperationsService, RestconfStreamsService, RestconfSchemaService {
+public interface BaseServicesWrapper extends RestconfOperationsService, RestconfSchemaService {
}
+++ /dev/null
-/*
- * 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.base.services.api;
-
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.UriInfo;
-import org.opendaylight.netconf.sal.restconf.impl.NormalizedNodeContext;
-import org.opendaylight.restconf.Draft18;
-import org.opendaylight.restconf.utils.RestconfConstants;
-
-/**
- * Container that provides access to the event notification streams supported by
- * the server.
- *
- */
-public interface RestconfStreamsService {
-
- /**
- * List of streams supported by the server.
- *
- * @param uriInfo
- * - URI information
- * @return {@link NormalizedNodeContext}
- */
- @GET
- @Path("data/ietf-restconf-monitoring:restconf-state/streams")
- @Produces({ Draft18.MediaTypes.DATA + RestconfConstants.JSON, Draft18.MediaTypes.DATA, MediaType.APPLICATION_JSON,
- MediaType.APPLICATION_XML, MediaType.TEXT_XML })
- public NormalizedNodeContext getAvailableStreams(@Context UriInfo uriInfo);
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.base.services.impl;
-
-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.Draft18;
-import org.opendaylight.restconf.base.services.api.RestconfStreamsService;
-import org.opendaylight.restconf.common.references.SchemaContextRef;
-import org.opendaylight.restconf.handlers.SchemaContextHandler;
-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.get());
- final Set<String> availableStreams = Notificator.getStreamNames();
-
- final DataSchemaNode streamListSchemaNode = RestconfSchemaUtil.getRestconfSchemaNode(
- schemaContextRef.getRestconfModule(), Draft18.MonitoringModule.STREAM_LIST_SCHEMA_NODE);
- Preconditions.checkState(streamListSchemaNode instanceof ListSchemaNode);
- final CollectionNodeBuilder<MapEntryNode, MapNode> listStreamBuilder = Builders
- .mapBuilder((ListSchemaNode) streamListSchemaNode);
-
- for (final String streamValue : availableStreams) {
- listStreamBuilder.withChild(RestconfMappingNodeUtil.toStreamEntryNode(streamValue, streamListSchemaNode));
- }
-
- final DataSchemaNode streamContSchemaNode = RestconfSchemaUtil.getRestconfSchemaNode(
- schemaContextRef.getRestconfModule(), Draft18.MonitoringModule.STREAMS_CONTAINER_SCHEMA_NODE);
- Preconditions.checkState(streamContSchemaNode instanceof ContainerSchemaNode);
- final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> streamsContainerBuilder = Builders
- .containerBuilder((ContainerSchemaNode) streamContSchemaNode);
-
- streamsContainerBuilder.withChild(listStreamBuilder.build());
-
- return new NormalizedNodeContext(
- new InstanceIdentifierContext<>(null, streamContSchemaNode, null, schemaContextRef.get()),
- streamsContainerBuilder.build());
- }
-}
import org.opendaylight.restconf.base.services.api.BaseServicesWrapper;
import org.opendaylight.restconf.base.services.api.RestconfOperationsService;
import org.opendaylight.restconf.base.services.api.RestconfSchemaService;
-import org.opendaylight.restconf.base.services.api.RestconfStreamsService;
import org.opendaylight.restconf.base.services.impl.RestconfOperationsServiceImpl;
import org.opendaylight.restconf.base.services.impl.RestconfSchemaServiceImpl;
-import org.opendaylight.restconf.base.services.impl.RestconfStreamsServiceImpl;
import org.opendaylight.restconf.handlers.DOMDataBrokerHandler;
import org.opendaylight.restconf.handlers.DOMMountPointServiceHandler;
import org.opendaylight.restconf.handlers.NotificationServiceHandler;
private RestconfInvokeOperationsService delegRestconfInvokeOpsService;
private RestconfStreamsSubscriptionService delegRestconfSubscrService;
private RestconfOperationsService delegRestOpsService;
- private RestconfStreamsService delegRestStrsService;
private RestconfSchemaService delegRestSchService;
private ServicesWrapperImpl() {
return this.delegRestOpsService.getOperations(identifier, uriInfo);
}
- @Override
- public NormalizedNodeContext getAvailableStreams(final UriInfo uriInfo) {
- return this.delegRestStrsService.getAvailableStreams(uriInfo);
- }
-
@Override
public SchemaExportContext getSchema(final String mountAndModuleId) {
return this.delegRestSchService.getSchema(mountAndModuleId);
final RpcServiceHandler rpcServiceHandler, final NotificationServiceHandler notificationServiceHandler) {
this.delegRestOpsService = new RestconfOperationsServiceImpl(schemaCtxHandler, domMountPointServiceHandler);
this.delegRestSchService = new RestconfSchemaServiceImpl(schemaCtxHandler, domMountPointServiceHandler);
- this.delegRestStrsService = new RestconfStreamsServiceImpl(schemaCtxHandler);
this.delegRestconfDataService = new RestconfDataServiceImpl(schemaCtxHandler, transactionChainHandler,
domMountPointServiceHandler);
this.delegRestconfInvokeOpsService = new RestconfInvokeOperationsServiceImpl(rpcServiceHandler,
schemaCtxHandler);
this.delegRestconfSubscrService =
new RestconfStreamsSubscriptionServiceImpl(domDataBrokerHandler, notificationServiceHandler,
- schemaCtxHandler);
+ schemaCtxHandler, transactionChainHandler);
}
}
import org.opendaylight.restconf.handlers.DOMDataBrokerHandler;
import org.opendaylight.restconf.handlers.NotificationServiceHandler;
import org.opendaylight.restconf.handlers.SchemaContextHandler;
+import org.opendaylight.restconf.handlers.TransactionChainHandler;
import org.opendaylight.restconf.restful.services.api.RestconfStreamsSubscriptionService;
import org.opendaylight.restconf.restful.utils.RestconfStreamsConstants;
import org.opendaylight.restconf.restful.utils.SubscribeToStreamUtil;
private final SchemaContextHandler schemaHandler;
+ private final TransactionChainHandler transactionChainHandler;
+
public RestconfStreamsSubscriptionServiceImpl(final DOMDataBrokerHandler domDataBrokerHandler,
- final NotificationServiceHandler notificationServiceHandler, final SchemaContextHandler schemaHandler) {
+ final NotificationServiceHandler notificationServiceHandler, final SchemaContextHandler schemaHandler,
+ final TransactionChainHandler transactionChainHandler) {
this.domDataBrokerHandler = domDataBrokerHandler;
this.notificationServiceHandler = notificationServiceHandler;
this.schemaHandler = schemaHandler;
+ this.transactionChainHandler = transactionChainHandler;
}
@Override
URI response = null;
if (identifier.contains(RestconfStreamsConstants.DATA_SUBSCR)) {
response =
- SubscribeToStreamUtil.dataSubs(identifier, uriInfo, start, stop, this.domDataBrokerHandler, filter);
+ SubscribeToStreamUtil.notifiDataStream(identifier, uriInfo, start, stop, this.domDataBrokerHandler, filter,
+ this.transactionChainHandler, this.schemaHandler);
} else if (identifier.contains(RestconfStreamsConstants.NOTIFICATION_STREAM)) {
- response = SubscribeToStreamUtil.notifStream(identifier, uriInfo, start, stop,
- this.notificationServiceHandler, filter);
+ response = SubscribeToStreamUtil.notifYangStream(identifier, uriInfo, start, stop,
+ this.notificationServiceHandler, filter, this.transactionChainHandler, this.schemaHandler);
}
if (response != null) {
return null;
}
- return StreamUtil.resolveEnum(clazz, (String) value);
+ return ResolveEnumUtil.resolveEnum(clazz, (String) value);
}
private static YangInstanceIdentifier preparePath(final ContainerNode data, final QName qName) {
package org.opendaylight.restconf.restful.utils;
/**
- * Common util class for stream
- * <ul>
- * <li>{@link SubscribeToStreamUtil}
- * <li>{@link CreateStreamUtil}
- * </ul>
+ * Common util class for resolve enum from String
*
*/
-public final class StreamUtil {
+public final class ResolveEnumUtil {
- private StreamUtil() {
+ private ResolveEnumUtil() {
throw new UnsupportedOperationException("Util class");
}
import javax.ws.rs.core.UriInfo;
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
import org.opendaylight.controller.md.sal.dom.api.DOMDataChangeListener;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
import org.opendaylight.controller.md.sal.dom.api.DOMNotificationListener;
import org.opendaylight.netconf.sal.restconf.impl.InstanceIdentifierContext;
import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException;
import org.opendaylight.netconf.sal.streams.listeners.NotificationListenerAdapter;
import org.opendaylight.netconf.sal.streams.listeners.Notificator;
import org.opendaylight.netconf.sal.streams.websockets.WebSocketServer;
+import org.opendaylight.restconf.Draft18.MonitoringModule;
import org.opendaylight.restconf.handlers.DOMDataBrokerHandler;
import org.opendaylight.restconf.handlers.NotificationServiceHandler;
import org.opendaylight.restconf.handlers.SchemaContextHandler;
+import org.opendaylight.restconf.handlers.TransactionChainHandler;
+import org.opendaylight.restconf.parser.IdentifierCodec;
import org.opendaylight.restconf.utils.RestconfConstants;
+import org.opendaylight.restconf.utils.mapping.RestconfMappingNodeUtil;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.SchemaNode;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
import org.slf4j.Logger;
* - string of enum value
* @return enum
*/
- public static <T> T parseURIEnum(final Class<T> clazz, final String value) {
+ private static <T> T parseURIEnum(final Class<T> clazz, final String value) {
if ((value == null) || value.equals("")) {
return null;
}
- return StreamUtil.resolveEnum(clazz, value);
+ return ResolveEnumUtil.resolveEnum(clazz, value);
}
/**
}
/**
- * Register listeners by streamName in identifier to listen to yang notifications
+ * Register listeners by streamName in identifier to listen to yang
+ * notifications, put or delete info about listener to DS according to
+ * ietf-restconf-monitoring
*
* @param identifier
* - identifier as stream name
* - DOMNotificationService handler for register listeners
* @param filter
* - indicate which subset of all possible events are of interest
+ * @param transactionChainHandler
+ * - to put new data about stream to DS and delete after close
+ * listener
+ * @param schemaHandler
+ * - for getting schema context
* @return location for listening
*/
- public static URI notifStream(final String identifier, final UriInfo uriInfo, final Date start, final Date stop,
- final NotificationServiceHandler notifiServiceHandler, final String filter) {
+ public static URI notifYangStream(final String identifier, final UriInfo uriInfo, Date start, final Date stop,
+ final NotificationServiceHandler notifiServiceHandler, final String filter,
+ final TransactionChainHandler transactionChainHandler, final SchemaContextHandler schemaHandler) {
final String streamName = Notificator.createStreamNameFromUri(identifier);
if (Strings.isNullOrEmpty(streamName)) {
throw new RestconfDocumentedException("Stream name is empty.", ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
ErrorTag.UNKNOWN_ELEMENT);
}
- for (final NotificationListenerAdapter listener : listeners) {
- registerToListenNotification(listener, notifiServiceHandler);
- listener.setQueryParams(start, stop, filter);
- }
-
final UriBuilder uriBuilder = uriInfo.getAbsolutePathBuilder();
int notificationPort = RestconfStreamsConstants.NOTIFICATION_PORT;
try {
final UriBuilder uriToWebsocketServerBuilder = uriBuilder.port(notificationPort).scheme("ws");
final URI uriToWebsocketServer = uriToWebsocketServerBuilder.replacePath(streamName).build();
+ final DOMDataReadWriteTransaction wTx = transactionChainHandler.get().newReadWriteTransaction();
+ final boolean exist = checkExist(schemaHandler, wTx);
+ final Module monitoringModule = schemaHandler.get()
+ .findModuleByNamespaceAndRevision(MonitoringModule.URI_MODULE, MonitoringModule.DATE);
+ if (start == null) {
+ start = new Date();
+ }
+ for (final NotificationListenerAdapter listener : listeners) {
+ registerToListenNotification(listener, notifiServiceHandler);
+ listener.setQueryParams(start, stop, filter);
+ listener.setCloseVars(transactionChainHandler, schemaHandler);
+ final NormalizedNode mapToStreams =
+ RestconfMappingNodeUtil.mapYangNotificationStreamByIetfRestconfMonitoring(listener.getSchemaPath().getLastComponent(),
+ schemaHandler.get().getNotifications(), start, listener.getOutputType(),
+ uriToWebsocketServer, monitoringModule, exist);
+ writeDataToDS(schemaHandler, listener.getSchemaPath().getLastComponent().getLocalName(), wTx, exist, mapToStreams);
+ }
+ submitData(wTx);
+
return uriToWebsocketServer;
}
+ private static boolean checkExist(final SchemaContextHandler schemaHandler, final DOMDataReadWriteTransaction wTx) {
+ boolean exist;
+ try {
+ exist = wTx
+ .exists(LogicalDatastoreType.OPERATIONAL, IdentifierCodec
+ .deserialize(MonitoringModule.PATH_TO_STREAMS, schemaHandler.get()))
+ .checkedGet();
+ } catch (final ReadFailedException e1) {
+ throw new RestconfDocumentedException("Problem while checking data if exists", e1);
+ }
+ return exist;
+ }
+
private static void registerToListenNotification(final NotificationListenerAdapter listener,
final NotificationServiceHandler notificationServiceHandler) {
if (listener.isListening()) {
}
/**
- * Register listener by streamName in identifier to listen to yang notifications
+ * Register listener by streamName in identifier to listen to data change
+ * notifications, put or delete info about listener to DS according to
+ * ietf-restconf-monitoring
*
* @param identifier
* - identifier as stream name
* - DOMDataBroker handler for register listener
* @param filter
* - indicate which subset of all possible events are of interest
+ * @param schemaHandler
+ * - for getting schema context
+ * @param transactionChainHandler
+ * - to put new data about stream to DS and delete after close
+ * listener
* @return location for listening
*/
- public static URI dataSubs(final String identifier, final UriInfo uriInfo, final Date start, final Date stop,
- final DOMDataBrokerHandler domDataBrokerHandler, final String filter) {
+ public static URI notifiDataStream(final String identifier, final UriInfo uriInfo, Date start, final Date stop,
+ final DOMDataBrokerHandler domDataBrokerHandler, final String filter,
+ final TransactionChainHandler transactionChainHandler, final SchemaContextHandler schemaHandler) {
final Map<String, String> mapOfValues = SubscribeToStreamUtil.mapValuesFromUri(identifier);
final LogicalDatastoreType ds = SubscribeToStreamUtil.parseURIEnum(LogicalDatastoreType.class,
final ListenerAdapter listener = Notificator.getListenerFor(streamName);
Preconditions.checkNotNull(listener, "Listener doesn't exist : " + streamName);
+ if (start == null) {
+ start = new Date();
+ }
+
listener.setQueryParams(start, stop, filter);
+ listener.setCloseVars(transactionChainHandler, schemaHandler);
SubscribeToStreamUtil.registration(ds, scope, listener, domDataBrokerHandler.get());
final UriBuilder uriBuilder = uriInfo.getAbsolutePathBuilder();
final UriBuilder uriToWebSocketServer =
uriBuilder.port(port).scheme(RestconfStreamsConstants.SCHEMA_SUBSCIBRE_URI);
- return uriToWebSocketServer.replacePath(streamName).build();
+ final URI uri = uriToWebSocketServer.replacePath(streamName).build();
+
+ final Module monitoringModule = schemaHandler.get()
+ .findModuleByNamespaceAndRevision(MonitoringModule.URI_MODULE, MonitoringModule.DATE);
+ final DOMDataReadWriteTransaction wTx = transactionChainHandler.get().newReadWriteTransaction();
+ final boolean exist = checkExist(schemaHandler, wTx);
+
+ final NormalizedNode mapToStreams = RestconfMappingNodeUtil.mapDataChangeNotificationStreamByIetfRestconfMonitoring(listener.getPath(), start,
+ listener.getOutputType(), uri, monitoringModule, exist, schemaHandler.get());
+ writeDataToDS(schemaHandler, listener.getPath().getLastPathArgument().getNodeType().getLocalName(), wTx, exist,
+ mapToStreams);
+ submitData(wTx);
+ return uri;
+ }
+
+ private static void writeDataToDS(final SchemaContextHandler schemaHandler, final String name,
+ final DOMDataReadWriteTransaction wTx, final boolean exist, final NormalizedNode mapToStreams) {
+ String pathId = "";
+ if (exist) {
+ pathId = MonitoringModule.PATH_TO_STREAM_WITHOUT_KEY + name;
+ } else {
+ pathId = MonitoringModule.PATH_TO_STREAMS;
+ }
+ wTx.merge(LogicalDatastoreType.OPERATIONAL, IdentifierCodec.deserialize(pathId, schemaHandler.get()),
+ mapToStreams);
}
+ private static void submitData(final DOMDataReadWriteTransaction wTx) {
+ try {
+ wTx.submit().checkedGet();
+ } catch (final TransactionCommitFailedException e) {
+ throw new RestconfDocumentedException("Problem while putting data to DS.", e);
+ }
+ }
+
+ /**
+ * Parse input of query parameters - start-time or stop-time - from
+ * {@link DateAndTime} format to {@link Date} format
+ *
+ * @param entry
+ * - start-time or stop-time as string in {@link DateAndTime}
+ * format
+ * @return parsed {@link Date} by entry
+ */
public static Date parseDateFromQueryParam(final Entry<String, List<String>> entry) {
final DateAndTime event = new DateAndTime(entry.getValue().iterator().next());
String numOf_ms = "";
*/
package org.opendaylight.restconf.utils.mapping;
-import com.google.common.base.Preconditions;
+import java.net.URI;
import java.text.SimpleDateFormat;
import java.util.Collection;
+import java.util.Date;
import java.util.Set;
import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException;
import org.opendaylight.restconf.Draft18.IetfYangLibrary;
import org.opendaylight.restconf.Draft18.MonitoringModule;
import org.opendaylight.restconf.Draft18.MonitoringModule.QueryParams;
-import org.opendaylight.restconf.utils.schema.context.RestconfSchemaUtil;
+import org.opendaylight.restconf.utils.parser.ParserIdentifier;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev160621.module.list.Module.ConformanceType;
import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
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.LeafSchemaNode;
import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaNode;
/**
* Util class for mapping nodes
throw new RestconfDocumentedException(qnameOfSchema.getLocalName() + " doesn't exist.");
}
- /**
- * 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<NodeIdentifierWithPredicates, MapEntryNode> 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<NodeIdentifierWithPredicates, MapEntryNode> 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());
- }
-
/**
* Map capabilites by ietf-restconf-monitoring
*
* - builder of parent for children
* @param leafListSchema
*/
- @SuppressWarnings("unchecked")
+ @SuppressWarnings({ "unchecked", "rawtypes" })
private static void fillLeafListCapa(final ListNodeBuilder builder, final LeafListSchemaNode leafListSchema) {
builder.withChild(leafListEntryBuild(leafListSchema, QueryParams.DEPTH));
builder.withChild(leafListEntryBuild(leafListSchema, QueryParams.FIELDS));
throw new RestconfDocumentedException(
childQName.getLocalName() + " doesn't exist in container " + MonitoringModule.CONT_RESTCONF_STATE_NAME);
}
+
+ /**
+ * Map data of yang notification to normalized node according to
+ * ietf-restconf-monitoring
+ *
+ * @param notifiQName
+ * - qname of notification from listener
+ * @param notifications
+ * - list of notifications for find schema of notification by
+ * notifiQName
+ * @param start
+ * - start-time query parameter of notification
+ * @param outputType
+ * - output type of notification
+ * @param uri
+ * - location of registered listener for sending data of
+ * notification
+ * @param monitoringModule
+ * - ietf-restconf-monitoring module
+ * @param existParent
+ * - true if data of parent -
+ * ietf-restconf-monitoring:restconf-state/streams - exist in DS
+ * @return mapped data of notification - map entry node if parent exists,
+ * container streams with list and map entry node if not
+ */
+ @SuppressWarnings("rawtypes")
+ public static NormalizedNode mapYangNotificationStreamByIetfRestconfMonitoring(final QName notifiQName,
+ final Set<NotificationDefinition> notifications, final Date start, final String outputType,
+ final URI uri, final Module monitoringModule, final boolean existParent) {
+ for (final NotificationDefinition notificationDefinition : notifications) {
+ if (notificationDefinition.getQName().equals(notifiQName)) {
+ final DataSchemaNode streamListSchema = ((ContainerSchemaNode) ((ContainerSchemaNode) monitoringModule
+ .getDataChildByName(MonitoringModule.CONT_RESTCONF_STATE_QNAME))
+ .getDataChildByName(MonitoringModule.CONT_STREAMS_QNAME))
+ .getDataChildByName(MonitoringModule.LIST_STREAM_QNAME);
+ final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> streamEntry =
+ Builders.mapEntryBuilder((ListSchemaNode) streamListSchema);
+
+ final ListSchemaNode listSchema = ((ListSchemaNode) streamListSchema);
+ prepareLeafAndFillEntryBuilder(streamEntry,
+ listSchema.getDataChildByName(MonitoringModule.LEAF_NAME_STREAM_QNAME),
+ notificationDefinition.getQName().getLocalName());
+ if ((notificationDefinition.getDescription() != null)
+ && !notificationDefinition.getDescription().equals("")) {
+ prepareLeafAndFillEntryBuilder(streamEntry,
+ listSchema.getDataChildByName(MonitoringModule.LEAF_DESCR_STREAM_QNAME),
+ notificationDefinition.getDescription());
+ }
+ prepareLeafAndFillEntryBuilder(streamEntry,
+ listSchema.getDataChildByName(MonitoringModule.LEAF_REPLAY_SUPP_STREAM_QNAME), true);
+ prepareLeafAndFillEntryBuilder(streamEntry,
+ listSchema.getDataChildByName(MonitoringModule.LEAF_START_TIME_STREAM_QNAME),
+ new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'XXX").format(start));
+ prepareListAndFillEntryBuilder(streamEntry,
+ (ListSchemaNode) listSchema.getDataChildByName(MonitoringModule.LIST_ACCESS_STREAM_QNAME),
+ outputType, uri);
+
+ if (!existParent) {
+ final DataSchemaNode contStreamsSchema = ((ContainerSchemaNode) monitoringModule
+ .getDataChildByName(MonitoringModule.CONT_RESTCONF_STATE_QNAME))
+ .getDataChildByName(MonitoringModule.CONT_STREAMS_QNAME);
+ return Builders.containerBuilder((ContainerSchemaNode) contStreamsSchema).withChild(Builders
+ .mapBuilder((ListSchemaNode) streamListSchema).withChild(streamEntry.build())
+ .build()).build();
+ }
+ return streamEntry.build();
+ }
+ }
+
+ throw new RestconfDocumentedException(notifiQName + " doesn't exist in any modul");
+ }
+
+ private static void prepareListAndFillEntryBuilder(
+ final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> streamEntry,
+ final ListSchemaNode listSchemaNode, final String outputType, final URI uriToWebsocketServer) {
+ final CollectionNodeBuilder<MapEntryNode, MapNode> accessListBuilder = Builders.mapBuilder(listSchemaNode);
+ final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entryAccessList =
+ Builders.mapEntryBuilder(listSchemaNode);
+ prepareLeafAndFillEntryBuilder(entryAccessList,
+ listSchemaNode.getDataChildByName(MonitoringModule.LEAF_ENCODING_ACCESS_QNAME), outputType);
+ prepareLeafAndFillEntryBuilder(entryAccessList,
+ listSchemaNode.getDataChildByName(MonitoringModule.LEAF_LOCATION_ACCESS_QNAME),
+ uriToWebsocketServer.toString());
+ streamEntry.withChild(accessListBuilder.withChild(entryAccessList.build()).build());
+ }
+
+ /**
+ * @param streamEntry
+ * @param dataChildByName
+ * @param localName
+ */
+ private static void prepareLeafAndFillEntryBuilder(
+ final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> streamEntry,
+ final DataSchemaNode leafSchema, final Object value) {
+ streamEntry.withChild(Builders.leafBuilder((LeafSchemaNode) leafSchema).withValue(value).build());
+ }
+
+ /**
+ * Map data of data change notification to normalized node according to
+ * ietf-restconf-monitoring
+ *
+ * @param path
+ * - path of data to listen on
+ * @param start
+ * - start-time query parameter of notification
+ * @param outputType
+ * - output type of notification
+ * @param uri
+ * - location of registered listener for sending data of
+ * notification
+ * @param monitoringModule
+ * - ietf-restconf-monitoring module
+ * @param existParent
+ * - true if data of parent -
+ * ietf-restconf-monitoring:restconf-state/streams - exist in DS
+ * @param schemaContext
+ * - schemaContext for parsing instance identifier to get schema
+ * node of data
+ * @return mapped data of notification - map entry node if parent exists,
+ * container streams with list and map entry node if not
+ */
+ @SuppressWarnings("rawtypes")
+ public static NormalizedNode mapDataChangeNotificationStreamByIetfRestconfMonitoring(
+ final YangInstanceIdentifier path, final Date start,
+ final String outputType, final URI uri, final Module monitoringModule, final boolean existParent,
+ final SchemaContext schemaContext) {
+ final SchemaNode schemaNode = ParserIdentifier
+ .toInstanceIdentifier(ParserIdentifier.stringFromYangInstanceIdentifier(path, schemaContext),
+ schemaContext, null)
+ .getSchemaNode();
+ final DataSchemaNode streamListSchema = ((ContainerSchemaNode) ((ContainerSchemaNode) monitoringModule
+ .getDataChildByName(MonitoringModule.CONT_RESTCONF_STATE_QNAME))
+ .getDataChildByName(MonitoringModule.CONT_STREAMS_QNAME))
+ .getDataChildByName(MonitoringModule.LIST_STREAM_QNAME);
+ final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> streamEntry =
+ Builders.mapEntryBuilder((ListSchemaNode) streamListSchema);
+
+ final ListSchemaNode listSchema = ((ListSchemaNode) streamListSchema);
+ prepareLeafAndFillEntryBuilder(streamEntry,
+ listSchema.getDataChildByName(MonitoringModule.LEAF_NAME_STREAM_QNAME),
+ schemaNode.getQName().getLocalName());
+ if ((schemaNode.getDescription() != null) && !schemaNode.getDescription().equals("")) {
+ prepareLeafAndFillEntryBuilder(streamEntry,
+ listSchema.getDataChildByName(MonitoringModule.LEAF_DESCR_STREAM_QNAME),
+ schemaNode.getDescription());
+ }
+ prepareLeafAndFillEntryBuilder(streamEntry,
+ listSchema.getDataChildByName(MonitoringModule.LEAF_REPLAY_SUPP_STREAM_QNAME), true);
+ prepareLeafAndFillEntryBuilder(streamEntry,
+ listSchema.getDataChildByName(MonitoringModule.LEAF_START_TIME_STREAM_QNAME),
+ new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'XXX").format(start));
+ prepareListAndFillEntryBuilder(streamEntry,
+ (ListSchemaNode) listSchema.getDataChildByName(MonitoringModule.LIST_ACCESS_STREAM_QNAME), outputType,
+ uri);
+
+ if (!existParent) {
+ final DataSchemaNode contStreamsSchema = ((ContainerSchemaNode) monitoringModule
+ .getDataChildByName(MonitoringModule.CONT_RESTCONF_STATE_QNAME))
+ .getDataChildByName(MonitoringModule.CONT_STREAMS_QNAME);
+ return Builders
+ .containerBuilder((ContainerSchemaNode) contStreamsSchema).withChild(Builders
+ .mapBuilder((ListSchemaNode) streamListSchema).withChild(streamEntry.build()).build())
+ .build();
+ }
+ return streamEntry.build();
+ }
}
*/
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.Draft18;
-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;
/**
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<GroupingDefinition> groupings = restconfModule.getGroupings();
- final GroupingDefinition restGroup = findSchemaNodeInCollection(groupings,
- Draft18.RestconfModule.RESTCONF_GROUPING_SCHEMA_NODE);
- final Collection<DataSchemaNode> 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 Draft18.RestconfModule.MODULE_LIST_SCHEMA_NODE:
- final DataSchemaNode moduleListSchNode = findSchemaNodeInCollection(
- ((DataNodeContainer) findSchemaNode(restCont,
- Draft18.RestconfModule.MODULES_CONTAINER_SCHEMA_NODE)).getChildNodes(),
- Draft18.RestconfModule.MODULE_LIST_SCHEMA_NODE);
- Preconditions.checkNotNull(moduleListSchNode);
- return moduleListSchNode;
- case Draft18.RestconfModule.MODULES_CONTAINER_SCHEMA_NODE:
- final DataSchemaNode modulesContSchNode = findSchemaNodeInCollection(((DataNodeContainer) restCont).getChildNodes(),
- Draft18.RestconfModule.MODULES_CONTAINER_SCHEMA_NODE);
- Preconditions.checkNotNull(modulesContSchNode);
- return modulesContSchNode;
-
- //STREAMS
- case Draft18.MonitoringModule.STREAM_LIST_SCHEMA_NODE:
- final DataSchemaNode streamListSchNode = findSchemaNodeInCollection(
- ((DataNodeContainer) findSchemaNode(restCont,
- Draft18.MonitoringModule.STREAMS_CONTAINER_SCHEMA_NODE)).getChildNodes(),
- Draft18.MonitoringModule.STREAM_LIST_SCHEMA_NODE);
- Preconditions.checkNotNull(streamListSchNode);
- return streamListSchNode;
- case Draft18.MonitoringModule.STREAMS_CONTAINER_SCHEMA_NODE:
- final DataSchemaNode streamsContSchNode = findSchemaNodeInCollection(
- ((DataNodeContainer) restCont).getChildNodes(),
- Draft18.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.
import org.junit.Test;
import org.mockito.InOrder;
import org.mockito.Mock;
+import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
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.api.DOMTransactionChain;
import org.opendaylight.controller.sal.core.api.Broker.ConsumerSession;
import org.opendaylight.netconf.sal.restconf.impl.BrokerFacade;
import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
import org.opendaylight.netconf.sal.streams.listeners.ListenerAdapter;
import org.opendaylight.netconf.sal.streams.listeners.NotificationListenerAdapter;
import org.opendaylight.netconf.sal.streams.listeners.Notificator;
+import org.opendaylight.restconf.handlers.SchemaContextHandler;
+import org.opendaylight.restconf.handlers.TransactionChainHandler;
import org.opendaylight.yang.gen.v1.urn.sal.restconf.event.subscription.rev140708.NotificationOutputTypeGrouping.NotificationOutputType;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.common.QName;
* Create, register, close and remove notification listener.
*/
@Test
- public void testRegisterToListenNotificationChanges() {
+ public void testRegisterToListenNotificationChanges() throws Exception {
// create test notification listener
final String identifier = "create-notification-stream/toaster:toastDone";
final SchemaPath path = SchemaPath.create(true,
// registrations should be invoked only once
verify(this.domNotification, times(1)).registerNotificationListener(listener, listener.getSchemaPath());
+ final DOMTransactionChain transactionChain = mock(DOMTransactionChain.class);
+ final DOMDataWriteTransaction wTx = mock(DOMDataWriteTransaction.class);
+ final CheckedFuture checked = Futures.immediateCheckedFuture("");
+ when(wTx.submit()).thenReturn(checked);
+ when(transactionChain.newWriteOnlyTransaction()).thenReturn(wTx);
+ final TransactionChainHandler transactionChainHandler = new TransactionChainHandler(transactionChain);
+ final SchemaContextHandler schemaHandler = Mockito.mock(SchemaContextHandler.class);
+ final SchemaContext schCtx = TestUtils.loadSchemaContext("/modules");
+ when(schemaHandler.get()).thenReturn(schCtx);
+ listener.setCloseVars(transactionChainHandler, schemaHandler);
// close and remove test notification listener
listener.close();
Notificator.removeNotificationListenerIfNoSubscriberExists(listener);
+++ /dev/null
-/*
- * 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.services.impl;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.when;
-import static org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.EMPTY;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import java.util.AbstractMap;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
-import org.opendaylight.netconf.sal.restconf.impl.NormalizedNodeContext;
-import org.opendaylight.netconf.sal.streams.listeners.Notificator;
-import org.opendaylight.restconf.Draft18;
-import org.opendaylight.restconf.base.services.api.RestconfStreamsService;
-import org.opendaylight.restconf.base.services.impl.RestconfStreamsServiceImpl;
-import org.opendaylight.restconf.handlers.SchemaContextHandler;
-import org.opendaylight.restconf.utils.mapping.RestconfMappingNodeConstants;
-import org.opendaylight.restconf.utils.mapping.RestconfMappingStreamConstants;
-import org.opendaylight.yang.gen.v1.urn.sal.restconf.event.subscription.rev140708.NotificationOutputTypeGrouping.NotificationOutputType;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-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.LeafNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.nodes.AbstractImmutableDataContainerAttrNode;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-
-/**
- * Unit tests for {@link RestconfStreamsServiceImpl}
- */
-public class RestconfStreamsServiceTest {
- private static final List<String> expectedStreams = Arrays.asList(new String[] {"stream-1", "stream-2", "stream-3"});
-
- @Rule public ExpectedException thrown = ExpectedException.none();
-
- @Mock private SchemaContextHandler contextHandler;
- @Mock private SchemaContext mockSchemaContext;
-
- // service under test
- private RestconfStreamsService streamsService;
-
- // schema context with testing Restconf modules
- private SchemaContext schemaContext;
-
- @Before
- public void setup() throws Exception {
- MockitoAnnotations.initMocks(this);
-
- this.schemaContext = TestRestconfUtils.loadSchemaContext("/modules/restconf-module-testing");
- this.streamsService = new RestconfStreamsServiceImpl(this.contextHandler);
- }
-
- @BeforeClass
- public static void setupTestStreams() {
- // clean
- Notificator.removeAllListeners();
-
- // put test streams
- Notificator.createListener(EMPTY, RestconfStreamsServiceTest.expectedStreams.get(0),
- NotificationOutputType.XML);
- Notificator.createListener(EMPTY, RestconfStreamsServiceTest.expectedStreams.get(1),
- NotificationOutputType.XML);
- Notificator.createListener(EMPTY, RestconfStreamsServiceTest.expectedStreams.get(2),
- NotificationOutputType.XML);
- }
-
- @AfterClass
- public static void removeTestStreams() {
- Notificator.removeAllListeners();
- }
-
- /**
- * Test of successful initialization of streams service.
- */
- @Test
- public void restconfStreamsServiceImplInitTest() {
- assertNotNull("Streams service should be initialized and not null", this.streamsService);
- }
-
- /**
- * Positive test to get all available streams supported by the server. Loaded streams are compared to expected
- * streams.
- */
- @Test
- public void getAvailableStreamsTest() throws Exception {
- // prepare conditions - get correct Restconf module
- when(this.contextHandler.get()).thenReturn(this.mockSchemaContext);
- when(this.mockSchemaContext.findModuleByNamespaceAndRevision(Draft18.RestconfModule.IETF_RESTCONF_QNAME
- .getNamespace(), Draft18.RestconfModule.IETF_RESTCONF_QNAME.getRevision()))
- .thenReturn(getTestingRestconfModule("ietf-restconf"));
-
- // make test
- final NormalizedNodeContext nodeContext = this.streamsService.getAvailableStreams(null);
-
- // verify loaded streams
- assertNotNull("Normalized node context should not be null", nodeContext);
- verifyStreams(((ContainerNode) nodeContext.getData()).getValue());
- }
-
- /**
- * Try to get all available streams supported by the server when current <code>SchemaContext</code> is
- * <code>null</code> expecting <code>NullPointerException</code>.
- */
- @Test
- public void getAvailableStreamsNullSchemaContextNegativeTest() {
- // prepare conditions - returned SchemaContext is null
- when(this.contextHandler.get()).thenReturn(null);
-
- // make test
- this.thrown.expect(NullPointerException.class);
- this.streamsService.getAvailableStreams(null);
- }
-
- /**
- * Try to get all available streams supported by the server when Restconf module is missing in
- * <code>SchemaContext</code> expecting <code>NullPointerException</code>.
- */
- @Test
- public void getAvailableStreamsMissingRestconfModuleNegativeTest() {
- // prepare conditions - get null Restconf module
- when(this.contextHandler.get()).thenReturn(this.mockSchemaContext);
- when(this.mockSchemaContext.findModuleByNamespaceAndRevision(Draft18.RestconfModule.IETF_RESTCONF_QNAME
- .getNamespace(), Draft18.RestconfModule.IETF_RESTCONF_QNAME.getRevision())).thenReturn(null);
-
- // make test
- this.thrown.expect(NullPointerException.class);
- this.streamsService.getAvailableStreams(null);
- }
-
- /**
- * There are multiple testing Restconf modules for different test cases. It is possible to distinguish them by
- * name or by namespace. This method is looking for Restconf test module by its name.
- * @param s Testing Restconf module name
- * @return Restconf module
- */
- private Module getTestingRestconfModule(final String s) {
- return this.schemaContext.findModuleByName(s, Draft18.RestconfModule.IETF_RESTCONF_QNAME.getRevision());
- }
-
- /**
- * Verify loaded streams
- * @param streams Streams to be verified
- */
- private void verifyStreams(final Collection<DataContainerChild<? extends PathArgument, ?>> streams) {
- assertNotNull("Collection of streams should not be empty", streams);
- assertFalse("Collection of streams should not be empty", Iterables.isEmpty(streams));
- final Iterator<DataContainerChild<? extends PathArgument, ?>> iterator = streams.iterator();
-
- final List<String> loadedStreams = new ArrayList<>();
- for (final Object stream : (Collection<?>) iterator.next().getValue()) {
- final Iterator mapEntries = ((AbstractImmutableDataContainerAttrNode) stream)
- .getChildren().entrySet().iterator();
-
- final List<String> allowedKeys = Lists.newArrayList(
- RestconfMappingNodeConstants.NAME,
- RestconfMappingNodeConstants.DESCRIPTION,
- RestconfMappingNodeConstants.REPLAY_SUPPORT,
- RestconfMappingNodeConstants.REPLAY_LOG,
- RestconfMappingNodeConstants.EVENTS);
-
- while (mapEntries.hasNext()) {
- final Map.Entry e = ((AbstractMap.SimpleImmutableEntry) mapEntries.next());
- final String key = ((NodeIdentifier) e.getKey()).getNodeType().getLocalName();
-
- assertTrue("Not allowed key", allowedKeys.contains(key));
-
- switch (key) {
- case RestconfMappingNodeConstants.NAME :
- loadedStreams.add((String) ((LeafNode) e.getValue()).getValue());
- break;
- case RestconfMappingNodeConstants.DESCRIPTION :
- assertEquals("Stream description value is not as expected",
- RestconfMappingStreamConstants.DESCRIPTION, ((LeafNode) e.getValue()).getValue());
- break;
- case RestconfMappingNodeConstants.REPLAY_SUPPORT :
- assertEquals("Stream replay support value is not as expected",
- RestconfMappingStreamConstants.REPLAY_SUPPORT, ((LeafNode) e.getValue()).getValue());
- break;
- case RestconfMappingNodeConstants.REPLAY_LOG :
- assertEquals("Stream replay log value is not as expected",
- RestconfMappingStreamConstants.REPLAY_LOG, ((LeafNode) e.getValue()).getValue());
- break;
- case RestconfMappingNodeConstants.EVENTS :
- assertEquals("Stream events value is not as expected",
- RestconfMappingStreamConstants.EVENTS, ((LeafNode) e.getValue()).getValue());
- break;
- }
- }
- }
-
- // sort and compare
- loadedStreams.sort((s1, s2) -> s1.compareTo(s2));
- assertEquals("Returned streams are not as expected", expectedStreams, loadedStreams);
- }
-}
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.Futures;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.HashSet;
import org.mockito.MockitoAnnotations;
import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
import org.opendaylight.controller.md.sal.dom.api.DOMDataChangeListener;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
import org.opendaylight.restconf.handlers.NotificationServiceHandler;
import org.opendaylight.restconf.handlers.SchemaContextHandler;
import org.opendaylight.restconf.handlers.TransactionChainHandler;
+import org.opendaylight.restconf.parser.IdentifierCodec;
+import org.opendaylight.yang.gen.v1.urn.sal.restconf.event.subscription.rev140708.NotificationOutputTypeGrouping.NotificationOutputType;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
public class RestconfStreamsSubscriptionServiceImplTest {
private UriInfo uriInfo;
@Mock
private NotificationServiceHandler notificationServiceHandler;
+ @Mock
+ private TransactionChainHandler transactionHandler;
private SchemaContextHandler schemaHandler;
final TransactionChainHandler txHandler = Mockito.mock(TransactionChainHandler.class);
final DOMTransactionChain domTx = Mockito.mock(DOMTransactionChain.class);
+ Mockito.when(this.transactionHandler.get()).thenReturn(domTx);
Mockito.when(txHandler.get()).thenReturn(domTx);
final DOMDataWriteTransaction wTx = Mockito.mock(DOMDataWriteTransaction.class);
Mockito.when(domTx.newWriteOnlyTransaction()).thenReturn(wTx);
+ final DOMDataReadWriteTransaction rwTx = Mockito.mock(DOMDataReadWriteTransaction.class);
+ final CheckedFuture checkedFuture = Futures.immediateCheckedFuture(true);
+ Mockito.when(rwTx.exists(Mockito.any(), Mockito.any())).thenReturn(checkedFuture);
+ final CheckedFuture checkedFutureEmpty = Futures.immediateCheckedFuture("");
+ Mockito.when(rwTx.submit()).thenReturn(checkedFutureEmpty);
+ Mockito.when(domTx.newReadWriteTransaction()).thenReturn(rwTx);
final CheckedFuture checked = Mockito.mock(CheckedFuture.class);
Mockito.when(wTx.submit()).thenReturn(checked);
final Object valueObj = null;
}
@Test
- public void testSubscribeToStream() {
+ public void testSubscribeToStream() throws Exception {
final UriBuilder uriBuilder = UriBuilder.fromUri(uri);
+ final ListenerAdapter createListener = Notificator.createListener(
+ IdentifierCodec.deserialize("toaster:toaster/toasterStatus", this.schemaHandler.get()),
+ "data-change-event-subscription/toaster:toaster/toasterStatus/datastore=OPERATIONAL/scope=ONE",
+ NotificationOutputType.XML);
doReturn(uriBuilder).when(this.uriInfo).getAbsolutePathBuilder();
final RestconfStreamsSubscriptionServiceImpl streamsSubscriptionService =
new RestconfStreamsSubscriptionServiceImpl(this.dataBrokerHandler, this.notificationServiceHandler,
- this.schemaHandler);
+ this.schemaHandler, this.transactionHandler);
final NormalizedNodeContext response = streamsSubscriptionService
.subscribeToStream(
"data-change-event-subscription/toaster:toaster/toasterStatus/datastore=OPERATIONAL/scope=ONE",
doReturn(uriBuilder).when(this.uriInfo).getAbsolutePathBuilder();
final RestconfStreamsSubscriptionServiceImpl streamsSubscriptionService =
new RestconfStreamsSubscriptionServiceImpl(this.dataBrokerHandler, this.notificationServiceHandler,
- this.schemaHandler);
+ this.schemaHandler, this.transactionHandler);
streamsSubscriptionService.subscribeToStream("toaster:toaster/toasterStatus/scope=ONE", this.uriInfo);
}
doReturn(uriBuilder).when(this.uriInfo).getAbsolutePathBuilder();
final RestconfStreamsSubscriptionServiceImpl streamsSubscriptionService =
new RestconfStreamsSubscriptionServiceImpl(this.dataBrokerHandler, this.notificationServiceHandler,
- this.schemaHandler);
+ this.schemaHandler, this.transactionHandler);
streamsSubscriptionService.subscribeToStream("toaster:toaster/toasterStatus/datastore=OPERATIONAL",
this.uriInfo);
}
package org.opendaylight.restconf.utils.mapping;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-import com.google.common.collect.Sets;
-import java.util.AbstractMap;
+import java.net.URI;
+import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
+import java.util.Date;
import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.Map.Entry;
import java.util.Set;
import org.junit.Assert;
import org.junit.Before;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
-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.Draft18;
import org.opendaylight.restconf.Draft18.IetfYangLibrary;
import org.opendaylight.restconf.Draft18.MonitoringModule;
import org.opendaylight.restconf.Draft18.MonitoringModule.QueryParams;
import org.opendaylight.restconf.Draft18.RestconfModule;
-import org.opendaylight.restconf.utils.schema.context.RestconfSchemaUtil;
+import org.opendaylight.restconf.utils.parser.ParserIdentifier;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.nodes.AbstractImmutableDataContainerAttrNode;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-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;
private static Set<Module> modules;
private static SchemaContext schemaContext;
- private static SchemaContext schemaContextCapabilites;
+ private static SchemaContext schemaContextMonitoring;
private static Set<Module> modulesRest;
- private Set<DataSchemaNode> allStreamChildNodes;
-
@BeforeClass
public static void loadTestSchemaContextAndModules() throws Exception {
- RestconfMappingNodeUtilTest.schemaContext = TestRestconfUtils.loadSchemaContext(
+ schemaContext = TestRestconfUtils.loadSchemaContext(
"/modules/restconf-module-testing");
- RestconfMappingNodeUtilTest.schemaContextCapabilites = TestRestconfUtils.loadSchemaContext("/modules");
- RestconfMappingNodeUtilTest.modules = schemaContextCapabilites.getModules();
- RestconfMappingNodeUtilTest.modulesRest =
- TestRestconfUtils.loadSchemaContext("/modules/restconf-module-testing").getModules();
+ schemaContextMonitoring = TestRestconfUtils.loadSchemaContext("/modules");
+ modules = schemaContextMonitoring.getModules();
+ modulesRest = TestRestconfUtils.loadSchemaContext("/modules/restconf-module-testing").getModules();
}
@Before
QName.create("", RestconfMappingNodeConstants.REPLAY_SUPPORT));
when(this.leafReplayLog.getQName()).thenReturn(QName.create(RestconfMappingNodeConstants.REPLAY_LOG));
when(this.leafEvents.getQName()).thenReturn(QName.create("", RestconfMappingNodeConstants.EVENTS));
-
- this.allStreamChildNodes = Sets.newHashSet(
- this.leafName, this.leafDescription, this.leafReplaySupport, this.leafReplayLog, this.leafEvents);
}
/**
@Test
public void restconfStateCapabilitesTest() {
- final Module monitoringModule = schemaContextCapabilites
+ final Module monitoringModule = schemaContextMonitoring
.findModuleByNamespaceAndRevision(MonitoringModule.URI_MODULE, MonitoringModule.DATE);
final NormalizedNode<NodeIdentifier, Collection<DataContainerChild<? extends PathArgument, ?>>> normNode =
RestconfMappingNodeUtil.mapCapabilites(monitoringModule);
Assert.assertTrue(listOfValues.contains(QueryParams.WITH_DEFAULTS));
}
- /**
- * Positive test of writing one stream to {@link MonitoringModule#STREAM_LIST_SCHEMA_NODE} and checking if stream
- * was correctly written.
- */
- @Test
- public void toStreamEntryNodeTest() {
- // test stream name
- final String stream1 = "stream-1";
-
- // get list stream node from Restconf module
- final ListSchemaNode listStream = (ListSchemaNode) RestconfSchemaUtil.getRestconfSchemaNode(
- getTestingRestconfModule("ietf-restconf"), MonitoringModule.STREAM_LIST_SCHEMA_NODE);
-
- // write stream to list stream node
- final MapEntryNode mapEntryNode = RestconfMappingNodeUtil.toStreamEntryNode(stream1, listStream);
-
- // verify
- verifyStream(stream1, mapEntryNode);
- }
-
- /**
- * Try to map streams when {@link MonitoringModule#STREAM_LIST_SCHEMA_NODE} is <code>null</code>.
- * Test is expected to fail catching <code>IllegalStateException</code>.
- */
- @Test
- public void toStreamEntryNodeNullListStreamNegativeTest() {
- this.thrown.expect(IllegalStateException.class);
- RestconfMappingNodeUtil.toStreamEntryNode("stream-1", null);
- }
-
- /**
- * Test trying to map streams to {@link MonitoringModule#STREAM_LIST_SCHEMA_NODE} which is not of type list.
- * Test is expected to fail with <code>IllegalStateException</code>.
- */
@Test
- public void toStreamEntryNodeIllegalListStreamNegativeTest() {
- this.thrown.expect(IllegalStateException.class);
- RestconfMappingNodeUtil.toStreamEntryNode("stream-1", mock(LeafSchemaNode.class));
- }
-
- /**
- * Test case with target {@link MonitoringModule#STREAM_LIST_SCHEMA_NODE} which does not contain any child nodes.
- * Test is catching <code>RestconfDocumentedException</code> and error type, error tag and error status code are
- * compared to expected values.
- */
- @Test
- public void toStreamEntryNodeSchemaNodeWithoutChildsNegativeTest() {
- final ListSchemaNode mockListNode = mock(ListSchemaNode.class);
- when(mockListNode.getChildNodes()).thenReturn(Collections.EMPTY_SET);
-
- try {
- RestconfMappingNodeUtil.toStreamEntryNode("stream-1", mockListNode);
- fail("Test should fail due to no child nodes in"
- + MonitoringModule.STREAM_LIST_SCHEMA_NODE
- + " node");
- } catch (final RestconfDocumentedException e) {
- assertEquals("Error type is not correct",
- ErrorType.PROTOCOL, e.getErrors().get(0).getErrorType());
- assertEquals("Error tag is not correct",
- ErrorTag.DATA_MISSING, e.getErrors().get(0).getErrorTag());
- assertEquals("Error status code is not correct",
- 404, e.getErrors().get(0).getErrorTag().getStatusCode());
- }
- }
+ public void toStreamEntryNodeTest() throws Exception {
+ final YangInstanceIdentifier path =
+ ParserIdentifier.toInstanceIdentifier("nested-module:depth1-cont/depth2-leaf1", schemaContextMonitoring, null).getInstanceIdentifier();
+ final Date start = new Date();
+ final String outputType = "XML";
+ final URI uri = new URI("uri");
+ final Module monitoringModule = schemaContextMonitoring
+ .findModuleByNamespaceAndRevision(MonitoringModule.URI_MODULE, MonitoringModule.DATE);
+ final boolean exist = true;
- /**
- * Test case when target list stream does not contain child with name {@link RestconfMappingNodeConstants#NAME}.
- * Test is catching <code>RestconfDocumentedException</code> and error type, error tag and error status code are
- * compared to expected values.
- */
- @Test
- public void toStreamEntryNodeMissingStreamNameNegativeTest() {
- prepareMockListWithMissingLeaf(this.leafName);
+ final Map<QName, Object> map =
+ prepareMap(path.getLastPathArgument().getNodeType().getLocalName(), uri, start, outputType);
- try {
- RestconfMappingNodeUtil.toStreamEntryNode("stream-1", this.mockStreamList);
- fail("Test should fail due to missing "
- + RestconfMappingNodeConstants.NAME
- + " node in " + MonitoringModule.STREAM_LIST_SCHEMA_NODE);
- } catch (final RestconfDocumentedException e) {
- assertEquals("Error type is not correct",
- ErrorType.PROTOCOL, e.getErrors().get(0).getErrorType());
- assertEquals("Error tag is not correct",
- ErrorTag.DATA_MISSING, e.getErrors().get(0).getErrorTag());
- assertEquals("Error status code is not correct",
- 404, e.getErrors().get(0).getErrorTag().getStatusCode());
- }
+ final NormalizedNode mappedData = RestconfMappingNodeUtil.mapDataChangeNotificationStreamByIetfRestconfMonitoring(path, start, outputType, uri,
+ monitoringModule, exist, schemaContextMonitoring);
+ assertNotNull(mappedData);
+ testData(map, mappedData);
}
- /**
- * Test case when target list stream does not contain child with name
- * {@link RestconfMappingNodeConstants#DESCRIPTION}. Test is catching <code>RestconfDocumentedException</code> and
- * checking error type and error tag.
- */
@Test
- public void toStreamEntryNodeMissingStreamDescriptionNegativeTest() {
- prepareMockListWithMissingLeaf(this.leafDescription);
-
- try {
- RestconfMappingNodeUtil.toStreamEntryNode("stream-1", this.mockStreamList);
- fail("Test should fail due to missing "
- + RestconfMappingNodeConstants.DESCRIPTION
- + " node in " + MonitoringModule.STREAM_LIST_SCHEMA_NODE);
- } catch (final RestconfDocumentedException e) {
- assertEquals("Error type is not correct",
- ErrorType.PROTOCOL, e.getErrors().get(0).getErrorType());
- assertEquals("Error tag is not correct",
- ErrorTag.DATA_MISSING, e.getErrors().get(0).getErrorTag());
- assertEquals("Error status code is not correct",
- 404, e.getErrors().get(0).getErrorTag().getStatusCode());
- }
- }
+ public void toStreamEntryNodeNotifiTest() throws Exception {
+ final Date start = new Date();
+ final String outputType = "JSON";
+ final URI uri = new URI("uri");
+ final Module monitoringModule = schemaContextMonitoring
+ .findModuleByNamespaceAndRevision(MonitoringModule.URI_MODULE, MonitoringModule.DATE);
+ final boolean exist = true;
- /**
- * Test case when target list stream does not contain child with name
- * {@link RestconfMappingNodeConstants#REPLAY_SUPPORT}. Test is catching <code>RestconfDocumentedException</code>
- * and checking error type and error tag.
- */
- @Test
- public void toStreamEntryNodeMissingStreamReplaySupportNegativeTest() {
- prepareMockListWithMissingLeaf(this.leafReplaySupport);
+ final Map<QName, Object> map = prepareMap("notifi", uri, start, outputType);
+ map.put(MonitoringModule.LEAF_DESCR_STREAM_QNAME, "Notifi");
- try {
- RestconfMappingNodeUtil.toStreamEntryNode("stream-1", this.mockStreamList);
- fail("Test should fail due to missing "
- + RestconfMappingNodeConstants.REPLAY_SUPPORT
- + " node in " + MonitoringModule.STREAM_LIST_SCHEMA_NODE);
- } catch (final RestconfDocumentedException e) {
- assertEquals("Error type is not correct",
- ErrorType.PROTOCOL, e.getErrors().get(0).getErrorType());
- assertEquals("Error tag is not correct",
- ErrorTag.DATA_MISSING, e.getErrors().get(0).getErrorTag());
- assertEquals("Error status code is not correct",
- 404, e.getErrors().get(0).getErrorTag().getStatusCode());
- }
+ final QName notifiQName = QName.create("urn:nested:module", "2014-06-3", "notifi");
+ final NormalizedNode mappedData =
+ RestconfMappingNodeUtil.mapYangNotificationStreamByIetfRestconfMonitoring(notifiQName, schemaContextMonitoring.getNotifications(), start,
+ outputType, uri, monitoringModule, exist);
+ assertNotNull(mappedData);
+ testData(map, mappedData);
}
- /**
- * Test case when target list stream does not contain child with name
- * {@link RestconfMappingNodeConstants#REPLAY_LOG}. Test is catching <code>RestconfDocumentedException</code> and
- * checking error type and error tag.
- */
- @Test
- public void toStreamEntryNodeMissingStreamReplayLogNegativeTest() {
- prepareMockListWithMissingLeaf(this.leafReplayLog);
-
- try {
- RestconfMappingNodeUtil.toStreamEntryNode("stream-1", this.mockStreamList);
- fail("Test should fail due to missing "
- + RestconfMappingNodeConstants.REPLAY_LOG
- + " node in " + MonitoringModule.STREAM_LIST_SCHEMA_NODE);
- } catch (final RestconfDocumentedException e) {
- assertEquals("Error type is not correct",
- ErrorType.PROTOCOL, e.getErrors().get(0).getErrorType());
- assertEquals("Error tag is not correct",
- ErrorTag.DATA_MISSING, e.getErrors().get(0).getErrorTag());
- assertEquals("Error status code is not correct",
- 404, e.getErrors().get(0).getErrorTag().getStatusCode());
- }
+ private Map<QName, Object> prepareMap(final String name, final URI uri, final Date start, final String outputType) {
+ final Map<QName, Object> map = new HashMap<>();
+ map.put(MonitoringModule.LEAF_NAME_STREAM_QNAME, name);
+ map.put(MonitoringModule.LEAF_LOCATION_ACCESS_QNAME, uri.toString());
+ map.put(MonitoringModule.LEAF_REPLAY_SUPP_STREAM_QNAME, true);
+ map.put(MonitoringModule.LEAF_START_TIME_STREAM_QNAME,
+ new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'XXX").format(start));
+ map.put(MonitoringModule.LEAF_ENCODING_ACCESS_QNAME, outputType);
+ return map;
}
- /**
- * Test case when target list stream does not contain child with name {@link RestconfMappingNodeConstants#EVENTS}.
- * Test is catching <code>RestconfDocumentedException</code> and checking error type, error tag and error status
- * code.
- */
- @Test
- public void toStreamEntryNodeMissingStreamEventsNegativeTest() {
- prepareMockListWithMissingLeaf(this.leafEvents);
-
- try {
- RestconfMappingNodeUtil.toStreamEntryNode("stream-1", this.mockStreamList);
- fail("Test should fail due to missing "
- + RestconfMappingNodeConstants.EVENTS
- + " node in " + MonitoringModule.STREAM_LIST_SCHEMA_NODE);
- } catch (final RestconfDocumentedException e) {
- assertEquals("Error type is not correct",
- ErrorType.PROTOCOL, e.getErrors().get(0).getErrorType());
- assertEquals("Error tag is not correct",
- ErrorTag.DATA_MISSING, e.getErrors().get(0).getErrorTag());
- assertEquals("Error status code is not correct",
- 404, e.getErrors().get(0).getErrorTag().getStatusCode());
+ private void testData(final Map<QName, Object> map, final NormalizedNode mappedData) {
+ for (final DataContainerChild<? extends PathArgument, ?> child : ((MapEntryNode) mappedData).getValue()) {
+ if (child instanceof LeafNode) {
+ final LeafNode leaf = ((LeafNode) child);
+ Assert.assertTrue(map.containsKey(leaf.getNodeType()));
+ Assert.assertEquals(map.get(leaf.getNodeType()), leaf.getValue());
+ }
}
}
- /**
- * Test case when target list stream contains child with name {@link RestconfMappingNodeConstants#NAME}. Test is
- * expecting <code>IllegalStateException</code>.
- */
- @Test
- public void toStreamEntryNodeStreamNameNegativeTest() {
- prepareMockListWithIllegalLeaf(this.leafName);
-
- this.thrown.expect(IllegalStateException.class);
- RestconfMappingNodeUtil.toStreamEntryNode("stream-1", this.mockStreamList);
- }
-
- /**
- * Test case when target list stream contains child with name {@link RestconfMappingNodeConstants#DESCRIPTION}.
- * Test is expecting <code>IllegalStateException</code>.
- */
- @Test
- public void toStreamEntryNodeStreamDescriptionNegativeTest() {
- prepareMockListWithIllegalLeaf(this.leafDescription);
-
- this.thrown.expect(IllegalStateException.class);
- RestconfMappingNodeUtil.toStreamEntryNode("stream-1", this.mockStreamList);
- }
-
- /**
- * Test case when target list stream contains child with name {@link RestconfMappingNodeConstants#REPLAY_SUPPORT}.
- * Test is expecting <code>IllegalStateException</code>.
- */
- @Test
- public void toStreamEntryNodeStreamReplaySupportNegativeTest() {
- prepareMockListWithIllegalLeaf(this.leafReplaySupport);
-
- this.thrown.expect(IllegalStateException.class);
- RestconfMappingNodeUtil.toStreamEntryNode("stream-1", this.mockStreamList);
- }
-
- /**
- * Test case when target list stream contains child with name {@link RestconfMappingNodeConstants#REPLAY_LOG}.
- * Test is expecting <code>IllegalStateException</code>.
- */
- @Test
- public void toStreamEntryNodeStreamReplayLogNegativeTest() {
- prepareMockListWithIllegalLeaf(this.leafReplayLog);
-
- this.thrown.expect(IllegalStateException.class);
- RestconfMappingNodeUtil.toStreamEntryNode("stream-1", this.mockStreamList);
- }
-
- /**
- * Test case when target list stream contains child with name {@link RestconfMappingNodeConstants#EVENTS}. Test is
- * expecting <code>IllegalStateException</code>.
- */
- @Test
- public void toStreamEntryNodeStreamEventsNegativeTest() {
- prepareMockListWithIllegalLeaf(this.leafEvents);
-
- this.thrown.expect(IllegalStateException.class);
- RestconfMappingNodeUtil.toStreamEntryNode("stream-1", this.mockStreamList);
- }
-
/**
* Verify loaded modules
*
loadedModules.remove(name);
}
}
-
- /**
- * Verify if a stream was correctly written into {@link MonitoringModule#STREAM_LIST_SCHEMA_NODE} node in Restconf
- * module.
- * @param streamName Expected stream name
- * @param streamNode Writetn strem node from Restconf module
- */
- private final void verifyStream(final String streamName, final MapEntryNode streamNode) {
- assertNotNull("Stream node can not be null", streamNode);
- final Iterator entries = ((AbstractImmutableDataContainerAttrNode) streamNode)
- .getChildren().entrySet().iterator();
- boolean notAllowedKey = false;
-
- while (entries.hasNext()) {
- final Entry e = ((AbstractMap.SimpleImmutableEntry) entries.next());
- final String key = ((YangInstanceIdentifier.NodeIdentifier) e.getKey()).getNodeType().getLocalName();
-
- switch (key) {
- case RestconfMappingNodeConstants.NAME :
- assertEquals("Stream name value is not as expected",
- streamName, ((LeafNode) e.getValue()).getValue());
- break;
- case RestconfMappingNodeConstants.DESCRIPTION :
- assertEquals("Stream description value is not as expected",
- RestconfMappingStreamConstants.DESCRIPTION, ((LeafNode) e.getValue()).getValue());
- break;
- case RestconfMappingNodeConstants.REPLAY_SUPPORT :
- assertEquals("Stream replay support value is not as expected",
- RestconfMappingStreamConstants.REPLAY_SUPPORT, ((LeafNode) e.getValue()).getValue());
- break;
- case RestconfMappingNodeConstants.REPLAY_LOG :
- assertEquals("Stream replay log value is not as expected",
- RestconfMappingStreamConstants.REPLAY_LOG, ((LeafNode) e.getValue()).getValue());
- break;
- case RestconfMappingNodeConstants.EVENTS :
- assertEquals("Stream events value is not as expected",
- RestconfMappingStreamConstants.EVENTS, ((LeafNode) e.getValue()).getValue());
- break;
- default:
- notAllowedKey = true;
- break;
- }
- }
-
- assertFalse("Not allowed key in list stream found", notAllowedKey);
- }
-
- /**
- * There are multiple testing Restconf modules for different test cases. It is possible to distinguish them by
- * name or by namespace. This method is looking for Restconf test module by its name.
- * @param s Testing Restconf module name
- * @return Restconf module
- */
- private Module getTestingRestconfModule(final String s) {
- return RestconfMappingNodeUtilTest.schemaContext.findModuleByName(
- s, Draft18.RestconfModule.IETF_RESTCONF_QNAME.getRevision());
- }
-
- /**
- * Updates {@link this#mockStreamList} to NOT contains specified leaf.
- * @param leaf Leaf to be missing
- */
- private void prepareMockListWithMissingLeaf(final LeafSchemaNode leaf) {
- // prepare set of leaf without selected leaf
- final Set childLeafs = new HashSet<>(this.allStreamChildNodes);
- childLeafs.remove(leaf);
-
- // mock list leaf nodes
- when(this.mockStreamList.getChildNodes()).thenReturn(childLeafs);
- }
-
- /**
- * Updates {@link this#mockStreamList} to contains specified leaf which is not of type {@link LeafSchemaNode}.
- * @param leaf Leaf to be changes
- */
- private void prepareMockListWithIllegalLeaf(final LeafSchemaNode leaf) {
- // prepare set of leaf without selected leaf
- final Set childLeafs = new HashSet<>(this.allStreamChildNodes);
- childLeafs.remove(leaf);
-
- // add leaf-list with the same local name as removed leaf
- final String localName = leaf.getQName().getLocalName();
- final LeafListSchemaNode mockLeafList = mock(LeafListSchemaNode.class);
- when(mockLeafList.getQName()).thenReturn(QName.create("", localName));
- childLeafs.add(mockLeafList);
-
- // mock list leaf nodes
- when(this.mockStreamList.getChildNodes()).thenReturn(childLeafs);
- }
}
package org.opendaylight.restconf.utils.schema.context;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
-import com.google.common.collect.Sets;
-import org.junit.Before;
-import org.junit.Rule;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import org.junit.Assert;
import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
+import org.mockito.Mockito;
import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException;
-import org.opendaylight.netconf.sal.restconf.impl.RestconfError;
-import org.opendaylight.restconf.Draft18;
-import org.opendaylight.restconf.Draft18.MonitoringModule;
-import org.opendaylight.restconf.Draft18.RestconfModule;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.model.api.SchemaNode;
/**
* Unit tests for {@link RestconfSchemaUtil}
*/
public class RestconfSchemaUtilTest {
- // schema with testing modules
- private SchemaContext schemaContext;
- @Rule
- public ExpectedException thrown = ExpectedException.none();
-
- @Before
- public void setup() throws Exception {
- this.schemaContext = TestRestconfUtils.loadSchemaContext("/modules/restconf-module-testing");
- }
-
- /**
- * Positive test for getting <code>DataSchemaNode</code> from Restconf module for schema node name equals to
- * {@link RestconfModule#MODULE_LIST_SCHEMA_NODE} when this node can be found.
- */
- @Test
- public void getRestconfSchemaNodeListModuleTest() {
- final DataSchemaNode dataSchemaNode = RestconfSchemaUtil.getRestconfSchemaNode(
- getTestingRestconfModule("ietf-restconf"),
- RestconfModule.MODULE_LIST_SCHEMA_NODE);
-
- assertNotNull("Existing schema node "+ RestconfModule.MODULE_LIST_SCHEMA_NODE + " should be found",
- dataSchemaNode);
- assertEquals("Incorrect schema node was returned",
- dataSchemaNode.getQName().getLocalName(), RestconfModule.MODULE_LIST_SCHEMA_NODE);
- assertEquals("Incorrect schema node was returned",
- dataSchemaNode.getQName().getNamespace().toString(), RestconfModule.NAMESPACE);
- assertEquals("Incorrect schema node was returned",
- dataSchemaNode.getQName().getFormattedRevision(), RestconfModule.REVISION);
- }
-
- /**
- * Positive test for getting <code>DataSchemaNode</code> from Restconf module for schema node name equals to
- * {@link MonitoringModule#STREAM_LIST_SCHEMA_NODE} when this node can be found.
- */
- @Test
- public void getRestconfSchemaNodeListStreamTest() {
- final DataSchemaNode dataSchemaNode = RestconfSchemaUtil.getRestconfSchemaNode(
- getTestingRestconfModule("ietf-restconf"),
- MonitoringModule.STREAM_LIST_SCHEMA_NODE);
-
- assertNotNull("Existing schema node " + MonitoringModule.STREAM_LIST_SCHEMA_NODE + " should be found",
- dataSchemaNode);
- assertEquals("Incorrect schema node was returned",
- dataSchemaNode.getQName().getLocalName(), MonitoringModule.STREAM_LIST_SCHEMA_NODE);
- assertEquals("Incorrect schema node was returned",
- dataSchemaNode.getQName().getNamespace().toString(), RestconfModule.NAMESPACE);
- assertEquals("Incorrect schema node was returned",
- dataSchemaNode.getQName().getFormattedRevision(), RestconfModule.REVISION);
- }
-
- /**
- * Positive test for getting <code>DataSchemaNode</code> from Restconf module for schema node name equals to
- * {@link RestconfModule#MODULES_CONTAINER_SCHEMA_NODE} when this node can be found.
- */
- @Test
- public void getRestconfSchemaNodeContainerModulesTest() {
- final DataSchemaNode dataSchemaNode = RestconfSchemaUtil.getRestconfSchemaNode(
- getTestingRestconfModule("ietf-restconf"),
- RestconfModule.MODULES_CONTAINER_SCHEMA_NODE);
-
- assertNotNull("Existing schema node " + RestconfModule.MODULES_CONTAINER_SCHEMA_NODE + "should be found",
- dataSchemaNode);
- assertEquals("Incorrect schema node was returned",
- dataSchemaNode.getQName().getLocalName(), RestconfModule.MODULES_CONTAINER_SCHEMA_NODE);
- assertEquals("Incorrect schema node was returned",
- dataSchemaNode.getQName().getNamespace().toString(), RestconfModule.NAMESPACE);
- assertEquals("Incorrect schema node was returned",
- dataSchemaNode.getQName().getFormattedRevision(), RestconfModule.REVISION);
- }
-
- /**
- * Positive test for getting <code>DataSchemaNode</code> from Restconf module for schema node name equals to
- * {@link MonitoringModule#STREAMS_CONTAINER_SCHEMA_NODE} when this node can be found.
- */
- @Test
- public void getRestconfSchemaNodeContainerStreamsTest() {
- final DataSchemaNode dataSchemaNode = RestconfSchemaUtil.getRestconfSchemaNode(
- getTestingRestconfModule("ietf-restconf"),
- MonitoringModule.STREAMS_CONTAINER_SCHEMA_NODE);
-
- assertNotNull("Existing schema node " + MonitoringModule.STREAMS_CONTAINER_SCHEMA_NODE + " should be found",
- dataSchemaNode);
- assertEquals("Incorrect schema node was returned",
- dataSchemaNode.getQName().getLocalName(), MonitoringModule.STREAMS_CONTAINER_SCHEMA_NODE);
- assertEquals("Incorrect schema node was returned",
- dataSchemaNode.getQName().getNamespace().toString(), RestconfModule.NAMESPACE);
- assertEquals("Incorrect schema node was returned",
- dataSchemaNode.getQName().getFormattedRevision(), RestconfModule.REVISION);
- }
-
- /**
- * Negative test for getting <code>DataSchemaNode</code> from Restconf module when Restconf module is
- * <code>null</code>. Test is expected to fail catching <code>NullPointerException</code>.
- */
- @Test
- public void getRestconfSchemaNodeNullRestconfModuleNegativeTest() {
- this.thrown.expect(NullPointerException.class);
- RestconfSchemaUtil.getRestconfSchemaNode(null, RestconfModule.RESTCONF_CONTAINER_SCHEMA_NODE);
- }
-
- /**
- * Negative test for getting <code>DataSchemaNode</code> from Restconf module when name of the schema node name is
- * <code>null</code>. Test is expected to fail with <code>NullPointerException</code>.
- */
- @Test
- public void getRestconfSchemaNodeNullSchemaNodeNameNegativeTest() {
- this.thrown.expect(NullPointerException.class);
- RestconfSchemaUtil.getRestconfSchemaNode(getTestingRestconfModule("ietf-restconf"), null);
- }
-
- /**
- * Negative test for getting <code>DataSchemaNode</code> from Restconf module when name of the schema node name
- * references to not existing node. Test is expected to fail catching code>RestconfDocumentedException</code> and
- * checking expected error type, error tag and error status code.
- */
- @Test
- public void getRestconfSchemaNodeNotExistingSchemaNodeNameNegativeTest() {
- try {
- RestconfSchemaUtil.getRestconfSchemaNode(getTestingRestconfModule("ietf-restconf"), "not-existing-node");
- fail("Test should fail due to not-existing node name");
- } catch (final RestconfDocumentedException e) {
- assertEquals("Error type is not correct",
- RestconfError.ErrorType.PROTOCOL, e.getErrors().get(0).getErrorType());
- assertEquals("Error tag is not correct",
- RestconfError.ErrorTag.DATA_MISSING, e.getErrors().get(0).getErrorTag());
- assertEquals("Error status code is not correct",
- 404, e.getErrors().get(0).getErrorTag().getStatusCode());
- }
- }
-
- /**
- * Positive test trying to find <code>DataSchemaNode</code> of {@link RestconfModule#RESTCONF_GROUPING_SCHEMA_NODE}
- * in Restconf module groupings collection.
- */
- @Test
- public void findSchemaNodeInCollectionTest() {
- final SchemaNode schemaNode = RestconfSchemaUtil.findSchemaNodeInCollection(
- getTestingRestconfModule("ietf-restconf").getGroupings(),
- RestconfModule.RESTCONF_GROUPING_SCHEMA_NODE);
-
- assertNotNull("Restconf grouping schema node should be found", schemaNode);
- assertEquals("Incorrect grouping was returned",
- schemaNode.getQName().getLocalName(), RestconfModule.RESTCONF_GROUPING_SCHEMA_NODE);
- assertEquals("Incorrect grouping was returned",
- schemaNode.getQName().getNamespace().toString(), RestconfModule.NAMESPACE);
- assertEquals("Incorrect grouping was returned",
- schemaNode.getQName().getFormattedRevision(), RestconfModule.REVISION);
- }
-
- /**
- * Negative test trying to find <code>DataSchemaNode</code> of not existing groupings schema node name in Restconf
- * module grouping collection. Test is expected to fail catching <code>RestconfDocumentedException</code> and
- * checking for correct error type, error tag and error status code.
- */
- @Test
- public void findSchemaNodeInCollectionNegativeTest() {
- try {
- RestconfSchemaUtil.findSchemaNodeInCollection(
- getTestingRestconfModule("ietf-restconf").getGroupings(), "not-existing-grouping");
- fail("Test should fail due to missing not-existing grouping in Restconf grouping collection");
- } catch (final RestconfDocumentedException e) {
- assertEquals("Error type is not correct",
- RestconfError.ErrorType.PROTOCOL, e.getErrors().get(0).getErrorType());
- assertEquals("Error tag is not correct",
- RestconfError.ErrorTag.DATA_MISSING, e.getErrors().get(0).getErrorTag());
- assertEquals("Error status code is not correct",
- 404, e.getErrors().get(0).getErrorTag().getStatusCode());
- }
- }
-
- /**
- * Negative test trying to find <code>DataSchemaNode</code> of existing schema node name in <code>null</code>
- * collection. Test is expected to fail with <code>NullPointerException</code>.
- */
@Test
- public void findSchemaNodeInCollectionNullCollectionNegativeTest() {
- this.thrown.expect(NullPointerException.class);
- RestconfSchemaUtil.findSchemaNodeInCollection(null, RestconfModule.MODULES_CONTAINER_SCHEMA_NODE);
+ public void findInCollectionTest() {
+ final SchemaNode origSchNode = mockSchemaNode("key");
+ final SchemaNode actualSch = findSchemaNodeInCollection("key", origSchNode);
+ Assert.assertEquals(origSchNode, actualSch);
}
- /**
- * Negative test trying to find <code>DataSchemaNode</code> for schema node name in empty collection. Test is
- * expected to fail with <code>RestconfDocumentedException</code>. Error type, error tag and error status code
- * are compared to expected values.
- */
- @Test
- public void findSchemaNodeInCollectionEmptyCollectionNegativeTest() {
- try {
- RestconfSchemaUtil.findSchemaNodeInCollection(
- Sets.newHashSet(), RestconfModule.MODULES_CONTAINER_SCHEMA_NODE);
- fail("Test should fail due to empty schema nodes collection");
- } catch (final RestconfDocumentedException e) {
- assertEquals("Error type is not correct",
- RestconfError.ErrorType.PROTOCOL, e.getErrors().get(0).getErrorType());
- assertEquals("Error tag is not correct",
- RestconfError.ErrorTag.DATA_MISSING, e.getErrors().get(0).getErrorTag());
- assertEquals("Error status code is not correct",
- 404, e.getErrors().get(0).getErrorTag().getStatusCode());
- }
+ @Test(expected = RestconfDocumentedException.class)
+ public void findInCollectionFailedTest() {
+ final SchemaNode origSchNode = mockSchemaNode("key");
+ findSchemaNodeInCollection("bad_key", origSchNode);
}
- /**
- * Negative test trying to find <code>DataSchemaNode</code> of <code>null</code> schema node name in Restconf module
- * groupings collection. Test is expected to fail with <code>RestconfDocumentedException</code>. Error type, error
- * tag and error status code are compared to expected values.
- */
- @Test
- public void findSchemaNodeInCollectionNullSchemaNodeName() {
- try {
- RestconfSchemaUtil.findSchemaNodeInCollection(
- getTestingRestconfModule("ietf-restconf").getGroupings(), null);
- fail("Test should fail due to null schema node name");
- } catch (final RestconfDocumentedException e) {
- assertEquals("Error type is not correct",
- RestconfError.ErrorType.PROTOCOL, e.getErrors().get(0).getErrorType());
- assertEquals("Error tag is not correct",
- RestconfError.ErrorTag.DATA_MISSING, e.getErrors().get(0).getErrorTag());
- assertEquals("Error status code is not correct",
- 404, e.getErrors().get(0).getErrorTag().getStatusCode());
+ private SchemaNode findSchemaNodeInCollection(final String key, final SchemaNode... origSchNode) {
+ final List<SchemaNode> collection = new ArrayList<>();
+ for (int i = 0; i < origSchNode.length; i++) {
+ collection.add(origSchNode[i]);
}
+ return RestconfSchemaUtil.findSchemaNodeInCollection(collection, key);
}
- /**
- * There are multiple testing Restconf modules for different test cases. It is possible to distinguish them by
- * name or by namespace. This method is looking for Restconf test module by its name.
- * @param s Testing Restconf module name
- * @return Restconf module
- */
- private Module getTestingRestconfModule(final String s) {
- return this.schemaContext.findModuleByName(s, Draft18.RestconfModule.IETF_RESTCONF_QNAME.getRevision());
+ private SchemaNode mockSchemaNode(final String origKey) {
+ final SchemaNode mockSchNode = Mockito.mock(SchemaNode.class);
+ Mockito.when(mockSchNode.getQName())
+ .thenReturn(QName.create("ns", new SimpleDateFormat("yyyy-MM-dd").format(new Date()), origKey));
+ return mockSchNode;
}
}
type string;
}
}
+
+ notification notifi{
+ description "Notifi";
+ }
}
--- /dev/null
+module toaster {
+
+ yang-version 1;
+
+ namespace
+ "http://netconfcentral.org/ns/toaster";
+
+ prefix toast;
+
+ organization "Netconf Central";
+
+ contact
+ "Andy Bierman <andy@netconfcentral.org>";
+
+ description
+ "YANG version of the TOASTER-MIB.";
+
+ revision "2009-11-20" {
+ description
+ "Toaster module in progress.";
+ }
+
+
+ identity toast-type {
+ description
+ "Base for all bread types supported by the toaster.
+ New bread types not listed here nay be added in the
+ future.";
+ }
+
+ identity white-bread {
+ base toast:toast-type;
+ description "White bread.";
+ }
+
+ identity wheat-bread {
+ base toast-type;
+ description "Wheat bread.";
+ }
+
+ identity wonder-bread {
+ base toast-type;
+ description "Wonder bread.";
+ }
+
+ identity frozen-waffle {
+ base toast-type;
+ description "Frozen waffle.";
+ }
+
+ identity frozen-bagel {
+ base toast-type;
+ description "Frozen bagel.";
+ }
+
+ identity hash-brown {
+ base toast-type;
+ description "Hash browned potatos.";
+ }
+
+ typedef DisplayString {
+ type string {
+ length "0 .. 255";
+ }
+ description
+ "YANG version of the SMIv2 DisplayString TEXTUAL-CONVENTION.";
+ reference
+ "RFC 2579, section 2.";
+
+ }
+
+ container toaster {
+ presence
+ "Indicates the toaster service is available";
+ description
+ "Top-level container for all toaster database objects.";
+ leaf toasterManufacturer {
+ type DisplayString;
+ config false;
+ mandatory true;
+ description
+ "The name of the toaster's manufacturer. For instance,
+ Microsoft Toaster.";
+ }
+
+ leaf toasterModelNumber {
+ type DisplayString;
+ config false;
+ mandatory true;
+ description
+ "The name of the toaster's model. For instance,
+ Radiant Automatic.";
+ }
+
+ leaf toasterStatus {
+ type enumeration {
+ enum "up" {
+ value 1;
+ description
+ "The toaster knob position is up.
+ No toast is being made now.";
+ }
+ enum "down" {
+ value 2;
+ description
+ "The toaster knob position is down.
+ Toast is being made now.";
+ }
+ }
+ config false;
+ mandatory true;
+ description
+ "This variable indicates the current state of
+ the toaster.";
+ }
+
+ leaf darknessFactor {
+ type uint32;
+ config true;
+ default 1000;
+ description
+ "The darkness factor. Basically, the number of ms to multiple the doneness value by.";
+ }
+ } // container toaster
+
+ rpc make-toast {
+ description
+ "Make some toast.
+ The toastDone notification will be sent when
+ the toast is finished.
+ An 'in-use' error will be returned if toast
+ is already being made.
+ A 'resource-denied' error will be returned
+ if the toaster service is disabled.";
+ input {
+ leaf toasterDoneness {
+ type uint32 {
+ range "1 .. 10";
+ }
+ default '5';
+ description
+ "This variable controls how well-done is the
+ ensuing toast. It should be on a scale of 1 to 10.
+ Toast made at 10 generally is considered unfit
+ for human consumption; toast made at 1 is warmed
+ lightly.";
+ }
+
+ leaf toasterToastType {
+ type identityref {
+ base toast:toast-type;
+ }
+ default 'wheat-bread';
+ description
+ "This variable informs the toaster of the type of
+ material that is being toasted. The toaster
+ uses this information, combined with
+ toasterDoneness, to compute for how
+ long the material must be toasted to achieve
+ the required doneness.";
+ }
+ }
+ } // rpc make-toast
+
+ rpc cancel-toast {
+ description
+ "Stop making toast, if any is being made.
+ A 'resource-denied' error will be returned
+ if the toaster service is disabled.";
+ } // rpc cancel-toast
+
+ rpc restock-toaster {
+ description
+ "Restocks the toaster with the amount of bread specified.";
+
+ input {
+ leaf amountOfBreadToStock {
+ type uint32;
+ description
+ "Indicates the amount of bread to re-stock";
+ }
+ }
+ }
+
+ notification toasterOutOfBread {
+ description
+ "Indicates that the toaster has run of out bread.";
+ } // notification toasterOutOfStock
+
+ notification toasterRestocked {
+ description
+ "Indicates that the toaster has run of out bread.";
+ leaf amountOfBread {
+ type uint32;
+ description
+ "Indicates the amount of bread that was re-stocked";
+ }
+ } // notification toasterOutOfStock
+
+ } // module toaster
\ No newline at end of file