X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;ds=sidebyside;f=opendaylight%2Fmd-sal%2Fsal-distributed-datastore%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fcluster%2Fdatabroker%2Fcompat%2FLegacyDOMDataBrokerAdapter.java;fp=opendaylight%2Fmd-sal%2Fsal-distributed-datastore%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fcluster%2Fdatabroker%2Fcompat%2FLegacyDOMDataBrokerAdapter.java;h=f4950379ce5366e3640d4fb765beb1c4bce69dcf;hb=f41c5e6e6f6e10b36b1e4b1992877e38e718c8fb;hp=0000000000000000000000000000000000000000;hpb=2f05ce3fdd200dccd4a99ae16d1340c72d36ca11;p=controller.git diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/compat/LegacyDOMDataBrokerAdapter.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/compat/LegacyDOMDataBrokerAdapter.java new file mode 100644 index 0000000000..f4950379ce --- /dev/null +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/compat/LegacyDOMDataBrokerAdapter.java @@ -0,0 +1,343 @@ +/* + * Copyright (c) 2017 Inocybe Technologies 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.controller.cluster.databroker.compat; + +import static com.google.common.base.Preconditions.checkState; + +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; +import com.google.common.collect.ForwardingObject; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableMap.Builder; +import com.google.common.util.concurrent.CheckedFuture; +import com.google.common.util.concurrent.ListenableFuture; +import java.util.Map; +import java.util.concurrent.atomic.AtomicReference; +import javax.annotation.Nonnull; +import org.opendaylight.controller.cluster.databroker.AbstractDOMBroker; +import org.opendaylight.controller.cluster.datastore.DistributedDataStoreInterface; +import org.opendaylight.controller.cluster.datastore.compat.LegacyDOMStoreAdapter; +import org.opendaylight.controller.md.sal.common.api.TransactionStatus; +import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction; +import org.opendaylight.controller.md.sal.common.api.data.DataStoreUnavailableException; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.controller.md.sal.common.api.data.OptimisticLockFailedException; +import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException; +import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener; +import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; +import org.opendaylight.controller.md.sal.common.impl.service.AbstractDataTransaction; +import org.opendaylight.controller.md.sal.dom.api.ClusteredDOMDataTreeChangeListener; +import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker; +import org.opendaylight.controller.md.sal.dom.api.DOMDataBrokerExtension; +import org.opendaylight.controller.md.sal.dom.api.DOMDataChangeListener; +import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction; +import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction; +import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeChangeListener; +import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeChangeService; +import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeCommitCohortRegistry; +import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeIdentifier; +import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction; +import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain; +import org.opendaylight.mdsal.common.api.MappingCheckedFuture; +import org.opendaylight.mdsal.dom.api.DOMDataTreeCommitCohort; +import org.opendaylight.mdsal.dom.api.DOMDataTreeCommitCohortRegistration; +import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction; +import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction; +import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.util.concurrent.ExceptionMapper; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; + +/** + * Adapter between the legacy controller API-based DOMDataBroker and the mdsal API-based DOMDataBroker. + * + * @author Thomas Pantelis + */ +public class LegacyDOMDataBrokerAdapter extends ForwardingObject implements DOMDataBroker { + private static final ExceptionMapper SUBMIT_EX_MAPPER = + new ExceptionMapper("submit", TransactionCommitFailedException.class) { + @Override + protected TransactionCommitFailedException newWithCause(String message, Throwable cause) { + if (cause instanceof org.opendaylight.mdsal.common.api.OptimisticLockFailedException) { + return new OptimisticLockFailedException(cause.getMessage(), cause.getCause()); + } else if (cause instanceof org.opendaylight.mdsal.common.api.TransactionCommitFailedException) { + Throwable rootCause = cause.getCause(); + if (rootCause instanceof org.opendaylight.mdsal.common.api.DataStoreUnavailableException) { + rootCause = new DataStoreUnavailableException(rootCause.getMessage(), rootCause.getCause()); + } + + return new TransactionCommitFailedException(cause.getMessage(), rootCause); + } + + return new TransactionCommitFailedException(message, cause); + } + }; + + private final AbstractDOMBroker delegate; + private final Map, DOMDataBrokerExtension> extensions; + + public LegacyDOMDataBrokerAdapter(AbstractDOMBroker delegate) { + this.delegate = delegate; + + Map, + org.opendaylight.mdsal.dom.api.DOMDataBrokerExtension> delegateExtensions = + delegate.getSupportedExtensions(); + + Builder, DOMDataBrokerExtension> extBuilder = ImmutableMap.builder(); + final org.opendaylight.mdsal.dom.api.DOMDataTreeChangeService delegateTreeChangeService = + (org.opendaylight.mdsal.dom.api.DOMDataTreeChangeService) delegateExtensions.get( + org.opendaylight.mdsal.dom.api.DOMDataTreeChangeService.class); + if (delegateTreeChangeService != null) { + extBuilder.put(DOMDataTreeChangeService.class, new DOMDataTreeChangeService() { + @Override + public ListenerRegistration registerDataTreeChangeListener( + DOMDataTreeIdentifier treeId, final L listener) { + final org.opendaylight.mdsal.dom.api.DOMDataTreeChangeListener delegateListener; + if (listener instanceof ClusteredDOMDataTreeChangeListener) { + delegateListener = (org.opendaylight.mdsal.dom.api.ClusteredDOMDataTreeChangeListener) + changes -> listener.onDataTreeChanged(changes); + } else { + delegateListener = changes -> listener.onDataTreeChanged(changes); + } + + final ListenerRegistration reg = + delegateTreeChangeService.registerDataTreeChangeListener( + new org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier(convert(treeId.getDatastoreType()), + treeId.getRootIdentifier()), delegateListener); + + return new ListenerRegistration() { + @Override + public L getInstance() { + return listener; + } + + @Override + public void close() { + reg.close(); + } + }; + } + }); + } + + final org.opendaylight.mdsal.dom.api.DOMDataTreeCommitCohortRegistry delegateCohortRegistry = + (org.opendaylight.mdsal.dom.api.DOMDataTreeCommitCohortRegistry) delegateExtensions.get( + org.opendaylight.mdsal.dom.api.DOMDataTreeCommitCohortRegistry.class); + if (delegateCohortRegistry != null) { + extBuilder.put(DOMDataTreeCommitCohortRegistry.class, new DOMDataTreeCommitCohortRegistry() { + @Override + public DOMDataTreeCommitCohortRegistration registerCommitCohort( + org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier path, T cohort) { + return delegateCohortRegistry.registerCommitCohort(path, cohort); + } + }); + } + + extensions = extBuilder.build(); + } + + @Override + protected AbstractDOMBroker delegate() { + return delegate; + } + + @Override + public Map, DOMDataBrokerExtension> getSupportedExtensions() { + return extensions; + } + + @Override + public DOMDataReadOnlyTransaction newReadOnlyTransaction() { + return new DOMDataReadOnlyTransactionAdapter(delegate().newReadOnlyTransaction()); + } + + @Override + public DOMDataReadWriteTransaction newReadWriteTransaction() { + return new DOMDataTransactionAdapter(delegate().newReadWriteTransaction()); + } + + @Override + public DOMDataWriteTransaction newWriteOnlyTransaction() { + return new DOMDataTransactionAdapter(delegate().newWriteOnlyTransaction()); + } + + @Override + public DOMTransactionChain createTransactionChain(final TransactionChainListener listener) { + AtomicReference legacyChain = new AtomicReference<>(); + org.opendaylight.mdsal.common.api.TransactionChainListener delegateListener = + new org.opendaylight.mdsal.common.api.TransactionChainListener() { + @SuppressWarnings("rawtypes") + @Override + public void onTransactionChainFailed(final org.opendaylight.mdsal.common.api.TransactionChain chain, + final org.opendaylight.mdsal.common.api.AsyncTransaction transaction, final Throwable cause) { + listener.onTransactionChainFailed(legacyChain.get(), + (AsyncTransaction) () -> transaction.getIdentifier(), + cause instanceof Exception ? SUBMIT_EX_MAPPER.apply((Exception)cause) : cause); + } + + @Override + public void onTransactionChainSuccessful(org.opendaylight.mdsal.common.api.TransactionChain chain) { + listener.onTransactionChainSuccessful(legacyChain.get()); + } + }; + + final org.opendaylight.mdsal.dom.api.DOMTransactionChain delegateChain = + delegate().createTransactionChain(delegateListener); + legacyChain.set(new DOMTransactionChain() { + @Override + public DOMDataReadOnlyTransaction newReadOnlyTransaction() { + return new DOMDataReadOnlyTransactionAdapter(delegateChain.newReadOnlyTransaction()); + } + + @Override + public DOMDataReadWriteTransaction newReadWriteTransaction() { + return new DOMDataTransactionAdapter(delegateChain.newReadWriteTransaction()); + } + + @Override + public DOMDataWriteTransaction newWriteOnlyTransaction() { + return new DOMDataTransactionAdapter(delegateChain.newWriteOnlyTransaction()); + } + + @Override + public void close() { + delegateChain.close(); + } + }); + + return legacyChain.get(); + } + + @Override + public ListenerRegistration registerDataChangeListener(final LogicalDatastoreType store, + final YangInstanceIdentifier path, final DOMDataChangeListener listener, + final DataChangeScope triggeringScope) { + org.opendaylight.mdsal.dom.spi.store.DOMStore potentialStore = delegate().getTxFactories().get(convert(store)); + checkState(potentialStore != null, "Requested logical data store is not available."); + checkState(potentialStore instanceof DistributedDataStoreInterface, + "Requested logical data store does not support DataChangeListener."); + return ((DistributedDataStoreInterface)potentialStore).registerChangeListener(path, listener, triggeringScope); + } + + private static org.opendaylight.mdsal.common.api.LogicalDatastoreType convert(LogicalDatastoreType datastoreType) { + return org.opendaylight.mdsal.common.api.LogicalDatastoreType.valueOf(datastoreType.name()); + } + + private static class DOMDataTransactionAdapter implements DOMDataReadWriteTransaction { + private final DOMDataTreeReadTransaction readDelegate; + private final DOMDataTreeWriteTransaction writeDelegate; + private final Object identifier; + + DOMDataTransactionAdapter(@Nonnull DOMDataTreeReadTransaction readDelegate) { + this.readDelegate = Preconditions.checkNotNull(readDelegate); + this.identifier = readDelegate.getIdentifier(); + this.writeDelegate = null; + } + + DOMDataTransactionAdapter(@Nonnull DOMDataTreeWriteTransaction writeDelegate) { + this.writeDelegate = Preconditions.checkNotNull(writeDelegate); + this.identifier = writeDelegate.getIdentifier(); + this.readDelegate = null; + } + + DOMDataTransactionAdapter(@Nonnull DOMDataTreeReadWriteTransaction rwDelegate) { + this.readDelegate = Preconditions.checkNotNull(rwDelegate); + this.writeDelegate = rwDelegate; + this.identifier = readDelegate.getIdentifier(); + } + + DOMDataTreeReadTransaction readDelegate() { + return readDelegate; + } + + DOMDataTreeWriteTransaction writeDelegate() { + return writeDelegate; + } + + @Override + public Object getIdentifier() { + return identifier; + } + + @Override + public CheckedFuture>, ReadFailedException> read(LogicalDatastoreType store, + YangInstanceIdentifier path) { + return MappingCheckedFuture.create(readDelegate().read(convert(store), path), + LegacyDOMStoreAdapter.READ_EX_MAPPER); + } + + @Override + public CheckedFuture exists(LogicalDatastoreType store, + YangInstanceIdentifier path) { + return MappingCheckedFuture.create(readDelegate().exists(convert(store), path), + LegacyDOMStoreAdapter.READ_EX_MAPPER); + } + + @Override + public void delete(LogicalDatastoreType store, YangInstanceIdentifier path) { + writeDelegate().delete(convert(store), path); + } + + @Override + public void put(LogicalDatastoreType store, YangInstanceIdentifier path, NormalizedNode data) { + writeDelegate().put(convert(store), path, data); + } + + @Override + public void merge(LogicalDatastoreType store, YangInstanceIdentifier path, NormalizedNode data) { + writeDelegate().merge(convert(store), path, data); + } + + @Override + public boolean cancel() { + return writeDelegate().cancel(); + } + + @Override + public CheckedFuture submit() { + return MappingCheckedFuture.create(writeDelegate().submit(), SUBMIT_EX_MAPPER); + } + + @Override + public ListenableFuture> commit() { + return AbstractDataTransaction.convertToLegacyCommitFuture(submit()); + } + } + + private static class DOMDataReadOnlyTransactionAdapter implements DOMDataReadOnlyTransaction { + private final DOMDataTransactionAdapter adapter; + + DOMDataReadOnlyTransactionAdapter(DOMDataTreeReadTransaction delegateTx) { + adapter = new DOMDataTransactionAdapter(delegateTx); + } + + @Override + public CheckedFuture>, ReadFailedException> read(LogicalDatastoreType store, + YangInstanceIdentifier path) { + return adapter.read(store, path); + } + + @Override + public CheckedFuture exists(LogicalDatastoreType store, + YangInstanceIdentifier path) { + return adapter.exists(store, path); + } + + @Override + public Object getIdentifier() { + return adapter.getIdentifier(); + } + + @Override + public void close() { + adapter.readDelegate().close(); + } + } +}