X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=bgp%2Ftopology-provider%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fbgpcep%2Fbgp%2Ftopology%2Fprovider%2FAbstractTopologyBuilder.java;h=c59e499395254b5197a305242b77461ba13816d5;hb=3c135df98a164d4207775de96a5217a392d1949e;hp=ef3a978135a3c519ba351cace5069757e7d317ec;hpb=8d6756a51b9a30104ee9a12a4882924d444d9a90;p=bgpcep.git diff --git a/bgp/topology-provider/src/main/java/org/opendaylight/bgpcep/bgp/topology/provider/AbstractTopologyBuilder.java b/bgp/topology-provider/src/main/java/org/opendaylight/bgpcep/bgp/topology/provider/AbstractTopologyBuilder.java index ef3a978135..c59e499395 100644 --- a/bgp/topology-provider/src/main/java/org/opendaylight/bgpcep/bgp/topology/provider/AbstractTopologyBuilder.java +++ b/bgp/topology-provider/src/main/java/org/opendaylight/bgpcep/bgp/topology/provider/AbstractTopologyBuilder.java @@ -7,21 +7,25 @@ */ package org.opendaylight.bgpcep.bgp.topology.provider; -import com.google.common.base.Optional; import com.google.common.base.Preconditions; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; +import java.util.Collections; import java.util.HashSet; import java.util.Map; import java.util.Set; -import java.util.concurrent.ExecutionException; +import javax.annotation.concurrent.GuardedBy; import org.opendaylight.bgpcep.topology.TopologyReference; +import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.DataChangeListener; import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction; import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent; +import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.controller.md.sal.common.api.data.TransactionChain; +import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener; import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; import org.opendaylight.protocol.bgp.rib.RibReference; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.Route; @@ -35,41 +39,40 @@ import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology. import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.TopologyTypes; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public abstract class AbstractTopologyBuilder implements AutoCloseable, DataChangeListener, LocRIBListener, TopologyReference { +public abstract class AbstractTopologyBuilder implements AutoCloseable, DataChangeListener, LocRIBListener, TopologyReference, TransactionChainListener { private static final Logger LOG = LoggerFactory.getLogger(AbstractTopologyBuilder.class); - private final RibReference locRibReference; private final InstanceIdentifier topology; - private final DataBroker dataProvider; + private final BindingTransactionChain chain; + private final RibReference locRibReference; private final Class idClass; + @GuardedBy("this") + private boolean closed = false; + protected AbstractTopologyBuilder(final DataBroker dataProvider, final RibReference locRibReference, final TopologyId topologyId, final TopologyTypes types, final Class idClass) { - this.dataProvider = Preconditions.checkNotNull(dataProvider); this.locRibReference = Preconditions.checkNotNull(locRibReference); this.idClass = Preconditions.checkNotNull(idClass); + this.chain = dataProvider.createTransactionChain(this); final TopologyKey tk = new TopologyKey(Preconditions.checkNotNull(topologyId)); - this.topology = InstanceIdentifier.builder(NetworkTopology.class).child(Topology.class, tk).toInstance(); + this.topology = InstanceIdentifier.builder(NetworkTopology.class).child(Topology.class, tk).build(); LOG.debug("Initiating topology builder from {} at {}", locRibReference, this.topology); - final ReadWriteTransaction t = dataProvider.newReadWriteTransaction(); - final Optional o; - try { - o = t.read(LogicalDatastoreType.OPERATIONAL, this.topology).get(); - } catch (InterruptedException | ExecutionException e) { - throw new IllegalStateException("Failed to read topology " + topology, e); - } - Preconditions.checkState(!o.isPresent(), "Data provider conflict detected on object {}", this.topology); + final WriteTransaction t = this.chain.newWriteOnlyTransaction(); t.put(LogicalDatastoreType.OPERATIONAL, this.topology, - new TopologyBuilder().setKey(tk).setServerProvided(Boolean.TRUE).setTopologyTypes(types).build()); + new TopologyBuilder().setKey(tk).setServerProvided(Boolean.TRUE).setTopologyTypes(types) + .setLink(Collections.emptyList()).setNode(Collections.emptyList()).build(), true); Futures.addCallback(t.submit(), new FutureCallback() { @Override public void onSuccess(final Void result) { @@ -86,17 +89,13 @@ public abstract class AbstractTopologyBuilder implements AutoCl public final InstanceIdentifier tableInstanceIdentifier(final Class afi, final Class safi) { - return this.locRibReference.getInstanceIdentifier().builder().child(LocRib.class).child(Tables.class, new TablesKey(afi, safi)).toInstance(); + return this.locRibReference.getInstanceIdentifier().builder().child(LocRib.class).child(Tables.class, new TablesKey(afi, safi)).build(); } protected abstract void createObject(ReadWriteTransaction trans, InstanceIdentifier id, T value); protected abstract void removeObject(ReadWriteTransaction trans, InstanceIdentifier id, T value); - public final DataBroker getDataProvider() { - return this.dataProvider; - } - @Override public final InstanceIdentifier getInstanceIdentifier() { return this.topology; @@ -112,9 +111,13 @@ public abstract class AbstractTopologyBuilder implements AutoCl } @Override - public final void onLocRIBChange(final ReadWriteTransaction trans, + public final synchronized void onLocRIBChange(final ReadWriteTransaction trans, final AsyncDataChangeEvent, DataObject> event) { LOG.debug("Received data change {} event with transaction {}", event, trans.getIdentifier()); + if (this.closed) { + LOG.trace("Transaction chain was already closed, skipping update."); + return; + } // FIXME: speed this up final Set> ids = new HashSet<>(); @@ -161,16 +164,18 @@ public abstract class AbstractTopologyBuilder implements AutoCl } @Override - public final void close() throws TransactionCommitFailedException { + public final synchronized void close() throws TransactionCommitFailedException { LOG.info("Shutting down builder for {}", getInstanceIdentifier()); - final WriteTransaction trans = this.dataProvider.newWriteOnlyTransaction(); + final WriteTransaction trans = this.chain.newWriteOnlyTransaction(); trans.delete(LogicalDatastoreType.OPERATIONAL, getInstanceIdentifier()); trans.submit().checkedGet(); + this.chain.close(); + this.closed = true; } @Override public final void onDataChanged(final AsyncDataChangeEvent, DataObject> change) { - final ReadWriteTransaction trans = this.dataProvider.newReadWriteTransaction(); + final ReadWriteTransaction trans = this.chain.newReadWriteTransaction(); try { onLocRIBChange(trans, change); @@ -179,4 +184,15 @@ public abstract class AbstractTopologyBuilder implements AutoCl return; } } + + @Override + public final void onTransactionChainFailed(final TransactionChain chain, final AsyncTransaction transaction, final Throwable cause) { + // TODO: restart? + LOG.error("Topology builder for {} failed in transaction {}", getInstanceIdentifier(), transaction.getIdentifier(), cause); + } + + @Override + public final void onTransactionChainSuccessful(final TransactionChain chain) { + LOG.info("Topology builder for {} shut down", getInstanceIdentifier()); + } }