Report ExactDataObjectStep from DataObjectModification
[mdsal.git] / dom / mdsal-dom-broker / src / main / java / org / opendaylight / mdsal / dom / broker / AbstractDOMDataBroker.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.mdsal.dom.broker;
9
10 import java.util.EnumMap;
11 import java.util.List;
12 import java.util.Map;
13 import java.util.concurrent.atomic.AtomicLong;
14 import org.eclipse.jdt.annotation.NonNull;
15 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
16 import org.opendaylight.mdsal.dom.api.DOMDataTreeChangeService;
17 import org.opendaylight.mdsal.dom.api.DOMTransactionChain;
18 import org.opendaylight.mdsal.dom.spi.PingPongMergingDOMDataBroker;
19 import org.opendaylight.mdsal.dom.spi.store.DOMStore;
20 import org.opendaylight.mdsal.dom.spi.store.DOMStoreTransactionChain;
21 import org.opendaylight.mdsal.dom.spi.store.DOMStoreTreeChangePublisher;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
24
25 public abstract class AbstractDOMDataBroker extends AbstractDOMForwardedTransactionFactory<DOMStore>
26         implements PingPongMergingDOMDataBroker {
27     private static final Logger LOG = LoggerFactory.getLogger(AbstractDOMDataBroker.class);
28
29     private final AtomicLong txNum = new AtomicLong();
30     private final AtomicLong chainNum = new AtomicLong();
31     private final @NonNull List<Extension> supportedExtensions;
32
33     private volatile AutoCloseable closeable;
34
35     protected AbstractDOMDataBroker(final Map<LogicalDatastoreType, DOMStore> datastores) {
36         super(datastores);
37
38         boolean treeChange = true;
39         for (var ds : datastores.values()) {
40             if (!(ds instanceof DOMStoreTreeChangePublisher)) {
41                 treeChange = false;
42                 break;
43             }
44         }
45
46         if (treeChange) {
47             supportedExtensions = List.of((DOMDataTreeChangeService) (treeId, listener) -> {
48                 final var dsType = treeId.datastore();
49                 if (getTxFactories().get(dsType) instanceof DOMStoreTreeChangePublisher publisher) {
50                     return publisher.registerTreeChangeListener(treeId.path(), listener);
51                 }
52                 throw new IllegalStateException("Publisher for " + dsType + " data store is not available");
53             });
54         } else {
55             supportedExtensions = List.of();
56         }
57     }
58
59     public void setCloseable(final AutoCloseable closeable) {
60         this.closeable = closeable;
61     }
62
63     @SuppressWarnings("checkstyle:IllegalCatch")
64     @Override
65     public void close() {
66         super.close();
67
68         if (closeable != null) {
69             try {
70                 closeable.close();
71             } catch (Exception e) {
72                 LOG.debug("Error closing instance", e);
73             }
74         }
75     }
76
77     @Override
78     protected Object newTransactionIdentifier() {
79         return "DOM-" + txNum.getAndIncrement();
80     }
81
82     @Override
83     public final List<Extension> supportedExtensions() {
84         return supportedExtensions;
85     }
86
87
88     @Override
89     public DOMTransactionChain createTransactionChain() {
90         checkNotClosed();
91
92         final var delegates = new EnumMap<LogicalDatastoreType, DOMStoreTransactionChain>(LogicalDatastoreType.class);
93         for (var entry : getTxFactories().entrySet()) {
94             delegates.put(entry.getKey(), entry.getValue().createTransactionChain());
95         }
96
97         final long chainId = chainNum.getAndIncrement();
98         LOG.debug("Transactoin chain {} created, backing store chains {}", chainId, delegates);
99         return new DOMDataBrokerTransactionChainImpl(chainId, delegates, this);
100     }
101 }