import org.opendaylight.mdsal.binding.api.query.QueryResult;
import org.opendaylight.mdsal.binding.dom.adapter.query.DefaultQuery;
import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeQueryOperations;
import org.opendaylight.mdsal.dom.api.DOMDataTreeReadOperations;
import org.opendaylight.mdsal.dom.api.DOMDataTreeTransaction;
import org.opendaylight.mdsal.dom.api.query.DOMQuery;
+import org.opendaylight.mdsal.dom.api.query.DOMQueryResult;
import org.opendaylight.mdsal.dom.spi.query.DOMQueryEvaluator;
import org.opendaylight.mdsal.dom.spi.query.EagerDOMQueryResult;
import org.opendaylight.yangtools.concepts.Delegator;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
abstract class AbstractForwardedTransaction<T extends DOMDataTreeTransaction> implements Delegator<T>,
Identifiable<Object> {
+ private static final Logger LOG = LoggerFactory.getLogger(AbstractForwardedTransaction.class);
private final @NonNull AdapterContext adapterContext;
private final @NonNull T delegate;
return readOps.exists(store, adapterContext.currentSerializer().toYangInstanceIdentifier(path));
}
- protected final <T extends @NonNull DataObject> @NonNull FluentFuture<QueryResult<T>> doExecute(
+ protected final <T extends @NonNull DataObject> @NonNull FluentFuture<QueryResult<T>> doExecute(
final DOMDataTreeReadOperations readOps, final @NonNull LogicalDatastoreType store,
final @NonNull QueryExpression<T> query) {
checkArgument(query instanceof DefaultQuery, "Unsupported query type %s", query);
final DefaultQuery<T> defaultQuery = (DefaultQuery<T>) query;
- final DOMQuery domQuery = defaultQuery.asDOMQuery();
+ final FluentFuture<DOMQueryResult> domResult = readOps instanceof DOMDataTreeQueryOperations
+ ? ((DOMDataTreeQueryOperations) readOps).execute(store, defaultQuery.asDOMQuery())
+ : fallbackExecute(readOps, store, defaultQuery.asDOMQuery());
+
+ return domResult.transform(defaultQuery::toQueryResult, MoreExecutors.directExecutor());
+ }
+
+ private static FluentFuture<DOMQueryResult> fallbackExecute(final @NonNull DOMDataTreeReadOperations readOps,
+ final @NonNull LogicalDatastoreType store, final @NonNull DOMQuery domQuery) {
+ LOG.trace("Fallback evaluation of {} on {}", domQuery, readOps);
return readOps.read(store, domQuery.getRoot())
- .transform(node -> node.map(
- data -> DOMQueryEvaluator.evaluateOn(domQuery, data)).orElse(EagerDOMQueryResult.of()),
- MoreExecutors.directExecutor())
- .transform(defaultQuery::toQueryResult, MoreExecutors.directExecutor());
+ .transform(
+ node -> node.map(data -> DOMQueryEvaluator.evaluateOn(domQuery, data)).orElse(EagerDOMQueryResult.of()),
+ // TODO: execute on a dedicated thread pool
+ MoreExecutors.directExecutor());
}
}
--- /dev/null
+/*
+ * Copyright (c) 2020 PANTHEON.tech, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.mdsal.dom.api;
+
+import com.google.common.annotations.Beta;
+import com.google.common.util.concurrent.FluentFuture;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.mdsal.common.api.ReadFailedException;
+import org.opendaylight.mdsal.dom.api.query.DOMQuery;
+import org.opendaylight.mdsal.dom.api.query.DOMQueryResult;
+
+/**
+ * Query-like operations supported by {@link DOMDataTreeReadTransaction} and {@link DOMDataTreeReadWriteTransaction}.
+ * This interface defines the operations without a tie-in with lifecycle management.
+ */
+@Beta
+public interface DOMDataTreeQueryOperations {
+ /**
+ * Executes a query on the provided logical data store.
+ *
+ * @param store Logical data store from which read should occur.
+ * @param query DOMQuery to execute
+ * @return a FluentFuture containing the result of the query. The Future blocks until the operation is complete.
+ * Once complete:
+ * <ul>
+ * <li>The Future returns the result of the query</li>
+ * <li>If the query execution fails, the Future will fail with a {@link ReadFailedException} or
+ * an exception derived from ReadFailedException.
+ * </li>
+ * </ul>
+ * @throws NullPointerException if any of the arguments is null
+ * @throws IllegalArgumentException if the query is not supported
+ */
+ FluentFuture<DOMQueryResult> execute(LogicalDatastoreType store, DOMQuery query);
+}
--- /dev/null
+/*
+ * Copyright (c) 2020 PANTHEON.tech, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.mdsal.dom.api;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * A {@link DOMDataTreeReadTransaction} which can also perform {@link DOMDataTreeQueryOperations}.
+ */
+@Beta
+public interface DOMDataTreeQueryReadTransaction extends DOMDataTreeReadTransaction, DOMDataTreeQueryOperations {
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2020 PANTHEON.tech, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.mdsal.dom.api;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * A {@link DOMDataTreeReadWriteTransaction} which can also perform {@link DOMDataTreeQueryOperations}.
+ */
+@Beta
+public interface DOMDataTreeQueryReadWriteTransaction
+ extends DOMDataTreeReadWriteTransaction, DOMDataTreeQueryOperations {
+
+}
import java.util.Map;
import java.util.Optional;
import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeQueryReadTransaction;
+import org.opendaylight.mdsal.dom.api.query.DOMQuery;
+import org.opendaylight.mdsal.dom.api.query.DOMQueryResult;
import org.opendaylight.mdsal.dom.spi.store.DOMStoreReadTransaction;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
* {@link LogicalDatastoreType} type parameter in
* {@link #read(LogicalDatastoreType, YangInstanceIdentifier)}.
*/
-class DOMForwardedReadOnlyTransaction extends
- AbstractDOMForwardedCompositeTransaction<LogicalDatastoreType, DOMStoreReadTransaction> implements
- DOMDataTreeReadTransaction {
+class DOMForwardedReadOnlyTransaction
+ extends AbstractDOMForwardedCompositeTransaction<LogicalDatastoreType, DOMStoreReadTransaction>
+ implements DOMDataTreeQueryReadTransaction {
protected DOMForwardedReadOnlyTransaction(final Object identifier,
final Map<LogicalDatastoreType, DOMStoreReadTransaction> backingTxs) {
return getSubtransaction(store).exists(path);
}
+ @Override
+ public FluentFuture<DOMQueryResult> execute(final LogicalDatastoreType store, final DOMQuery query) {
+ return getSubtransaction(store).execute(query);
+ }
+
@Override
public void close() {
closeSubtransactions();
import java.util.Map;
import java.util.Optional;
import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeQueryReadWriteTransaction;
+import org.opendaylight.mdsal.dom.api.query.DOMQuery;
+import org.opendaylight.mdsal.dom.api.query.DOMQueryResult;
import org.opendaylight.mdsal.dom.spi.store.DOMStoreReadWriteTransaction;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
* underlying transactions.
*/
final class DOMForwardedReadWriteTransaction extends DOMForwardedWriteTransaction<DOMStoreReadWriteTransaction>
- implements DOMDataTreeReadWriteTransaction {
+ implements DOMDataTreeQueryReadWriteTransaction {
DOMForwardedReadWriteTransaction(final Object identifier,
final Map<LogicalDatastoreType, DOMStoreReadWriteTransaction> backingTxs,
public FluentFuture<Boolean> exists(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
return getSubtransaction(store).exists(path);
}
+
+ @Override
+ public FluentFuture<DOMQueryResult> execute(final LogicalDatastoreType store, final DOMQuery query) {
+ return getSubtransaction(store).execute(query);
+ }
}
package org.opendaylight.mdsal.dom.spi.store;
import com.google.common.util.concurrent.FluentFuture;
+import com.google.common.util.concurrent.MoreExecutors;
import java.util.Optional;
+import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.mdsal.common.api.ReadFailedException;
+import org.opendaylight.mdsal.dom.api.query.DOMQuery;
+import org.opendaylight.mdsal.dom.api.query.DOMQueryResult;
+import org.opendaylight.mdsal.dom.spi.query.DOMQueryEvaluator;
+import org.opendaylight.mdsal.dom.spi.query.EagerDOMQueryResult;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
* </ul>
*/
FluentFuture<Boolean> exists(YangInstanceIdentifier path);
+
+ /**
+ * Executes a query on the provided logical data store.
+ *
+ * <p>
+ * Default operation invokes {@code read(query.getRoot())} and then executes the result with
+ * {@link DOMQueryEvaluator}. Implementations are encouraged to provide a more efficient implementation as
+ * appropriate.
+ *
+ * @param query DOMQuery to execute
+ * @return a FluentFuture containing the result of the query. The Future blocks until the operation is complete.
+ * Once complete:
+ * <ul>
+ * <li>The Future returns the result of the query</li>
+ * <li>If the query execution fails, the Future will fail with a {@link ReadFailedException} or
+ * an exception derived from ReadFailedException.
+ * </li>
+ * </ul>
+ * @throws NullPointerException if any of the arguments is null
+ * @throws IllegalArgumentException if the query is not supported
+ */
+ default @NonNull FluentFuture<DOMQueryResult> execute(final DOMQuery query) {
+ return read(query.getRoot()).transform(
+ node -> node.map(data -> DOMQueryEvaluator.evaluateOn(query, data)).orElse(EagerDOMQueryResult.of()),
+ MoreExecutors.directExecutor());
+ }
}