import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction;
import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
+import org.opendaylight.mdsal.dom.api.DOMTransactionChain;
import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
import org.opendaylight.restconf.common.context.WriterParameters;
import org.opendaylight.restconf.common.context.WriterParameters.WriterParametersBuilder;
import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
import org.opendaylight.restconf.common.errors.RestconfError;
-import org.opendaylight.restconf.nb.rfc8040.references.SchemaContextRef;
import org.opendaylight.restconf.nb.rfc8040.rests.transactions.TransactionVarsWrapper;
import org.opendaylight.restconf.nb.rfc8040.streams.listeners.NotificationListenerAdapter;
import org.opendaylight.restconf.nb.rfc8040.utils.mapping.RestconfMappingNodeUtil;
import org.opendaylight.yangtools.yang.data.util.DataSchemaContextTree;
import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
/**
* Parse parameters from URI request and check their types and values.
*
- *
* @param identifier
* {@link InstanceIdentifierContext}
* @param uriInfo
* URI info
- * @param tagged
- * set tagged for {@link WriterParameters}
* @return {@link WriterParameters}
*/
- public static @NonNull WriterParameters parseUriParameters(final @NonNull InstanceIdentifierContext<?> identifier,
- final @Nullable UriInfo uriInfo, final boolean tagged) {
- return parseParams(identifier, uriInfo, tagged);
- }
-
- /**
- * Parse parameters from URI request and check their types and values.
- *
- *
- * @param identifier
- * {@link InstanceIdentifierContext}
- * @param uriInfo
- * URI info
- * @return {@link WriterParameters}
- */
- public static @NonNull WriterParameters parseUriParameters(final @NonNull InstanceIdentifierContext<?> identifier,
- final @Nullable UriInfo uriInfo) {
- return parseParams(identifier, uriInfo, false);
- }
-
- private static WriterParameters parseParams(final InstanceIdentifierContext<?> identifier, final UriInfo uriInfo,
- final boolean tagged) {
+ public static WriterParameters parseUriParameters(final InstanceIdentifierContext<?> identifier,
+ final UriInfo uriInfo) {
final WriterParametersBuilder builder = new WriterParametersBuilder();
- builder.setTagged(tagged);
if (uriInfo == null) {
return builder.build();
final List<String> depth = uriInfo.getQueryParameters().getOrDefault(
RestconfDataServiceConstant.ReadData.DEPTH,
Collections.singletonList(RestconfDataServiceConstant.ReadData.UNBOUNDED));
+ final List<String> withDefaults = uriInfo.getQueryParameters().getOrDefault(
+ RestconfDataServiceConstant.ReadData.WITH_DEFAULTS,
+ Collections.emptyList());
// fields
final List<String> fields = uriInfo.getQueryParameters().getOrDefault(
RestconfDataServiceConstant.ReadData.FIELDS,
ParametersUtil.checkParameterCount(content, RestconfDataServiceConstant.ReadData.CONTENT);
ParametersUtil.checkParameterCount(depth, RestconfDataServiceConstant.ReadData.DEPTH);
ParametersUtil.checkParameterCount(fields, RestconfDataServiceConstant.ReadData.FIELDS);
+ ParametersUtil.checkParameterCount(fields, RestconfDataServiceConstant.ReadData.WITH_DEFAULTS);
// check and set content
final String contentValue = content.get(0);
builder.setFields(ParserFieldsParameter.parseFieldsParameter(identifier, fields.get(0)));
}
+ // check and set withDefaults parameter
+ if (!withDefaults.isEmpty()) {
+ switch (withDefaults.get(0)) {
+ case RestconfDataServiceConstant.ReadData.REPORT_ALL_TAGGED_DEFAULT_VALUE:
+ builder.setTagged(true);
+ break;
+ case RestconfDataServiceConstant.ReadData.REPORT_ALL_DEFAULT_VALUE:
+ break;
+ default:
+ builder.setWithDefault(withDefaults.get(0));
+ }
+ }
+
return builder.build();
}
}
/**
- * Read specific type of data from data store via transaction.
+ * Read specific type of data from data store via transaction. Close {@link DOMTransactionChain} inside of object
+ * {@link TransactionVarsWrapper} provided as a parameter.
*
* @param valueOfContent
* type of data to read (config, state, all)
* @param transactionNode
* {@link TransactionVarsWrapper} - wrapper for variables
* @param withDefa
- * vaule of with-defaults parameter
+ * value of with-defaults parameter
* @param ctx
* schema context
* @return {@link NormalizedNode}
return readAllData(transactionNode, withDefa, ctx);
default:
+ transactionNode.getTransactionChain().close();
throw new RestconfDocumentedException(
new RestconfError(RestconfError.ErrorType.PROTOCOL, RestconfError.ErrorTag.INVALID_VALUE,
"Invalid content parameter: " + valueOfContent, null,
* {@link TransactionVarsWrapper} - wrapper for variables
* @param withDefa
* vaule of with-defaults parameter
- * @param schemaContextRef
+ * @param schemaContext
* schema context
* @param uriInfo
* uri info
*/
public static NormalizedNode<?, ?> readData(final String identifier, final String content,
final TransactionVarsWrapper transactionNode, final String withDefa,
- final SchemaContextRef schemaContextRef, final UriInfo uriInfo) {
- final SchemaContext schemaContext = schemaContextRef.get();
- if (identifier.contains(STREAMS_PATH) && !identifier.contains(STREAM_PATH_PART)) {
- createAllYangNotificationStreams(transactionNode, schemaContextRef, uriInfo);
+ final EffectiveModelContext schemaContext, final UriInfo uriInfo) {
+ if (identifier != null && identifier.contains(STREAMS_PATH) && !identifier.contains(STREAM_PATH_PART)) {
+ createAllYangNotificationStreams(transactionNode, schemaContext, uriInfo);
}
return readData(content, transactionNode, withDefa, schemaContext);
}
private static void createAllYangNotificationStreams(final TransactionVarsWrapper transactionNode,
- final SchemaContextRef schemaContextRef, final UriInfo uriInfo) {
+ final EffectiveModelContext schemaContext, final UriInfo uriInfo) {
final DOMDataTreeReadWriteTransaction wTx = transactionNode.getTransactionChain().newReadWriteTransaction();
- final boolean exist = SubscribeToStreamUtil.checkExist(schemaContextRef.get(), wTx);
+ final boolean exist = SubscribeToStreamUtil.checkExist(schemaContext, wTx);
- for (final NotificationDefinition notificationDefinition : schemaContextRef.get().getNotifications()) {
+ for (final NotificationDefinition notificationDefinition : schemaContext.getNotifications()) {
final NotificationListenerAdapter notifiStreamXML =
- CreateStreamUtil.createYangNotifiStream(notificationDefinition, schemaContextRef,
+ CreateStreamUtil.createYangNotifiStream(notificationDefinition, schemaContext,
NotificationOutputType.XML);
final NotificationListenerAdapter notifiStreamJSON =
- CreateStreamUtil.createYangNotifiStream(notificationDefinition, schemaContextRef,
+ CreateStreamUtil.createYangNotifiStream(notificationDefinition, schemaContext,
NotificationOutputType.JSON);
- writeNotificationStreamToDatastore(schemaContextRef, uriInfo, wTx, exist, notifiStreamXML);
- writeNotificationStreamToDatastore(schemaContextRef, uriInfo, wTx, exist, notifiStreamJSON);
+ writeNotificationStreamToDatastore(schemaContext, uriInfo, wTx, exist, notifiStreamXML);
+ writeNotificationStreamToDatastore(schemaContext, uriInfo, wTx, exist, notifiStreamJSON);
}
SubscribeToStreamUtil.submitData(wTx);
}
- private static void writeNotificationStreamToDatastore(final SchemaContextRef schemaContextRef,
+ private static void writeNotificationStreamToDatastore(final EffectiveModelContext schemaContext,
final UriInfo uriInfo, final DOMDataTreeReadWriteTransaction readWriteTransaction, final boolean exist,
final NotificationListenerAdapter listener) {
final URI uri = SubscribeToStreamUtil.prepareUriByStreamName(uriInfo, listener.getStreamName());
- final NormalizedNode mapToStreams = RestconfMappingNodeUtil.mapYangNotificationStreamByIetfRestconfMonitoring(
- listener.getSchemaPath().getLastComponent(), schemaContextRef.get().getNotifications(), null,
- listener.getOutputType(), uri,
- SubscribeToStreamUtil.getMonitoringModule(schemaContextRef.get()), exist);
- SubscribeToStreamUtil.writeDataToDS(schemaContextRef.get(),
+ final NormalizedNode<?, ?> mapToStreams =
+ RestconfMappingNodeUtil.mapYangNotificationStreamByIetfRestconfMonitoring(
+ listener.getSchemaPath().getLastComponent(), schemaContext.getNotifications(), null,
+ listener.getOutputType(), uri, SubscribeToStreamUtil.getMonitoringModule(schemaContext), exist);
+ SubscribeToStreamUtil.writeDataToDS(schemaContext,
listener.getSchemaPath().getLastComponent().getLocalName(), readWriteTransaction, exist, mapToStreams);
}
final NormalizedNodeBuilder<NodeIdentifier, Object, LeafNode<Object>> leafBuilder =
Builders.leafBuilder((LeafSchemaNode) childSchema);
if (keys.contains(child.getNodeType())) {
- leafBuilder.withValue(((LeafNode) child).getValue());
+ leafBuilder.withValue(((LeafNode<?>) child).getValue());
builder.withChild(leafBuilder.build());
} else {
if (trim) {
if (defaultVal == null || !defaultVal.equals(nodeVal)) {
- leafBuilder.withValue(((LeafNode) child).getValue());
+ leafBuilder.withValue(((LeafNode<?>) child).getValue());
builder.withChild(leafBuilder.build());
}
} else {
if (defaultVal != null && defaultVal.equals(nodeVal)) {
- leafBuilder.withValue(((LeafNode) child).getValue());
+ leafBuilder.withValue(((LeafNode<?>) child).getValue());
builder.withChild(leafBuilder.build());
}
}
Builders.leafBuilder((LeafSchemaNode) childSchema);
if (trim) {
if (defaultVal == null || !defaultVal.equals(nodeVal)) {
- leafBuilder.withValue(((LeafNode) child).getValue());
+ leafBuilder.withValue(((LeafNode<?>) child).getValue());
builder.withChild(leafBuilder.build());
}
} else {
if (defaultVal != null && defaultVal.equals(nodeVal)) {
- leafBuilder.withValue(((LeafNode) child).getValue());
+ leafBuilder.withValue(((LeafNode<?>) child).getValue());
builder.withChild(leafBuilder.build());
}
}
/**
* If is set specific {@link LogicalDatastoreType} in
* {@link TransactionVarsWrapper}, then read this type of data from DS. If
- * don't, we have to read all data from DS (state + config)
+ * don't, we have to read all data from DS (state + config).
+ * This method will close {@link org.opendaylight.mdsal.dom.api.DOMTransactionChain} inside of
+ * {@link TransactionVarsWrapper}.
*
* @param transactionNode
* {@link TransactionVarsWrapper} - wrapper for variables
*/
private static @Nullable NormalizedNode<?, ?> readDataViaTransaction(
final @NonNull TransactionVarsWrapper transactionNode) {
+ return readDataViaTransaction(transactionNode, true);
+ }
+
+
+ /**
+ * If is set specific {@link LogicalDatastoreType} in
+ * {@link TransactionVarsWrapper}, then read this type of data from DS. If
+ * don't, we have to read all data from DS (state + config)
+ *
+ * @param transactionNode
+ * {@link TransactionVarsWrapper} - wrapper for variables
+ * @param closeTransactionChain
+ * If is set to true, after transaction it will close transactionChain in {@link TransactionVarsWrapper}
+ * @return {@link NormalizedNode}
+ */
+ private static @Nullable NormalizedNode<?, ?> readDataViaTransaction(
+ final @NonNull TransactionVarsWrapper transactionNode, final boolean closeTransactionChain) {
final NormalizedNodeFactory dataFactory = new NormalizedNodeFactory();
try (DOMDataTreeReadTransaction tx = transactionNode.getTransactionChain().newReadOnlyTransaction()) {
final FluentFuture<Optional<NormalizedNode<?, ?>>> listenableFuture = tx.read(
transactionNode.getLogicalDatastoreType(),
transactionNode.getInstanceIdentifier().getInstanceIdentifier());
- FutureCallbackTx.addCallback(listenableFuture, RestconfDataServiceConstant.ReadData.READ_TYPE_TX,
- dataFactory);
+ if (closeTransactionChain) {
+ //Method close transactionChain inside of TransactionVarsWrapper, if is provide as a parameter.
+ FutureCallbackTx.addCallback(listenableFuture, RestconfDataServiceConstant.ReadData.READ_TYPE_TX,
+ dataFactory, transactionNode.getTransactionChain());
+ } else {
+ FutureCallbackTx.addCallback(listenableFuture, RestconfDataServiceConstant.ReadData.READ_TYPE_TX,
+ dataFactory);
+ }
}
return dataFactory.build();
}
/**
- * Read config and state data, then map them.
+ * Read config and state data, then map them. Close {@link DOMTransactionChain} inside of object
+ * {@link TransactionVarsWrapper} provided as a parameter.
*
* @param transactionNode
* {@link TransactionVarsWrapper} - wrapper for variables
final String withDefa, final SchemaContext ctx) {
// PREPARE STATE DATA NODE
transactionNode.setLogicalDatastoreType(LogicalDatastoreType.OPERATIONAL);
- final NormalizedNode<?, ?> stateDataNode = readDataViaTransaction(transactionNode);
+ final NormalizedNode<?, ?> stateDataNode = readDataViaTransaction(transactionNode, false);
// PREPARE CONFIG DATA NODE
transactionNode.setLogicalDatastoreType(LogicalDatastoreType.CONFIGURATION);
final NormalizedNode<?, ?> configDataNode;
+ //Here will be closed transactionChain
if (withDefa == null) {
configDataNode = readDataViaTransaction(transactionNode);
} else {
mapValueToBuilder(((LeafSetNode<Object>) configDataNode).getValue(),
((LeafSetNode<Object>) stateDataNode).getValue(), builder);
return builder.build();
+ } else if (configDataNode instanceof LeafSetEntryNode) {
+ return Builders.leafSetEntryBuilder()
+ .withNodeIdentifier(((LeafSetEntryNode<?>) configDataNode).getIdentifier())
+ .withValue(configDataNode.getValue())
+ .build();
} else if (configDataNode instanceof UnkeyedListNode) {
final CollectionNodeBuilder<UnkeyedListEntryNode, UnkeyedListNode> builder = Builders
.unkeyedListBuilder().withNodeIdentifier(((UnkeyedListNode) configDataNode).getIdentifier());