import com.google.common.base.CharMatcher;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
-import com.google.common.base.Predicates;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
-import com.google.common.base.Throwables;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.util.concurrent.CheckedFuture;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
-import java.math.BigInteger;
import java.net.URI;
import java.net.URISyntaxException;
+import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
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 java.util.concurrent.CancellationException;
import java.util.concurrent.CountDownLatch;
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.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime;
+import org.opendaylight.yang.gen.v1.urn.sal.restconf.event.subscription.rev140708.NotificationOutputTypeGrouping.NotificationOutputType;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.QNameModule;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
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.api.schema.LeafSetEntryNode;
import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
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.api.schema.tree.ModifiedNodeDoesNotExistException;
import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.ListNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeAttrBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafNodeBuilder;
import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.model.api.SchemaNode;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveSchemaContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final String SCOPE_PARAM_NAME = "scope";
+ private static final String OUTPUT_TYPE_PARAM_NAME = "notification-output-type";
+
private static final String NETCONF_BASE = "urn:ietf:params:xml:ns:netconf:base:1.0";
private static final String NETCONF_BASE_PAYLOAD_NAME = "data";
static {
try {
final Date eventSubscriptionAugRevision = new SimpleDateFormat("yyyy-MM-dd").parse("2014-07-08");
- NETCONF_BASE_QNAME = QName.create(QNameModule.create(new URI(NETCONF_BASE), null), NETCONF_BASE_PAYLOAD_NAME );
+ NETCONF_BASE_QNAME = QName.create(QNameModule.create(new URI(NETCONF_BASE), null),
+ NETCONF_BASE_PAYLOAD_NAME);
SAL_REMOTE_AUGMENT = QNameModule.create(NAMESPACE_EVENT_SUBSCRIPTION_AUGMENT,
eventSubscriptionAugRevision);
- SAL_REMOTE_AUG_IDENTIFIER = new YangInstanceIdentifier.AugmentationIdentifier(Sets.newHashSet(QName.create(SAL_REMOTE_AUGMENT, "scope"),
- QName.create(SAL_REMOTE_AUGMENT, "datastore")));
+ SAL_REMOTE_AUG_IDENTIFIER = new YangInstanceIdentifier.AugmentationIdentifier(Sets.newHashSet(
+ QName.create(SAL_REMOTE_AUGMENT, "scope"),
+ QName.create(SAL_REMOTE_AUGMENT, "datastore"),
+ QName.create(SAL_REMOTE_AUGMENT, "notification-output-type")));
} catch (final ParseException e) {
final String errMsg = "It wasn't possible to convert revision date of sal-remote-augment to date";
LOG.debug(errMsg);
throw new RestconfDocumentedException(errMsg, ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
}
- final InstanceIdentifierContext<?> mountPointIdentifier = this.controllerContext.toMountPointIdentifier(identifier);
+ final InstanceIdentifierContext<?> mountPointIdentifier = this.controllerContext
+ .toMountPointIdentifier(identifier);
final DOMMountPoint mountPoint = mountPointIdentifier.getMountPoint();
final Set<Module> modules = this.controllerContext.getAllModules(mountPoint);
final MapNode mountPointModulesMap = makeModuleMapNode(modules);
DOMMountPoint mountPoint = null;
final SchemaContext schemaContext;
if (identifier.contains(ControllerContext.MOUNT)) {
- final InstanceIdentifierContext<?> mountPointIdentifier = this.controllerContext.toMountPointIdentifier(identifier);
+ final InstanceIdentifierContext<?> mountPointIdentifier = this.controllerContext
+ .toMountPointIdentifier(identifier);
mountPoint = mountPointIdentifier.getMountPoint();
module = this.controllerContext.findModuleByNameAndRevision(mountPoint, moduleNameAndRevision);
schemaContext = mountPoint.getSchemaContext();
final SchemaContext schemaContext = this.controllerContext.getGlobalSchema();
final Set<String> availableStreams = Notificator.getStreamNames();
final Module restconfModule = getRestconfModule();
- final DataSchemaNode streamSchemaNode = this.controllerContext.getRestconfModuleRestConfSchemaNode(restconfModule,
- Draft02.RestConfModule.STREAM_LIST_SCHEMA_NODE);
+ final DataSchemaNode streamSchemaNode = this.controllerContext
+ .getRestconfModuleRestConfSchemaNode(restconfModule, Draft02.RestConfModule.STREAM_LIST_SCHEMA_NODE);
Preconditions.checkState(streamSchemaNode instanceof ListSchemaNode);
final CollectionNodeBuilder<MapEntryNode, MapNode> listStreamsBuilder = Builders
Set<Module> modules = null;
DOMMountPoint mountPoint = null;
if (identifier.contains(ControllerContext.MOUNT)) {
- final InstanceIdentifierContext<?> mountPointIdentifier = this.controllerContext.toMountPointIdentifier(identifier);
+ final InstanceIdentifierContext<?> mountPointIdentifier = this.controllerContext
+ .toMountPointIdentifier(identifier);
mountPoint = mountPointIdentifier.getMountPoint();
modules = this.controllerContext.getAllModules(mountPoint);
} else {
- final String errMsg = "URI has bad format. If operations behind mount point should be showed, URI has to end with ";
+ final String errMsg = "URI has bad format. If operations behind mount point should be showed, URI has to "
+ + "end with ";
LOG.debug(errMsg + ControllerContext.MOUNT + " for " + identifier);
- throw new RestconfDocumentedException(errMsg + ControllerContext.MOUNT, ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
+ throw new RestconfDocumentedException(errMsg + ControllerContext.MOUNT, ErrorType.PROTOCOL,
+ ErrorTag.INVALID_VALUE);
}
return operationsFromModulesToNormalizedContext(modules, mountPoint);
}
+ /**
+ * Special case only for GET restconf/operations use (since moment of pre-Beryllium
+ * Yang parser and Yang model API removal). The method is creating fake
+ * schema context with fake module and fake data by use own implementations
+ * of schema nodes and module.
+ *
+ * @param modules
+ * - set of modules for get RPCs from every module
+ * @param mountPoint
+ * - mount point, if in use otherwise null
+ * @return {@link NormalizedNodeContext}
+ */
private NormalizedNodeContext operationsFromModulesToNormalizedContext(final Set<Module> modules,
final DOMMountPoint mountPoint) {
- throw new UnsupportedOperationException();
+
+ final ContainerSchemaNodeImpl fakeCont = new ContainerSchemaNodeImpl();
+ final List<LeafNode<Object>> listRpcNodes = new ArrayList<>();
+ for (final Module m : modules) {
+ for (final RpcDefinition rpc : m.getRpcs()) {
+
+ final LeafSchemaNode fakeLeaf = new LeafSchemaNodeImpl(fakeCont.getPath(),
+ QName.create(ModuleImpl.moduleQName, m.getName() + ":" + rpc.getQName().getLocalName()));
+ fakeCont.addNodeChild(fakeLeaf);
+ listRpcNodes.add(Builders.leafBuilder(fakeLeaf).build());
+ }
+ }
+ final ContainerSchemaNode fakeContSchNode = fakeCont;
+ final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> containerBuilder = Builders
+ .containerBuilder(fakeContSchNode);
+
+ for (final LeafNode<Object> rpcNode : listRpcNodes) {
+ containerBuilder.withChild(rpcNode);
+ }
+
+ final Module fakeModule = new ModuleImpl(fakeContSchNode);
+
+ final Set<Module> fakeModules = new HashSet<>();
+ fakeModules.add(fakeModule);
+ final SchemaContext fakeSchemaCtx = EffectiveSchemaContext.resolveSchemaContext(fakeModules);
+ final InstanceIdentifierContext<ContainerSchemaNode> instanceIdentifierContext =
+ new InstanceIdentifierContext<>(null, fakeContSchNode, mountPoint, fakeSchemaCtx);
+ return new NormalizedNodeContext(instanceIdentifierContext, containerBuilder.build());
}
private Module getRestconfModule() {
}
@Override
- public NormalizedNodeContext invokeRpc(final String identifier, final NormalizedNodeContext payload, final UriInfo uriInfo) {
+ public NormalizedNodeContext invokeRpc(final String identifier, final NormalizedNodeContext payload,
+ final UriInfo uriInfo) {
final SchemaPath type = payload.getInstanceIdentifierContext().getSchemaNode().getPath();
final URI namespace = payload.getInstanceIdentifierContext().getSchemaNode().getQName().getNamespace();
final CheckedFuture<DOMRpcResult, DOMRpcException> response;
throw new RestconfDocumentedException(cause.getMessage(), ErrorType.PROTOCOL,
ErrorTag.INVALID_VALUE);
} else if (cause instanceof DOMRpcImplementationNotAvailableException) {
- throw new RestconfDocumentedException(cause.getMessage(), ErrorType.APPLICATION, ErrorTag.OPERATION_NOT_SUPPORTED);
+ throw new RestconfDocumentedException(cause.getMessage(), ErrorType.APPLICATION,
+ ErrorTag.OPERATION_NOT_SUPPORTED);
}
- throw new RestconfDocumentedException("The operation encountered an unexpected error while executing.",cause);
+ throw new RestconfDocumentedException("The operation encountered an unexpected error while executing.",
+ cause);
} else {
- throw new RestconfDocumentedException("The operation encountered an unexpected error while executing.",e);
+ throw new RestconfDocumentedException("The operation encountered an unexpected error while executing.",
+ e);
}
} catch (final CancellationException e) {
final String errMsg = "The operation was cancelled while executing.";
// did not expect any input
throw new RestconfDocumentedException("No input expected.", ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE);
}
- // else
- // {
- // TODO: Validate "mandatory" and "config" values here??? Or should those be
- // those be
- // validate in a more central location inside MD-SAL core.
- // }
}
- private CheckedFuture<DOMRpcResult, DOMRpcException> invokeSalRemoteRpcSubscribeRPC(final NormalizedNodeContext payload) {
+ private CheckedFuture<DOMRpcResult, DOMRpcException>
+ invokeSalRemoteRpcSubscribeRPC(final NormalizedNodeContext payload) {
final ContainerNode value = (ContainerNode) payload.getData();
final QName rpcQName = payload.getInstanceIdentifierContext().getSchemaNode().getQName();
final Optional<DataContainerChild<? extends PathArgument, ?>> path = value.getChild(new NodeIdentifier(
final YangInstanceIdentifier pathIdentifier = ((YangInstanceIdentifier) pathValue);
String streamName = (String) CREATE_DATA_SUBSCR;
+ NotificationOutputType outputType = null;
if (!pathIdentifier.isEmpty()) {
final String fullRestconfIdentifier = DATA_SUBSCR
+ this.controllerContext.toFullRestconfIdentifier(pathIdentifier, null);
- LogicalDatastoreType datastore = parseEnumTypeParameter(value, LogicalDatastoreType.class, DATASTORE_PARAM_NAME);
+ LogicalDatastoreType datastore =
+ parseEnumTypeParameter(value, LogicalDatastoreType.class, DATASTORE_PARAM_NAME);
datastore = datastore == null ? DEFAULT_DATASTORE : datastore;
DataChangeScope scope = parseEnumTypeParameter(value, DataChangeScope.class, SCOPE_PARAM_NAME);
scope = scope == null ? DEFAULT_SCOPE : scope;
+ outputType = parseEnumTypeParameter(value, NotificationOutputType.class,
+ OUTPUT_TYPE_PARAM_NAME);
+ outputType = outputType == null ? NotificationOutputType.XML : outputType;
+
streamName = Notificator.createStreamNameFromUri(fullRestconfIdentifier + "/datastore=" + datastore
+ "/scope=" + scope);
}
final QName outputQname = QName.create(rpcQName, "output");
final QName streamNameQname = QName.create(rpcQName, "stream-name");
- final ContainerNode output = ImmutableContainerNodeBuilder.create().withNodeIdentifier(new NodeIdentifier(outputQname))
- .withChild(ImmutableNodes.leafNode(streamNameQname, streamName)).build();
+ final ContainerNode output =
+ ImmutableContainerNodeBuilder.create().withNodeIdentifier(new NodeIdentifier(outputQname))
+ .withChild(ImmutableNodes.leafNode(streamNameQname, streamName)).build();
if (!Notificator.existListenerFor(streamName)) {
- Notificator.createListener(pathIdentifier, streamName);
+ Notificator.createListener(pathIdentifier, streamName, outputType);
}
final DOMRpcResult defaultDOMRpcResult = new DefaultDOMRpcResult(output);
try {
waiter.await();
- } catch (final InterruptedException e) {
+ } catch (final Exception e) {
final String msg = "Problem while waiting for response";
LOG.warn(msg);
throw new RestconfDocumentedException(msg, e);
if ( ! uriKeyValue.equals(dataKeyValue)) {
final String errMsg = "The value '" + uriKeyValue + "' for key '" + keyDefinition.getLocalName() +
- "' specified in the URI doesn't match the value '" + dataKeyValue + "' specified in the message body. ";
+ "' specified in the URI doesn't match the value '" + dataKeyValue
+ + "' specified in the message body. ";
throw new RestconfDocumentedException(errMsg, ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
}
}
}
@Override
- public Response createConfigurationData(final String identifier, final NormalizedNodeContext payload, final UriInfo uriInfo) {
+ public Response createConfigurationData(final String identifier, final NormalizedNodeContext payload,
+ final UriInfo uriInfo) {
return createConfigurationData(payload, uriInfo);
}
try {
waiter.await();
- } catch (final InterruptedException e) {
+ } catch (final Exception e) {
final String msg = "Problem while waiting for response";
LOG.warn(msg);
throw new RestconfDocumentedException(msg, e);
}
}
- private URI resolveLocation(final UriInfo uriInfo, final String uriBehindBase, final DOMMountPoint mountPoint, final YangInstanceIdentifier normalizedII) {
+ private URI resolveLocation(final UriInfo uriInfo, final String uriBehindBase, final DOMMountPoint mountPoint,
+ final YangInstanceIdentifier normalizedII) {
if(uriInfo == null) {
// This is null if invoked internally
return null;
final DOMMountPoint mountPoint = iiWithData.getMountPoint();
final YangInstanceIdentifier normalizedII = iiWithData.getInstanceIdentifier();
- CheckedFuture<Void, TransactionCommitFailedException> future;
+ final CheckedFuture<Void, TransactionCommitFailedException> future;
if (mountPoint != null) {
future = this.broker.commitConfigurationDataDelete(mountPoint, normalizedII);
} else {
try {
waiter.await();
- } catch (final InterruptedException e) {
+ } catch (final Exception e) {
final String msg = "Problem while waiting for response";
LOG.warn(msg);
throw new RestconfDocumentedException(msg, e);
}
+
return Response.status(Status.OK).build();
}
protected void handlerLoggerDelete(final Throwable t) {
if (t != null) {
- final Optional<Throwable> searchedException = Iterables.tryFind(Throwables.getCausalChain(t),
- Predicates.instanceOf(ModifiedNodeDoesNotExistException.class));
- if (searchedException.isPresent()) {
- throw new RestconfDocumentedException("Data specified for deleting doesn't exist.", ErrorType.APPLICATION, ErrorTag.DATA_MISSING);
- }
final String errMsg = "Error while deleting data";
LOG.info(errMsg, t);
throw new RestconfDocumentedException(errMsg, t);
* </ul>
*/
@Override
- public Response subscribeToStream(final String identifier, final UriInfo uriInfo) {
+ public NormalizedNodeContext subscribeToStream(final String identifier, final UriInfo uriInfo) {
+ boolean startTime_used = false;
+ boolean stopTime_used = false;
+ boolean filter_used = false;
+ Date start = null;
+ Date stop = null;
+ String filter = null;
+
+ for (final Entry<String, List<String>> entry : uriInfo.getQueryParameters().entrySet()) {
+ switch (entry.getKey()) {
+ case "start-time":
+ if (!startTime_used) {
+ startTime_used = true;
+ start = parseDateFromQueryParam(entry);
+ } else {
+ throw new RestconfDocumentedException("Start-time parameter can be used only once.");
+ }
+ break;
+ case "stop-time":
+ if (!stopTime_used) {
+ stopTime_used = true;
+ stop = parseDateFromQueryParam(entry);
+ } else {
+ throw new RestconfDocumentedException("Stop-time parameter can be used only once.");
+ }
+ break;
+ case "filter":
+ if (!filter_used) {
+ filter_used = true;
+ filter = entry.getValue().iterator().next();
+ } else {
+ throw new RestconfDocumentedException("Filter parameter can be used only once.");
+ }
+ break;
+ default:
+ throw new RestconfDocumentedException("Bad parameter used with notifications: " + entry.getKey());
+ }
+ }
+ if(!startTime_used && stopTime_used){
+ throw new RestconfDocumentedException("Stop-time parameter has to be used with start-time parameter.");
+ }
+ URI response = null;
if (identifier.contains(DATA_SUBSCR)) {
- return dataSubs(identifier, uriInfo);
+ response = dataSubs(identifier, uriInfo, start, stop, filter);
} else if (identifier.contains(NOTIFICATION_STREAM)) {
- return notifStream(identifier, uriInfo);
+ response = notifStream(identifier, uriInfo, start, stop, filter);
+ }
+
+ if(response != null){
+ // prepare node with value of location
+ final InstanceIdentifierContext<?> iid = prepareIIDSubsStreamOutput();
+ final NormalizedNodeAttrBuilder<NodeIdentifier, Object, LeafNode<Object>> builder = ImmutableLeafNodeBuilder
+ .create().withValue(response.toString());
+ builder.withNodeIdentifier(
+ NodeIdentifier.create(QName.create("subscribe:to:notification", "2016-10-28", "location")));
+
+ // prepare new header with location
+ final Map<String, Object> headers = new HashMap<>();
+ headers.put("Location", response);
+
+ return new NormalizedNodeContext(iid, builder.build(), headers);
}
+
final String msg = "Bad type of notification of sal-remote";
LOG.warn(msg);
throw new RestconfDocumentedException(msg);
}
+ private Date parseDateFromQueryParam(final Entry<String, List<String>> entry) {
+ final DateAndTime event = new DateAndTime(entry.getValue().iterator().next());
+ String numOf_ms = "";
+ final String value = event.getValue();
+ if (value.contains(".")) {
+ numOf_ms = numOf_ms + ".";
+ final int lastChar = value.contains("Z") ? value.indexOf("Z") : (value.contains("+") ? value.indexOf("+")
+ : (value.contains("-") ? value.indexOf("-") : value.length()));
+ for (int i = 0; i < (lastChar - value.indexOf(".") - 1); i++) {
+ numOf_ms = numOf_ms + "S";
+ }
+ }
+ String zone = "";
+ if (!value.contains("Z")) {
+ zone = zone + "XXX";
+ }
+ final DateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss" + numOf_ms + zone);
+
+ try {
+ return dateFormatter.parse(value.contains("Z") ? value.replace('T', ' ').substring(0, value.indexOf("Z"))
+ : value.replace('T', ' '));
+ } catch (final ParseException e) {
+ throw new RestconfDocumentedException("Cannot parse of value in date: " + value + e);
+ }
+ }
+
+ /**
+ * @return {@link InstanceIdentifierContext} of location leaf for
+ * notification
+ */
+ private InstanceIdentifierContext<?> prepareIIDSubsStreamOutput() {
+ final QName qnameBase = QName.create("subscribe:to:notification", "2016-10-28", "notifi");
+ final SchemaContext schemaCtx = ControllerContext.getInstance().getGlobalSchema();
+ final DataSchemaNode location = ((ContainerSchemaNode) schemaCtx
+ .findModuleByNamespaceAndRevision(qnameBase.getNamespace(), qnameBase.getRevision())
+ .getDataChildByName(qnameBase)).getDataChildByName(QName.create(qnameBase, "location"));
+ final List<PathArgument> path = new ArrayList<>();
+ path.add(NodeIdentifier.create(qnameBase));
+ path.add(NodeIdentifier.create(QName.create(qnameBase, "location")));
+
+ return new InstanceIdentifierContext<SchemaNode>(YangInstanceIdentifier.create(path), location, null,
+ schemaCtx);
+ }
+
/**
* Register notification listener by stream name
*
* - stream name
* @param uriInfo
* - uriInfo
- * @return {@link Response}
+ * @param stop
+ * - stop-time of getting notification
+ * @param start
+ * - start-time of getting notification
+ * @param filter
+ * - indicate wh ich subset of allpossible events are of interest
+ * @return {@link URI} of location
*/
- private Response notifStream(final String identifier, final UriInfo uriInfo) {
+ private URI notifStream(final String identifier, final UriInfo uriInfo, final Date start, final Date stop,
+ final String filter) {
final String streamName = Notificator.createStreamNameFromUri(identifier);
if (Strings.isNullOrEmpty(streamName)) {
throw new RestconfDocumentedException("Stream name is empty.", ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
for (final NotificationListenerAdapter listener : listeners) {
this.broker.registerToListenNotification(listener);
+ listener.setQueryParams(start, stop, filter);
}
final UriBuilder uriBuilder = uriInfo.getAbsolutePathBuilder();
final UriBuilder uriToWebsocketServerBuilder = uriBuilder.port(notificationPort).scheme("ws");
final URI uriToWebsocketServer = uriToWebsocketServerBuilder.replacePath(streamName).build();
- return Response.status(Status.OK).location(uriToWebsocketServer).build();
+ return uriToWebsocketServer;
}
/**
* - stream name
* @param uriInfo
* - uri info
- * @return {@link Response}
+ * @param stop
+ * - start-time of getting notification
+ * @param start
+ * - stop-time of getting notification
+ * @param filter
+ * - indicate which subset of all possible events are of interest
+ * @return {@link URI} of location
*/
- private Response dataSubs(final String identifier, final UriInfo uriInfo) {
+ private URI dataSubs(final String identifier, final UriInfo uriInfo, final Date start, final Date stop,
+ final String filter) {
final String streamName = Notificator.createStreamNameFromUri(identifier);
if (Strings.isNullOrEmpty(streamName)) {
throw new RestconfDocumentedException("Stream name is empty.", ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
if (listener == null) {
throw new RestconfDocumentedException("Stream was not found.", ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT);
}
+ listener.setQueryParams(start, stop, filter);
final Map<String, String> paramToValues = resolveValuesFromUri(identifier);
final LogicalDatastoreType datastore = parserURIEnumParameter(LogicalDatastoreType.class,
final UriBuilder uriToWebsocketServerBuilder = uriBuilder.port(notificationPort).scheme("ws");
final URI uriToWebsocketServer = uriToWebsocketServerBuilder.replacePath(streamName).build();
- return Response.status(Status.OK).location(uriToWebsocketServer).build();
+ return uriToWebsocketServer;
}
@Override
- public PATCHStatusContext patchConfigurationData(final String identifier, final PATCHContext context, final UriInfo uriInfo) {
+ public PATCHStatusContext patchConfigurationData(final String identifier, final PATCHContext context,
+ final UriInfo uriInfo) {
if (context == null) {
throw new RestconfDocumentedException("Input is required.", ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE);
}
try {
- return this.broker.patchConfigurationDataWithinTransaction(context,
- this.controllerContext.getGlobalSchema());
- } catch (final InterruptedException e) {
+ return this.broker.patchConfigurationDataWithinTransaction(context);
+ } catch (final Exception e) {
LOG.debug("Patch transaction failed", e);
throw new RestconfDocumentedException(e.getMessage());
}
}
try {
- return this.broker.patchConfigurationDataWithinTransaction(context,
- this.controllerContext.getGlobalSchema());
- } catch (final InterruptedException e) {
+ return this.broker.patchConfigurationDataWithinTransaction(context);
+ } catch (final Exception e) {
LOG.debug("Patch transaction failed", e);
throw new RestconfDocumentedException(e.getMessage());
}
return null;
}
final Optional<DataContainerChild<? extends PathArgument, ?>> enumNode =
- ((AugmentationNode) augNode.get()).getChild(new NodeIdentifier(QName.create(SAL_REMOTE_AUGMENT, paramName)));
+ ((AugmentationNode) augNode.get())
+ .getChild(new NodeIdentifier(QName.create(SAL_REMOTE_AUGMENT, paramName)));
if (!enumNode.isPresent()) {
return null;
}
return result;
}
- public BigInteger getOperationalReceived() {
- // TODO Auto-generated method stub
- return null;
- }
-
private MapNode makeModuleMapNode(final Set<Module> modules) {
Preconditions.checkNotNull(modules);
final Module restconfModule = getRestconfModule();