use of org.opendaylight.restconf.common.errors.RestconfDocumentedException in project netconf by opendaylight.
the class RestconfImpl method getModules.
/**
* Valid only for mount point.
*/
@Override
@Deprecated
public NormalizedNodeContext getModules(final String identifier, final UriInfo uriInfo) {
if (!identifier.contains(ControllerContext.MOUNT)) {
final String errMsg = "URI has bad format. If modules behind mount point should be showed," + " URI has to end with " + ControllerContext.MOUNT;
LOG.debug("{} for {}", errMsg, identifier);
throw new RestconfDocumentedException(errMsg, ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
}
final InstanceIdentifierContext<?> mountPointIdentifier = controllerContext.toMountPointIdentifier(identifier);
final DOMMountPoint mountPoint = mountPointIdentifier.getMountPoint();
final MapNode mountPointModulesMap = makeModuleMapNode(controllerContext.getAllModules(mountPoint));
final Module restconfModule = getRestconfModule();
final DataSchemaNode modulesSchemaNode = controllerContext.getRestconfModuleRestConfSchemaNode(restconfModule, RestConfModule.MODULES_CONTAINER_SCHEMA_NODE);
checkState(modulesSchemaNode instanceof ContainerSchemaNode);
final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> moduleContainerBuilder = SchemaAwareBuilders.containerBuilder((ContainerSchemaNode) modulesSchemaNode);
moduleContainerBuilder.withChild(mountPointModulesMap);
return new NormalizedNodeContext(new InstanceIdentifierContext<>(MODULES, modulesSchemaNode, mountPoint, controllerContext.getGlobalSchema()), moduleContainerBuilder.build(), QueryParametersParser.parseWriterParameters(uriInfo));
}
use of org.opendaylight.restconf.common.errors.RestconfDocumentedException in project netconf by opendaylight.
the class RestconfDocumentedExceptionMapper method toJsonResponseBody.
private static Object toJsonResponseBody(final NormalizedNodeContext errorsNode, final DataNodeContainer errorsSchemaNode) {
final ByteArrayOutputStream outStream = new ByteArrayOutputStream();
NormalizedNode data = errorsNode.getData();
final InstanceIdentifierContext<?> context = errorsNode.getInstanceIdentifierContext();
final DataSchemaNode schema = (DataSchemaNode) context.getSchemaNode();
final OutputStreamWriter outputWriter = new OutputStreamWriter(outStream, StandardCharsets.UTF_8);
if (data == null) {
throw new RestconfDocumentedException(Response.Status.NOT_FOUND);
}
boolean isDataRoot = false;
XMLNamespace initialNs = null;
SchemaPath path;
if (context.getSchemaNode() instanceof SchemaContext) {
isDataRoot = true;
path = SchemaPath.ROOT;
} else {
final List<QName> qNames = context.getInstanceIdentifier().getPathArguments().stream().filter(arg -> !(arg instanceof NodeIdentifierWithPredicates)).filter(arg -> !(arg instanceof AugmentationIdentifier)).map(PathArgument::getNodeType).collect(Collectors.toList());
path = SchemaPath.of(Absolute.of(qNames)).getParent();
}
if (!schema.isAugmenting() && !(schema instanceof SchemaContext)) {
initialNs = schema.getQName().getNamespace();
}
final JsonWriter jsonWriter = JsonWriterFactory.createJsonWriter(outputWriter);
final NormalizedNodeStreamWriter jsonStreamWriter = JSONNormalizedNodeStreamWriter.createExclusiveWriter(JSONCodecFactorySupplier.DRAFT_LHOTKA_NETMOD_YANG_JSON_02.getShared(context.getSchemaContext()), path, initialNs, jsonWriter);
// We create a delegating writer to special-case error-info as error-info is defined as an empty
// container in the restconf yang schema but we create a leaf node so we can output it. The delegate
// stream writer validates the node type against the schema and thus will expect a LeafSchemaNode but
// the schema has a ContainerSchemaNode so, to avoid an error, we override the leafNode behavior
// for error-info.
final NormalizedNodeStreamWriter streamWriter = new ForwardingNormalizedNodeStreamWriter() {
private boolean inOurLeaf;
@Override
protected NormalizedNodeStreamWriter delegate() {
return jsonStreamWriter;
}
@Override
public void startLeafNode(final NodeIdentifier name) throws IOException {
if (name.getNodeType().equals(RestConfModule.ERROR_INFO_QNAME)) {
inOurLeaf = true;
jsonWriter.name(RestConfModule.ERROR_INFO_QNAME.getLocalName());
} else {
super.startLeafNode(name);
}
}
@Override
public void scalarValue(final Object value) throws IOException {
if (inOurLeaf) {
jsonWriter.value(value.toString());
} else {
super.scalarValue(value);
}
}
@Override
public void endNode() throws IOException {
if (inOurLeaf) {
inOurLeaf = false;
} else {
super.endNode();
}
}
};
final NormalizedNodeWriter nnWriter = NormalizedNodeWriter.forStreamWriter(streamWriter);
try {
if (isDataRoot) {
writeDataRoot(outputWriter, nnWriter, (ContainerNode) data);
} else {
if (data instanceof MapEntryNode) {
data = ImmutableNodes.mapNodeBuilder(data.getIdentifier().getNodeType()).withChild((MapEntryNode) data).build();
}
nnWriter.write(data);
}
nnWriter.flush();
outputWriter.flush();
} catch (final IOException e) {
LOG.warn("Error writing error response body", e);
}
try {
streamWriter.close();
} catch (IOException e) {
LOG.warn("Failed to close stream writer", e);
}
return outStream.toString(StandardCharsets.UTF_8);
}
use of org.opendaylight.restconf.common.errors.RestconfDocumentedException in project netconf by opendaylight.
the class XmlToPatchBodyReader method readFrom.
@SuppressWarnings("checkstyle:IllegalCatch")
@Override
public PatchContext readFrom(final Class<PatchContext> type, final Type genericType, final Annotation[] annotations, final MediaType mediaType, final MultivaluedMap<String, String> httpHeaders, final InputStream entityStream) throws WebApplicationException {
try {
final InstanceIdentifierContext<?> path = getInstanceIdentifierContext();
final Optional<InputStream> nonEmptyInputStreamOptional = RestUtil.isInputStreamEmpty(entityStream);
if (nonEmptyInputStreamOptional.isEmpty()) {
// represent empty nopayload input
return new PatchContext(path, null, null);
}
final Document doc = UntrustedXML.newDocumentBuilder().parse(nonEmptyInputStreamOptional.get());
return parse(path, doc);
} catch (final RestconfDocumentedException e) {
throw e;
} catch (final Exception e) {
LOG.debug("Error parsing xml input", e);
RestconfDocumentedException.throwIfYangError(e);
throw new RestconfDocumentedException("Error parsing input: " + e.getMessage(), ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE, e);
}
}
use of org.opendaylight.restconf.common.errors.RestconfDocumentedException in project netconf by opendaylight.
the class XmlToPatchBodyReader method parse.
private static PatchContext parse(final InstanceIdentifierContext<?> pathContext, final Document doc) throws XMLStreamException, IOException, ParserConfigurationException, SAXException, URISyntaxException {
final List<PatchEntity> resultCollection = new ArrayList<>();
final String patchId = doc.getElementsByTagName("patch-id").item(0).getFirstChild().getNodeValue();
final NodeList editNodes = doc.getElementsByTagName("edit");
for (int i = 0; i < editNodes.getLength(); i++) {
DataSchemaNode schemaNode = (DataSchemaNode) pathContext.getSchemaNode();
final Element element = (Element) editNodes.item(i);
final String operation = element.getElementsByTagName("operation").item(0).getFirstChild().getNodeValue();
final PatchEditOperation oper = PatchEditOperation.valueOf(operation.toUpperCase(Locale.ROOT));
final String editId = element.getElementsByTagName("edit-id").item(0).getFirstChild().getNodeValue();
final String target = element.getElementsByTagName("target").item(0).getFirstChild().getNodeValue();
final List<Element> values = readValueNodes(element, oper);
final Element firstValueElement = values != null ? values.get(0) : null;
// get namespace according to schema node from path context or value
final String namespace = firstValueElement == null ? schemaNode.getQName().getNamespace().toString() : firstValueElement.getNamespaceURI();
// find module according to namespace
final Module module = pathContext.getSchemaContext().findModules(XMLNamespace.of(namespace)).iterator().next();
// initialize codec + set default prefix derived from module name
final StringModuleInstanceIdentifierCodec codec = new StringModuleInstanceIdentifierCodec(pathContext.getSchemaContext(), module.getName());
// find complete path to target and target schema node
// target can be also empty (only slash)
YangInstanceIdentifier targetII;
final SchemaNode targetNode;
final Inference inference;
if (target.equals("/")) {
targetII = pathContext.getInstanceIdentifier();
targetNode = pathContext.getSchemaContext();
inference = Inference.ofDataTreePath(pathContext.getSchemaContext(), schemaNode.getQName());
} else {
targetII = codec.deserialize(codec.serialize(pathContext.getInstanceIdentifier()).concat(prepareNonCondXpath(schemaNode, target.replaceFirst("/", ""), firstValueElement, namespace, module.getQNameModule().getRevision().map(Revision::toString).orElse(null))));
// move schema node
schemaNode = verifyNotNull(codec.getDataContextTree().findChild(targetII).orElseThrow().getDataSchemaNode());
final SchemaInferenceStack stack = SchemaInferenceStack.of(pathContext.getSchemaContext());
targetII.getPathArguments().stream().filter(arg -> !(arg instanceof YangInstanceIdentifier.NodeIdentifierWithPredicates)).filter(arg -> !(arg instanceof YangInstanceIdentifier.AugmentationIdentifier)).forEach(p -> stack.enterSchemaTree(p.getNodeType()));
final EffectiveStatement<?, ?> parentStmt = stack.exit();
verify(parentStmt instanceof SchemaNode, "Unexpected parent %s", parentStmt);
targetNode = (SchemaNode) parentStmt;
inference = stack.toInference();
}
if (targetNode == null) {
LOG.debug("Target node {} not found in path {} ", target, pathContext.getSchemaNode());
throw new RestconfDocumentedException("Error parsing input", ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE);
}
if (oper.isWithValue()) {
final NormalizedNode parsed;
if (schemaNode instanceof ContainerSchemaNode || schemaNode instanceof ListSchemaNode) {
final NormalizedNodeResult resultHolder = new NormalizedNodeResult();
final NormalizedNodeStreamWriter writer = ImmutableNormalizedNodeStreamWriter.from(resultHolder);
final XmlParserStream xmlParser = XmlParserStream.create(writer, inference);
xmlParser.traverse(new DOMSource(firstValueElement));
parsed = resultHolder.getResult();
} else {
parsed = null;
}
// for lists allow to manipulate with list items through their parent
if (targetII.getLastPathArgument() instanceof NodeIdentifierWithPredicates) {
targetII = targetII.getParent();
}
resultCollection.add(new PatchEntity(editId, oper, targetII, parsed));
} else {
resultCollection.add(new PatchEntity(editId, oper, targetII));
}
}
return new PatchContext(pathContext, ImmutableList.copyOf(resultCollection), patchId);
}
use of org.opendaylight.restconf.common.errors.RestconfDocumentedException in project netconf by opendaylight.
the class BrokerFacade method postData.
private void postData(final DOMDataTreeReadWriteTransaction rwTransaction, final LogicalDatastoreType datastore, final YangInstanceIdentifier path, final NormalizedNode payload, final EffectiveModelContext schemaContext, final String insert, final String point) {
if (insert == null) {
makeNormalPost(rwTransaction, datastore, path, payload, schemaContext);
return;
}
final DataSchemaNode schemaNode = checkListAndOrderedType(schemaContext, path);
checkItemDoesNotExists(rwTransaction, datastore, path);
switch(insert) {
case "first":
if (schemaNode instanceof ListSchemaNode) {
final UserMapNode readList = (UserMapNode) this.readConfigurationData(path.getParent().getParent());
if (readList == null || readList.isEmpty()) {
simplePostPut(rwTransaction, datastore, path, payload, schemaContext);
} else {
rwTransaction.delete(datastore, path.getParent().getParent());
simplePostPut(rwTransaction, datastore, path, payload, schemaContext);
makeNormalPost(rwTransaction, datastore, path.getParent().getParent(), readList, schemaContext);
}
} else {
final UserLeafSetNode<?> readLeafList = (UserLeafSetNode<?>) readConfigurationData(path.getParent());
if (readLeafList == null || readLeafList.isEmpty()) {
simplePostPut(rwTransaction, datastore, path, payload, schemaContext);
} else {
rwTransaction.delete(datastore, path.getParent());
simplePostPut(rwTransaction, datastore, path, payload, schemaContext);
makeNormalPost(rwTransaction, datastore, path.getParent().getParent(), readLeafList, schemaContext);
}
}
break;
case "last":
simplePostPut(rwTransaction, datastore, path, payload, schemaContext);
break;
case "before":
if (schemaNode instanceof ListSchemaNode) {
final UserMapNode readList = (UserMapNode) this.readConfigurationData(path.getParent().getParent());
if (readList == null || readList.isEmpty()) {
simplePostPut(rwTransaction, datastore, path, payload, schemaContext);
} else {
insertWithPointListPost(rwTransaction, datastore, path, payload, schemaContext, point, readList, true);
}
} else {
final UserLeafSetNode<?> readLeafList = (UserLeafSetNode<?>) readConfigurationData(path.getParent());
if (readLeafList == null || readLeafList.isEmpty()) {
simplePostPut(rwTransaction, datastore, path, payload, schemaContext);
} else {
insertWithPointLeafListPost(rwTransaction, datastore, path, payload, schemaContext, point, readLeafList, true);
}
}
break;
case "after":
if (schemaNode instanceof ListSchemaNode) {
final UserMapNode readList = (UserMapNode) this.readConfigurationData(path.getParent().getParent());
if (readList == null || readList.isEmpty()) {
simplePostPut(rwTransaction, datastore, path, payload, schemaContext);
} else {
insertWithPointListPost(rwTransaction, datastore, path, payload, schemaContext, point, readList, false);
}
} else {
final UserLeafSetNode<?> readLeafList = (UserLeafSetNode<?>) readConfigurationData(path.getParent());
if (readLeafList == null || readLeafList.isEmpty()) {
simplePostPut(rwTransaction, datastore, path, payload, schemaContext);
} else {
insertWithPointLeafListPost(rwTransaction, datastore, path, payload, schemaContext, point, readLeafList, false);
}
}
break;
default:
throw new RestconfDocumentedException("Used bad value of insert parameter. Possible values are first, last, before or after, " + "but was: " + insert);
}
}
Aggregations