use of org.opendaylight.restconf.common.errors.RestconfDocumentedException in project netconf by opendaylight.
the class QueryParametersParser method parseWriterParameters.
public static WriterParameters parseWriterParameters(final UriInfo info) {
final WriterParameters.WriterParametersBuilder wpBuilder = new WriterParameters.WriterParametersBuilder();
if (info == null) {
return wpBuilder.build();
}
String param = info.getQueryParameters(false).getFirst(UriParameters.DEPTH.toString());
if (!Strings.isNullOrEmpty(param) && !"unbounded".equals(param)) {
try {
final int depth = Integer.parseInt(param);
if (depth < 1) {
throw new RestconfDocumentedException(new RestconfError(ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE, "Invalid depth parameter: " + depth, null, "The depth parameter must be an integer > 1 or \"unbounded\""));
}
wpBuilder.setDepth(depth);
} catch (final NumberFormatException e) {
throw new RestconfDocumentedException(e, new RestconfError(ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE, "Invalid depth parameter: " + e.getMessage(), null, "The depth parameter must be an integer > 1 or \"unbounded\""));
}
}
param = info.getQueryParameters(false).getFirst(UriParameters.PRETTY_PRINT.toString());
wpBuilder.setPrettyPrint("true".equals(param));
return wpBuilder.build();
}
use of org.opendaylight.restconf.common.errors.RestconfDocumentedException in project netconf by opendaylight.
the class RestconfImpl method parseDateFromQueryParam.
private static Instant parseDateFromQueryParam(final Entry<String, List<String>> entry) {
final DateAndTime event = new DateAndTime(entry.getValue().iterator().next());
final String value = event.getValue();
final TemporalAccessor p;
try {
p = FORMATTER.parse(value);
} catch (final DateTimeParseException e) {
throw new RestconfDocumentedException("Cannot parse of value in date: " + value, e);
}
return Instant.from(p);
}
use of org.opendaylight.restconf.common.errors.RestconfDocumentedException in project netconf by opendaylight.
the class RestconfImpl method createConfigurationData.
@Override
public Response createConfigurationData(final NormalizedNodeContext payload, final UriInfo uriInfo) {
if (payload == null) {
throw new RestconfDocumentedException("Input is required.", ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE);
}
final DOMMountPoint mountPoint = payload.getInstanceIdentifierContext().getMountPoint();
final InstanceIdentifierContext<?> iiWithData = payload.getInstanceIdentifierContext();
final YangInstanceIdentifier normalizedII = iiWithData.getInstanceIdentifier();
boolean insertUsed = false;
boolean pointUsed = false;
String insert = null;
String point = null;
if (uriInfo != null) {
for (final Entry<String, List<String>> entry : uriInfo.getQueryParameters().entrySet()) {
switch(entry.getKey()) {
case "insert":
if (!insertUsed) {
insertUsed = true;
insert = entry.getValue().iterator().next();
} else {
throw new RestconfDocumentedException("Insert parameter can be used only once.");
}
break;
case "point":
if (!pointUsed) {
pointUsed = true;
point = entry.getValue().iterator().next();
} else {
throw new RestconfDocumentedException("Point parameter can be used only once.");
}
break;
default:
throw new RestconfDocumentedException("Bad parameter for post: " + entry.getKey());
}
}
}
if (pointUsed && !insertUsed) {
throw new RestconfDocumentedException("Point parameter can't be used without Insert parameter.");
}
if (pointUsed && (insert.equals("first") || insert.equals("last"))) {
throw new RestconfDocumentedException("Point parameter can be used only with 'after' or 'before' values of Insert parameter.");
}
FluentFuture<? extends CommitInfo> future;
if (mountPoint != null) {
future = broker.commitConfigurationDataPost(mountPoint, normalizedII, payload.getData(), insert, point);
} else {
future = broker.commitConfigurationDataPost(controllerContext.getGlobalSchema(), normalizedII, payload.getData(), insert, point);
}
try {
future.get();
} catch (final InterruptedException e) {
LOG.info("Error creating data {}", uriInfo != null ? uriInfo.getPath() : "", e);
throw new RestconfDocumentedException(e.getMessage(), e);
} catch (final ExecutionException e) {
LOG.info("Error creating data {}", uriInfo != null ? uriInfo.getPath() : "", e);
throw RestconfDocumentedException.decodeAndThrow(e.getMessage(), Throwables.getCauseAs(e, TransactionCommitFailedException.class));
}
LOG.trace("Successfuly created data.");
final ResponseBuilder responseBuilder = Response.status(Status.NO_CONTENT);
// FIXME: Provide path to result.
final URI location = resolveLocation(uriInfo, "", mountPoint, normalizedII);
if (location != null) {
responseBuilder.location(location);
}
return responseBuilder.build();
}
use of org.opendaylight.restconf.common.errors.RestconfDocumentedException in project netconf by opendaylight.
the class RestconfImpl method invokeSalRemoteRpcSubscribeRPC.
private ListenableFuture<DOMRpcResult> invokeSalRemoteRpcSubscribeRPC(final NormalizedNodeContext payload) {
final ContainerNode value = (ContainerNode) payload.getData();
final QName rpcQName = payload.getInstanceIdentifierContext().getSchemaNode().getQName();
final Optional<DataContainerChild> path = value.findChildByArg(new NodeIdentifier(QName.create(rpcQName, "path")));
final Object pathValue = path.isPresent() ? path.get().body() : null;
if (!(pathValue instanceof YangInstanceIdentifier)) {
LOG.debug("Instance identifier {} was not normalized correctly", rpcQName);
throw new RestconfDocumentedException("Instance identifier was not normalized correctly", ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED);
}
final YangInstanceIdentifier pathIdentifier = (YangInstanceIdentifier) pathValue;
String streamName = (String) CREATE_DATA_SUBSCR;
NotificationOutputType outputType = null;
if (!pathIdentifier.isEmpty()) {
final String fullRestconfIdentifier = DATA_SUBSCR + controllerContext.toFullRestconfIdentifier(pathIdentifier, null);
LogicalDatastoreType datastore = parseEnumTypeParameter(value, LogicalDatastoreType.class, DATASTORE_PARAM_NAME);
datastore = datastore == null ? DEFAULT_DATASTORE : datastore;
Scope scope = parseEnumTypeParameter(value, Scope.class, SCOPE_PARAM_NAME);
scope = scope == null ? Scope.BASE : scope;
outputType = parseEnumTypeParameter(value, NotificationOutputType.class, OUTPUT_TYPE_PARAM_NAME);
outputType = outputType == null ? NotificationOutputType.XML : outputType;
streamName = Notificator.createStreamNameFromUri(fullRestconfIdentifier + "/datastore=" + datastore + "/scope=" + scope);
}
if (Strings.isNullOrEmpty(streamName)) {
LOG.debug("Path is empty or contains value node which is not Container or List built-in type at {}", pathIdentifier);
throw new RestconfDocumentedException("Path is empty or contains value node which is not Container or List " + "built-in type.", ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
}
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();
if (!Notificator.existListenerFor(streamName)) {
Notificator.createListener(pathIdentifier, streamName, outputType, controllerContext);
}
return Futures.immediateFuture(new DefaultDOMRpcResult(output));
}
use of org.opendaylight.restconf.common.errors.RestconfDocumentedException in project netconf by opendaylight.
the class RestconfImpl method dataSubs.
/**
* Register data change listener by stream name.
*
* @param identifier
* stream name
* @param uriInfo
* uri info
* @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 URI dataSubs(final String identifier, final UriInfo uriInfo, final Instant start, final Instant stop, final String filter, final boolean leafNodesOnly, final boolean skipNotificationData) {
final String streamName = Notificator.createStreamNameFromUri(identifier);
if (Strings.isNullOrEmpty(streamName)) {
throw new RestconfDocumentedException("Stream name is empty.", ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
}
final ListenerAdapter listener = Notificator.getListenerFor(streamName);
if (listener == null) {
throw new RestconfDocumentedException("Stream was not found.", ErrorType.PROTOCOL, ErrorTag.UNKNOWN_ELEMENT);
}
listener.setQueryParams(start, Optional.ofNullable(stop), Optional.ofNullable(filter), leafNodesOnly, skipNotificationData);
final Map<String, String> paramToValues = resolveValuesFromUri(identifier);
final LogicalDatastoreType datastore = parserURIEnumParameter(LogicalDatastoreType.class, paramToValues.get(DATASTORE_PARAM_NAME));
if (datastore == null) {
throw new RestconfDocumentedException("Stream name doesn't contains datastore value (pattern /datastore=)", ErrorType.APPLICATION, ErrorTag.MISSING_ATTRIBUTE);
}
final Scope scope = parserURIEnumParameter(Scope.class, paramToValues.get(SCOPE_PARAM_NAME));
if (scope == null) {
throw new RestconfDocumentedException("Stream name doesn't contains datastore value (pattern /scope=)", ErrorType.APPLICATION, ErrorTag.MISSING_ATTRIBUTE);
}
broker.registerToListenDataChanges(datastore, scope, listener);
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();
}
Aggregations