use of org.opendaylight.restconf.common.errors.RestconfDocumentedException in project netconf by opendaylight.
the class SubscribeToStreamUtil method subscribeToYangStream.
/**
* Register listener by streamName in identifier to listen to yang notifications, and put or delete information
* about listener to DS according to ietf-restconf-monitoring.
*
* @param identifier Name of the stream.
* @param uriInfo URI information.
* @param notificationQueryParams Query parameters of notification.
* @param handlersHolder Holder of handlers for notifications.
* @return Stream location for listening.
*/
@NonNull
final URI subscribeToYangStream(final String identifier, final UriInfo uriInfo, final NotificationQueryParams notificationQueryParams, final HandlersHolder handlersHolder) {
final String streamName = ListenersBroker.createStreamNameFromUri(identifier);
if (isNullOrEmpty(streamName)) {
throw new RestconfDocumentedException("Stream name is empty.", ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
}
final NotificationListenerAdapter notificationListenerAdapter = ListenersBroker.getInstance().getNotificationListenerFor(streamName).orElseThrow(() -> new RestconfDocumentedException(String.format("Stream with name %s was not found.", streamName), ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT));
final EffectiveModelContext schemaContext = handlersHolder.getSchemaHandler().get();
final URI uri = prepareUriByStreamName(uriInfo, streamName);
notificationListenerAdapter.setQueryParams(notificationQueryParams);
notificationListenerAdapter.listen(handlersHolder.getNotificationServiceHandler());
final DOMDataBroker dataBroker = handlersHolder.getDataBroker();
notificationListenerAdapter.setCloseVars(dataBroker, handlersHolder.getSchemaHandler());
final MapEntryNode mapToStreams = RestconfMappingNodeUtil.mapYangNotificationStreamByIetfRestconfMonitoring(notificationListenerAdapter.getSchemaPath().lastNodeIdentifier(), schemaContext.getNotifications(), notificationListenerAdapter.getStart(), notificationListenerAdapter.getOutputType(), uri);
// FIXME: how does this correlate with the transaction notificationListenerAdapter.close() will do?
final DOMDataTreeWriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
writeDataToDS(writeTransaction, mapToStreams);
submitData(writeTransaction);
return uri;
}
use of org.opendaylight.restconf.common.errors.RestconfDocumentedException in project netconf by opendaylight.
the class RestconfImpl method invokeRpc.
@SuppressFBWarnings(value = "NP_LOAD_OF_KNOWN_NULL_VALUE", justification = "Looks like a false positive, see below FIXME")
private NormalizedNodeContext invokeRpc(final String identifier, final UriInfo uriInfo) {
final DOMMountPoint mountPoint;
final String identifierEncoded;
final EffectiveModelContext schemaContext;
if (identifier.contains(ControllerContext.MOUNT)) {
// mounted RPC call - look up mount instance.
final InstanceIdentifierContext<?> mountPointId = controllerContext.toMountPointIdentifier(identifier);
mountPoint = mountPointId.getMountPoint();
schemaContext = modelContext(mountPoint);
final int startOfRemoteRpcName = identifier.lastIndexOf(ControllerContext.MOUNT) + ControllerContext.MOUNT.length() + 1;
final String remoteRpcName = identifier.substring(startOfRemoteRpcName);
identifierEncoded = remoteRpcName;
} else if (identifier.indexOf('/') == CHAR_NOT_FOUND) {
identifierEncoded = identifier;
mountPoint = null;
schemaContext = controllerContext.getGlobalSchema();
} else {
LOG.debug("Identifier {} cannot contain slash character (/).", identifier);
throw new RestconfDocumentedException(String.format("Identifier %n%s%ncan\'t contain slash character (/).%n" + "If slash is part of identifier name then use %%2F placeholder.", identifier), ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
}
final String identifierDecoded = ControllerContext.urlPathArgDecode(identifierEncoded);
final RpcDefinition rpc;
if (mountPoint == null) {
rpc = controllerContext.getRpcDefinition(identifierDecoded);
} else {
rpc = findRpc(modelContext(mountPoint), identifierDecoded);
}
if (rpc == null) {
LOG.debug("RPC {} does not exist.", identifierDecoded);
throw new RestconfDocumentedException("RPC does not exist.", ErrorType.RPC, ErrorTag.UNKNOWN_ELEMENT);
}
if (!rpc.getInput().getChildNodes().isEmpty()) {
LOG.debug("No input specified for RPC {} with an input section", rpc);
throw new RestconfDocumentedException("No input specified for RPC " + rpc + " with an input section defined", ErrorType.RPC, ErrorTag.MISSING_ELEMENT);
}
final ContainerNode input = defaultInput(rpc.getQName());
final ListenableFuture<? extends DOMRpcResult> response;
if (mountPoint != null) {
final Optional<DOMRpcService> mountRpcServices = mountPoint.getService(DOMRpcService.class);
if (mountRpcServices.isEmpty()) {
throw new RestconfDocumentedException("Rpc service is missing.");
}
response = mountRpcServices.get().invokeRpc(rpc.getQName(), input);
} else {
response = broker.invokeRpc(rpc.getQName(), input);
}
final NormalizedNode result = checkRpcResponse(response).getResult();
if (result != null && ((ContainerNode) result).isEmpty()) {
throw new WebApplicationException(Response.Status.NO_CONTENT);
}
// doing that work.
return new NormalizedNodeContext(new InstanceIdentifierContext<>(null, rpc, mountPoint, schemaContext), result, QueryParametersParser.parseWriterParameters(uriInfo));
}
use of org.opendaylight.restconf.common.errors.RestconfDocumentedException in project netconf by opendaylight.
the class RestconfImpl method notifStream.
/**
* Register notification listener by stream name.
*
* @param identifier
* stream name
* @param uriInfo
* uriInfo
* @param stop
* stop-time of getting notification
* @param start
* start-time of getting notification
* @param filter
* indicate which subset of all possible events are of interest
* @return {@link URI} of location
*/
private URI notifStream(final String identifier, final UriInfo uriInfo, final Instant start, final Instant 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);
}
final List<NotificationListenerAdapter> listeners = Notificator.getNotificationListenerFor(streamName);
if (listeners == null || listeners.isEmpty()) {
throw new RestconfDocumentedException("Stream was not found.", ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT);
}
for (final NotificationListenerAdapter listener : listeners) {
broker.registerToListenNotification(listener);
listener.setQueryParams(start, Optional.ofNullable(stop), Optional.ofNullable(filter), false, false);
}
final UriBuilder uriBuilder = uriInfo.getAbsolutePathBuilder();
final WebSocketServer webSocketServerInstance = WebSocketServer.getInstance(NOTIFICATION_PORT);
final int notificationPort = webSocketServerInstance.getPort();
final UriBuilder uriToWebsocketServerBuilder = uriBuilder.port(notificationPort).scheme(getWsScheme(uriInfo));
return uriToWebsocketServerBuilder.replacePath(streamName).build();
}
use of org.opendaylight.restconf.common.errors.RestconfDocumentedException in project netconf by opendaylight.
the class RestconfImpl method getModule.
@Override
@Deprecated
public NormalizedNodeContext getModule(final String identifier, final UriInfo uriInfo) {
final Entry<String, Revision> nameRev = getModuleNameAndRevision(requireNonNull(identifier));
Module module = null;
DOMMountPoint mountPoint = null;
final EffectiveModelContext schemaContext;
if (identifier.contains(ControllerContext.MOUNT)) {
final InstanceIdentifierContext<?> mountPointIdentifier = controllerContext.toMountPointIdentifier(identifier);
mountPoint = mountPointIdentifier.getMountPoint();
module = controllerContext.findModuleByNameAndRevision(mountPoint, nameRev.getKey(), nameRev.getValue());
schemaContext = modelContext(mountPoint);
} else {
module = controllerContext.findModuleByNameAndRevision(nameRev.getKey(), nameRev.getValue());
schemaContext = controllerContext.getGlobalSchema();
}
if (module == null) {
LOG.debug("Module with name '{}' and revision '{}' was not found.", nameRev.getKey(), nameRev.getValue());
throw new RestconfDocumentedException("Module with name '" + nameRev.getKey() + "' and revision '" + nameRev.getValue() + "' was not found.", ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT);
}
final Module restconfModule = getRestconfModule();
final Set<Module> modules = Collections.singleton(module);
final MapNode moduleMap = makeModuleMapNode(modules);
final DataSchemaNode moduleSchemaNode = controllerContext.getRestconfModuleRestConfSchemaNode(restconfModule, RestConfModule.MODULE_LIST_SCHEMA_NODE);
checkState(moduleSchemaNode instanceof ListSchemaNode);
return new NormalizedNodeContext(new InstanceIdentifierContext<>(MODULE, moduleSchemaNode, mountPoint, schemaContext), moduleMap, QueryParametersParser.parseWriterParameters(uriInfo));
}
use of org.opendaylight.restconf.common.errors.RestconfDocumentedException in project netconf by opendaylight.
the class RestconfImpl method invokeRpc.
@Override
public NormalizedNodeContext invokeRpc(final String identifier, final NormalizedNodeContext payload, final UriInfo uriInfo) {
if (payload == null) {
// no payload specified, reroute this to no payload invokeRpc implementation
return invokeRpc(identifier, uriInfo);
}
final SchemaNode schema = payload.getInstanceIdentifierContext().getSchemaNode();
final ListenableFuture<? extends DOMRpcResult> response;
final DOMMountPoint mountPoint = payload.getInstanceIdentifierContext().getMountPoint();
final NormalizedNode input = nonnullInput(schema, payload.getData());
final EffectiveModelContext schemaContext;
if (mountPoint != null) {
final Optional<DOMRpcService> mountRpcServices = mountPoint.getService(DOMRpcService.class);
if (mountRpcServices.isEmpty()) {
LOG.debug("Error: Rpc service is missing.");
throw new RestconfDocumentedException("Rpc service is missing.");
}
schemaContext = modelContext(mountPoint);
response = mountRpcServices.get().invokeRpc(schema.getQName(), input);
} else {
final XMLNamespace namespace = schema.getQName().getNamespace();
if (namespace.toString().equals(SAL_REMOTE_NAMESPACE)) {
if (identifier.contains(CREATE_DATA_SUBSCR)) {
response = invokeSalRemoteRpcSubscribeRPC(payload);
} else if (identifier.contains(CREATE_NOTIFICATION_STREAM)) {
response = invokeSalRemoteRpcNotifiStrRPC(payload);
} else {
final String msg = "Not supported operation";
LOG.warn(msg);
throw new RestconfDocumentedException(msg, ErrorType.RPC, ErrorTag.OPERATION_NOT_SUPPORTED);
}
} else {
response = broker.invokeRpc(schema.getQName(), input);
}
schemaContext = controllerContext.getGlobalSchema();
}
final DOMRpcResult result = checkRpcResponse(response);
RpcDefinition resultNodeSchema = null;
final NormalizedNode resultData;
if (result != null && result.getResult() != null) {
resultData = result.getResult();
resultNodeSchema = (RpcDefinition) payload.getInstanceIdentifierContext().getSchemaNode();
} else {
resultData = null;
}
if (resultData != null && ((ContainerNode) resultData).isEmpty()) {
throw new WebApplicationException(Response.Status.NO_CONTENT);
} else {
return new NormalizedNodeContext(new InstanceIdentifierContext<>(null, resultNodeSchema, mountPoint, schemaContext), resultData, QueryParametersParser.parseWriterParameters(uriInfo));
}
}
Aggregations