2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.mdsal.binding.dom.adapter;
10 import static com.google.common.base.Preconditions.checkArgument;
11 import static com.google.common.base.Preconditions.checkState;
12 import static java.util.Objects.requireNonNull;
14 import com.google.common.util.concurrent.FluentFuture;
15 import com.google.common.util.concurrent.MoreExecutors;
16 import java.util.Optional;
17 import org.eclipse.jdt.annotation.NonNull;
18 import org.opendaylight.mdsal.binding.api.query.QueryExpression;
19 import org.opendaylight.mdsal.binding.api.query.QueryResult;
20 import org.opendaylight.mdsal.binding.dom.adapter.query.DefaultQuery;
21 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
22 import org.opendaylight.mdsal.dom.api.DOMDataTreeQueryOperations;
23 import org.opendaylight.mdsal.dom.api.DOMDataTreeReadOperations;
24 import org.opendaylight.mdsal.dom.api.DOMDataTreeTransaction;
25 import org.opendaylight.mdsal.dom.api.query.DOMQuery;
26 import org.opendaylight.mdsal.dom.api.query.DOMQueryResult;
27 import org.opendaylight.mdsal.dom.spi.query.DOMQueryEvaluator;
28 import org.opendaylight.yangtools.concepts.Delegator;
29 import org.opendaylight.yangtools.concepts.Identifiable;
30 import org.opendaylight.yangtools.yang.binding.DataObject;
31 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
32 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
36 abstract class AbstractForwardedTransaction<T extends DOMDataTreeTransaction> implements Delegator<T>,
37 Identifiable<Object> {
38 private static final Logger LOG = LoggerFactory.getLogger(AbstractForwardedTransaction.class);
40 private final @NonNull AdapterContext adapterContext;
41 private final @NonNull T delegate;
43 AbstractForwardedTransaction(final AdapterContext adapterContext, final T delegateTx) {
44 this.adapterContext = requireNonNull(adapterContext, "Codec must not be null");
45 this.delegate = requireNonNull(delegateTx, "Delegate must not be null");
49 public final Object getIdentifier() {
50 return delegate.getIdentifier();
54 public final T getDelegate() {
58 protected final <S extends DOMDataTreeTransaction> S getDelegateChecked(final Class<S> txType) {
59 checkState(txType.isInstance(delegate));
60 return txType.cast(delegate);
63 protected final AdapterContext adapterContext() {
64 return adapterContext;
67 protected final <D extends DataObject> @NonNull FluentFuture<Optional<D>> doRead(
68 final DOMDataTreeReadOperations readOps, final LogicalDatastoreType store,
69 final InstanceIdentifier<D> path) {
70 checkArgument(!path.isWildcarded(), "Invalid read of wildcarded path %s", path);
72 final CurrentAdapterSerializer codec = adapterContext.currentSerializer();
73 final YangInstanceIdentifier domPath = codec.toYangInstanceIdentifier(path);
75 return readOps.read(store, domPath)
76 .transform(optData -> optData.map(domData -> (D) codec.fromNormalizedNode(domPath, domData).getValue()),
77 MoreExecutors.directExecutor());
80 protected final @NonNull FluentFuture<Boolean> doExists(final DOMDataTreeReadOperations readOps,
81 final LogicalDatastoreType store, final InstanceIdentifier<?> path) {
82 checkArgument(!path.isWildcarded(), "Invalid exists of wildcarded path %s", path);
83 return readOps.exists(store, adapterContext.currentSerializer().toYangInstanceIdentifier(path));
86 protected static final <T extends @NonNull DataObject> @NonNull FluentFuture<QueryResult<T>> doExecute(
87 final DOMDataTreeReadOperations readOps, final @NonNull LogicalDatastoreType store,
88 final @NonNull QueryExpression<T> query) {
89 checkArgument(query instanceof DefaultQuery, "Unsupported query type %s", query);
90 final var defaultQuery = (DefaultQuery<T>) query;
92 final var domFuture = requireNonNull(readOps) instanceof DOMDataTreeQueryOperations dtqOps
93 ? dtqOps.execute(store, defaultQuery.asDOMQuery())
94 : fallbackExecute(readOps, store, defaultQuery.asDOMQuery());
96 return domFuture.transform(defaultQuery::toQueryResult, MoreExecutors.directExecutor());
99 private static FluentFuture<DOMQueryResult> fallbackExecute(final @NonNull DOMDataTreeReadOperations readOps,
100 final @NonNull LogicalDatastoreType store, final @NonNull DOMQuery domQuery) {
101 LOG.trace("Fallback evaluation of {} on {}", domQuery, readOps);
102 return readOps.read(store, domQuery.getRoot())
104 node -> node.map(data -> DOMQueryEvaluator.evaluateOn(domQuery, data)).orElse(DOMQueryResult.of()),
105 // TODO: execute on a dedicated thread pool
106 MoreExecutors.directExecutor());