return;
}
elanClusterUtils.runOnlyInOwnerNode(elanName, "updating mcast mac upon tunnel event",
- () -> Collections.singletonList(
- elanL2GatewayMulticastUtils.updateRemoteMcastMacOnElanL2GwDevices(elanName)));
+ () -> {
+ elanL2GatewayMulticastUtils.updateRemoteMcastMacOnElanL2GwDevices(elanName);
+ return Collections.emptyList();
+ });
}
@Override
package org.opendaylight.netvirt.elan.internal;
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+import static org.opendaylight.genius.infra.Datastore.OPERATIONAL;
+
import com.google.common.base.Optional;
import com.google.common.util.concurrent.ListenableFuture;
import java.util.ArrayList;
}
elanInterfaceCache.getInterfaceNames(elanName).forEach(
elanInterfaceName -> jobCoordinator.enqueueJob(ElanUtils.getElanInterfaceJobKey(elanInterfaceName),
- () -> Collections.singletonList(txRunner.callWithNewReadWriteTransactionAndSubmit(tx -> {
+ () -> Collections.singletonList(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
LOG.info("Deleting the elanInterface present under ConfigDS:{}", elanInterfaceName);
- ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION,
- ElanUtils.getElanInterfaceConfigurationDataPathId(elanInterfaceName));
+ tx.delete(ElanUtils.getElanInterfaceConfigurationDataPathId(elanInterfaceName));
elanInterfaceManager.unbindService(elanInterfaceName, tx);
LOG.info("unbind the Interface:{} service bounded to Elan:{}", elanInterfaceName, elanName);
})), ElanConstants.JOB_MAX_RETRIES));
if (existingElanTag == null || !existingElanTag.equals(update.getElanTag())) {
if (update.getElanTag() == null || update.getElanTag() == 0L) {
// update the elan-Instance with new properties
- ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(
- tx -> ElanUtils.updateOperationalDataStore(idManager, update, new ArrayList<>(), tx)),
- LOG, "Error updating ELAN tag in ELAN instance");
+ ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL,
+ operTx -> ListenableFutures.addErrorLogging(
+ txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
+ confTx -> ElanUtils.updateOperationalDataStore(idManager, update, new ArrayList<>(), confTx,
+ operTx)), LOG, "Error updating ELAN tag in ELAN instance")), LOG,
+ "Error updating ELAN tag in ELAN instance");
} else {
jobCoordinator.enqueueJob(elanName, () -> elanInterfaceManager.handleunprocessedElanInterfaces(update),
ElanConstants.JOB_MAX_RETRIES);
@Override
protected void add(InstanceIdentifier<ElanInstance> identifier, ElanInstance elanInstanceAdded) {
- ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(tx -> {
+ ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, operTx -> {
String elanInstanceName = elanInstanceAdded.getElanInstanceName();
- Elan elanInfo = ElanUtils.getElanByName(tx, elanInstanceName);
+ Elan elanInfo = ElanUtils.getElanByName(operTx, elanInstanceName);
if (elanInfo == null) {
- ElanUtils.updateOperationalDataStore(idManager, elanInstanceAdded, new ArrayList<>(), tx);
+ ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
+ confTx -> ElanUtils.updateOperationalDataStore(idManager, elanInstanceAdded, new ArrayList<>(),
+ confTx, operTx)), LOG, "Error adding an ELAN instance");
}
}), LOG, "Error adding an ELAN instance");
}
*/
package org.opendaylight.netvirt.elan.internal;
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+
import com.google.common.base.Optional;
import java.util.Collections;
import javax.annotation.PostConstruct;
return;
}
jobCoordinator.enqueueJob(ElanUtils.getElanInterfaceJobKey(interfaceName),
- () -> Collections.singletonList(txRunner.callWithNewReadWriteTransactionAndSubmit(tx -> {
+ () -> Collections.singletonList(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
LOG.debug("unbinding elan service on interface {} for its config removal", interfaceName);
elanInterfaceManager.unbindService(interfaceName, tx);
})), ElanConstants.JOB_MAX_RETRIES);
*/
package org.opendaylight.netvirt.elan.internal;
+import static org.opendaylight.controller.md.sal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+import static org.opendaylight.genius.infra.Datastore.OPERATIONAL;
import static org.opendaylight.netvirt.elan.utils.ElanUtils.isVxlanNetworkOrVxlanSegment;
import com.google.common.base.Optional;
import javax.inject.Singleton;
import org.apache.commons.lang3.StringUtils;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-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.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
import org.opendaylight.genius.infra.Datastore.Configuration;
+import org.opendaylight.genius.infra.Datastore.Operational;
import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.genius.infra.TransactionAdapter;
import org.opendaylight.genius.infra.TypedReadWriteTransaction;
+import org.opendaylight.genius.infra.TypedWriteTransaction;
import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo;
import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
import org.opendaylight.genius.itm.globals.ITMConstants;
jobCoordinator.enqueueJob(elanInstanceName, configWorker, ElanConstants.JOB_MAX_RETRIES);
}
+ private static class RemoveElanInterfaceHolder {
+ boolean isLastElanInterface = false;
+ boolean isLastInterfaceOnDpn = false;
+ BigInteger dpId = null;
+ }
+
@SuppressWarnings("checkstyle:ForbidCertainMethod")
public List<ListenableFuture<Void>> removeElanInterface(ElanInstance elanInfo, String interfaceName,
InterfaceInfo interfaceInfo) {
String elanName = elanInfo.getElanInstanceName();
- boolean isLastElanInterface = false;
- boolean isLastInterfaceOnDpn = false;
- BigInteger dpId = null;
long elanTag = elanInfo.getElanTag();
// We use two transaction so we don't suffer on multiple shards (interfaces and flows)
- WriteTransaction interfaceTx = broker.newWriteOnlyTransaction();
- Elan elanState = removeElanStateForInterface(elanInfo, interfaceName, interfaceTx);
- if (elanState == null) {
- interfaceTx.cancel();
- return Collections.emptyList();
- }
- WriteTransaction flowTx = broker.newWriteOnlyTransaction();
- List<String> elanInterfaces = elanState.getElanInterfaces();
- if (elanInterfaces.isEmpty()) {
- isLastElanInterface = true;
- }
- if (interfaceInfo != null) {
- dpId = interfaceInfo.getDpId();
- DpnInterfaces dpnInterfaces = removeElanDpnInterfaceFromOperationalDataStore(elanName, dpId,
- interfaceName, elanTag, interfaceTx);
- /*
- * If there are not elan ports, remove the unknown dmac, terminating
- * service table flows, remote/local bc group
- */
- if (dpnInterfaces == null || dpnInterfaces.getInterfaces() == null
- || dpnInterfaces.getInterfaces().isEmpty()) {
- // No more Elan Interfaces in this DPN
- LOG.debug("deleting the elan: {} present on dpId: {}", elanInfo.getElanInstanceName(), dpId);
- if (!elanUtils.isOpenstackVniSemanticsEnforced()) {
- removeDefaultTermFlow(dpId, elanInfo.getElanTag());
+ List<ListenableFuture<Void>> futures = new ArrayList<>();
+ RemoveElanInterfaceHolder holder = new RemoveElanInterfaceHolder();
+ futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, interfaceTx -> {
+ Elan elanState = removeElanStateForInterface(elanInfo, interfaceName, interfaceTx);
+ if (elanState == null) {
+ return;
+ }
+ futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, flowTx -> {
+ List<String> elanInterfaces = elanState.getElanInterfaces();
+ if (elanInterfaces.isEmpty()) {
+ holder.isLastElanInterface = true;
}
- removeUnknownDmacFlow(dpId, elanInfo, flowTx, elanInfo.getElanTag());
- removeEtreeUnknownDmacFlow(dpId, elanInfo, flowTx);
- removeElanBroadcastGroup(elanInfo, interfaceInfo, flowTx);
- removeLocalBroadcastGroup(elanInfo, interfaceInfo, flowTx);
- removeEtreeBroadcastGrups(elanInfo, interfaceInfo, flowTx);
- if (isVxlanNetworkOrVxlanSegment(elanInfo)) {
- if (elanUtils.isOpenstackVniSemanticsEnforced()) {
- elanUtils.removeTerminatingServiceAction(dpId,
- ElanUtils.getVxlanSegmentationId(elanInfo).intValue());
+ if (interfaceInfo != null) {
+ holder.dpId = interfaceInfo.getDpId();
+ DpnInterfaces dpnInterfaces = removeElanDpnInterfaceFromOperationalDataStore(elanName, holder.dpId,
+ interfaceName, elanTag, interfaceTx);
+ /*
+ * If there are not elan ports, remove the unknown dmac, terminating
+ * service table flows, remote/local bc group
+ */
+ if (dpnInterfaces == null || dpnInterfaces.getInterfaces() == null
+ || dpnInterfaces.getInterfaces().isEmpty()) {
+ // No more Elan Interfaces in this DPN
+ LOG.debug("deleting the elan: {} present on dpId: {}", elanInfo.getElanInstanceName(),
+ holder.dpId);
+ if (!elanUtils.isOpenstackVniSemanticsEnforced()) {
+ removeDefaultTermFlow(holder.dpId, elanInfo.getElanTag());
+ }
+ removeUnknownDmacFlow(holder.dpId, elanInfo, flowTx, elanInfo.getElanTag());
+ removeEtreeUnknownDmacFlow(holder.dpId, elanInfo, flowTx);
+ removeElanBroadcastGroup(elanInfo, interfaceInfo, flowTx);
+ removeLocalBroadcastGroup(elanInfo, interfaceInfo, flowTx);
+ removeEtreeBroadcastGrups(elanInfo, interfaceInfo, flowTx);
+ if (isVxlanNetworkOrVxlanSegment(elanInfo)) {
+ if (elanUtils.isOpenstackVniSemanticsEnforced()) {
+ elanUtils.removeTerminatingServiceAction(holder.dpId,
+ ElanUtils.getVxlanSegmentationId(elanInfo).intValue());
+ }
+ unsetExternalTunnelTable(holder.dpId, elanInfo);
+ }
+ holder.isLastInterfaceOnDpn = true;
+ } else {
+ setupLocalBroadcastGroups(elanInfo, dpnInterfaces, interfaceInfo);
}
- unsetExternalTunnelTable(dpId, elanInfo);
}
- isLastInterfaceOnDpn = true;
- } else {
- setupLocalBroadcastGroups(elanInfo, dpnInterfaces, interfaceInfo);
- }
- }
-
- List<ListenableFuture<Void>> futures = new ArrayList<>();
- futures.add(ElanUtils.waitForTransactionToComplete(interfaceTx));
- futures.add(ElanUtils.waitForTransactionToComplete(flowTx));
+ }));
+ }));
+ futures.forEach(ElanUtils::waitForTransactionToComplete);
- if (isLastInterfaceOnDpn && dpId != null && isVxlanNetworkOrVxlanSegment(elanInfo)) {
- setElanAndEtreeBCGrouponOtherDpns(elanInfo, dpId);
+ if (holder.isLastInterfaceOnDpn && holder.dpId != null && isVxlanNetworkOrVxlanSegment(elanInfo)) {
+ setElanAndEtreeBCGrouponOtherDpns(elanInfo, holder.dpId);
}
InterfaceRemoveWorkerOnElanInterface removeInterfaceWorker = new InterfaceRemoveWorkerOnElanInterface(
- interfaceName, elanInfo, interfaceInfo, this, isLastElanInterface);
+ interfaceName, elanInfo, interfaceInfo, this, holder.isLastElanInterface);
jobCoordinator.enqueueJob(ElanUtils.getElanInterfaceJobKey(interfaceName), removeInterfaceWorker,
ElanConstants.JOB_MAX_RETRIES);
}
private void removeEtreeUnknownDmacFlow(BigInteger dpId, ElanInstance elanInfo,
- WriteTransaction deleteFlowGroupTx) {
+ TypedReadWriteTransaction<Configuration> deleteFlowGroupTx)
+ throws ExecutionException, InterruptedException {
EtreeLeafTagName etreeLeafTag = elanEtreeUtils.getEtreeLeafTagByElanTag(elanInfo.getElanTag());
if (etreeLeafTag != null) {
long leafTag = etreeLeafTag.getEtreeLeafTag().getValue();
}
private void removeEtreeBroadcastGrups(ElanInstance elanInfo, InterfaceInfo interfaceInfo,
- WriteTransaction deleteFlowGroupTx) {
+ TypedReadWriteTransaction<Configuration> deleteFlowGroupTx)
+ throws ExecutionException, InterruptedException {
removeLeavesEtreeBroadcastGroup(elanInfo, interfaceInfo, deleteFlowGroupTx);
removeLeavesLocalBroadcastGroup(elanInfo, interfaceInfo, deleteFlowGroupTx);
}
private void removeLeavesLocalBroadcastGroup(ElanInstance elanInfo, InterfaceInfo interfaceInfo,
- WriteTransaction deleteFlowGroupTx) {
+ TypedReadWriteTransaction<Configuration> deleteFlowGroupTx)
+ throws ExecutionException, InterruptedException {
EtreeInstance etreeInstance = elanInfo.augmentation(EtreeInstance.class);
if (etreeInstance != null) {
BigInteger dpnId = interfaceInfo.getDpId();
long groupId = ElanUtils.getEtreeLeafLocalBCGId(etreeInstance.getEtreeLeafTagVal().getValue());
- List<Bucket> listBuckets = new ArrayList<>();
- int bucketId = 0;
- listBuckets.add(getLocalBCGroupBucketInfo(interfaceInfo, bucketId));
- Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll,
- MDSALUtil.buildBucketLists(listBuckets));
- LOG.trace("deleted the localBroadCast Group:{}", group);
- mdsalManager.removeGroupToTx(dpnId, group, deleteFlowGroupTx);
+ LOG.trace("deleted the localBroadCast Group:{}", groupId);
+ mdsalManager.removeGroup(deleteFlowGroupTx, dpnId, groupId);
}
}
private void removeLeavesEtreeBroadcastGroup(ElanInstance elanInfo, InterfaceInfo interfaceInfo,
- WriteTransaction deleteFlowGroupTx) {
+ TypedReadWriteTransaction<Configuration> deleteFlowGroupTx)
+ throws ExecutionException, InterruptedException {
EtreeInstance etreeInstance = elanInfo.augmentation(EtreeInstance.class);
if (etreeInstance != null) {
long etreeTag = etreeInstance.getEtreeLeafTagVal().getValue();
- int bucketId = 0;
- int actionKey = 0;
- List<Bucket> listBuckets = new ArrayList<>();
- List<Action> listAction = new ArrayList<>();
- listAction.add(new ActionGroup(ElanUtils.getEtreeLeafLocalBCGId(etreeTag)).buildAction(++actionKey));
- listBuckets.add(MDSALUtil.buildBucket(listAction, MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT,
- MDSALUtil.WATCH_GROUP));
- bucketId++;
- listBuckets.addAll(getRemoteBCGroupBucketInfos(elanInfo, bucketId, interfaceInfo, etreeTag));
BigInteger dpnId = interfaceInfo.getDpId();
long groupId = ElanUtils.getEtreeLeafRemoteBCGId(etreeTag);
- Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll,
- MDSALUtil.buildBucketLists(listBuckets));
- LOG.trace("deleting the remoteBroadCast group:{}", group);
- mdsalManager.removeGroupToTx(dpnId, group, deleteFlowGroupTx);
+ LOG.trace("deleting the remoteBroadCast group:{}", groupId);
+ mdsalManager.removeGroup(deleteFlowGroupTx, dpnId, groupId);
}
}
- private Elan removeElanStateForInterface(ElanInstance elanInfo, String interfaceName, WriteTransaction tx) {
+ private Elan removeElanStateForInterface(ElanInstance elanInfo, String interfaceName,
+ TypedReadWriteTransaction<Operational> tx) throws ExecutionException, InterruptedException {
String elanName = elanInfo.getElanInstanceName();
- Elan elanState = ElanUtils.getElanByName(broker, elanName);
+ Elan elanState = ElanUtils.getElanByName(tx, elanName);
if (elanState == null) {
return elanState;
}
}
if (elanInterfaces.isEmpty()) {
- tx.delete(LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanName));
- tx.delete(LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanMacTableOperationalDataPath(elanName));
- tx.delete(LogicalDatastoreType.OPERATIONAL,
- ElanUtils.getElanInfoEntriesOperationalDataPath(elanInfo.getElanTag()));
+ tx.delete(ElanUtils.getElanInstanceOperationalDataPath(elanName));
+ tx.delete(ElanUtils.getElanMacTableOperationalDataPath(elanName));
+ tx.delete(ElanUtils.getElanInfoEntriesOperationalDataPath(elanInfo.getElanTag()));
} else {
Elan updateElanState = new ElanBuilder().setElanInterfaces(elanInterfaces).setName(elanName)
.withKey(new ElanKey(elanName)).build();
- tx.put(LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanName),
- updateElanState);
+ tx.put(ElanUtils.getElanInstanceOperationalDataPath(elanName), updateElanState);
}
return elanState;
}
- private void deleteElanInterfaceFromConfigDS(String interfaceName, WriteTransaction tx) {
+ private void deleteElanInterfaceFromConfigDS(String interfaceName, TypedReadWriteTransaction<Configuration> tx)
+ throws ReadFailedException {
// removing the ElanInterface from the config data_store if interface is
// not present in Interface config DS
- if (interfaceManager.getInterfaceInfoFromConfigDataStore(interfaceName) == null
+ if (interfaceManager.getInterfaceInfoFromConfigDataStore(TransactionAdapter.toReadWriteTransaction(tx),
+ interfaceName) == null
&& elanInterfaceCache.get(interfaceName).isPresent()) {
- tx.delete(LogicalDatastoreType.CONFIGURATION,
- ElanUtils.getElanInterfaceConfigurationDataPathId(interfaceName));
+ tx.delete(ElanUtils.getElanInterfaceConfigurationDataPathId(interfaceName));
}
}
String elanName = elanInfo.getElanInstanceName();
List<ListenableFuture<Void>> futures = new ArrayList<>();
futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, flowTx -> {
- futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(interfaceTx -> {
+ futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, interfaceTx -> {
InstanceIdentifier<ElanInterfaceMac> elanInterfaceId = ElanUtils
.getElanInterfaceMacEntriesOperationalDataPath(interfaceName);
- Optional<ElanInterfaceMac> existingElanInterfaceMac =
- interfaceTx.read(LogicalDatastoreType.OPERATIONAL, elanInterfaceId).checkedGet();
+ Optional<ElanInterfaceMac> existingElanInterfaceMac = interfaceTx.read(elanInterfaceId).get();
LOG.debug("Removing the Interface:{} from elan:{}", interfaceName, elanName);
if (interfaceInfo != null) {
if (existingElanInterfaceMac.isPresent()) {
Optional<MacEntry> macEntryOptional =
elanUtils.getMacEntryForElanInstance(interfaceTx, elanName, macAddress);
if (!isLastElanInterface && macEntryOptional.isPresent()) {
- interfaceTx.delete(LogicalDatastoreType.OPERATIONAL,
- ElanUtils.getMacEntryOperationalDataPath(elanName, macAddress));
+ interfaceTx.delete(ElanUtils.getMacEntryOperationalDataPath(elanName, macAddress));
}
elanUtils.deleteMacFlows(elanInfo, interfaceInfo, macEntry, flowTx);
macAddresses.add(macAddress);
for (MacEntry macEntry : macEntries) {
PhysAddress macAddress = macEntry.getMacAddress();
if (elanUtils.getMacEntryForElanInstance(elanName, macAddress).isPresent()) {
- interfaceTx.delete(LogicalDatastoreType.OPERATIONAL,
- ElanUtils.getMacEntryOperationalDataPath(elanName, macAddress));
+ interfaceTx.delete(ElanUtils.getMacEntryOperationalDataPath(elanName, macAddress));
}
}
}
}
if (existingElanInterfaceMac.isPresent()) {
- interfaceTx.delete(LogicalDatastoreType.OPERATIONAL, elanInterfaceId);
+ interfaceTx.delete(elanInterfaceId);
}
- unbindService(interfaceName, interfaceTx);
- deleteElanInterfaceFromConfigDS(interfaceName, interfaceTx);
+ unbindService(interfaceName, flowTx);
+ deleteElanInterfaceFromConfigDS(interfaceName, flowTx);
}));
}));
return futures;
private DpnInterfaces removeElanDpnInterfaceFromOperationalDataStore(String elanName, BigInteger dpId,
String interfaceName, long elanTag,
- WriteTransaction tx) {
+ TypedReadWriteTransaction<Operational> tx)
+ throws ExecutionException, InterruptedException {
synchronized (elanName.intern()) {
DpnInterfaces dpnInterfaces = elanUtils.getElanInterfaceInfoByElanDpn(elanName, dpId);
for (StaticMacEntries staticMacEntry : updatedEntries) {
InstanceIdentifier<MacEntry> macEntryIdentifier = getMacEntryOperationalDataPath(elanName,
staticMacEntry.getMacAddress());
- Optional<MacEntry> existingMacEntry = ElanUtils.read(broker,
- LogicalDatastoreType.OPERATIONAL, macEntryIdentifier);
- WriteTransaction tx = broker.newWriteOnlyTransaction();
- if (existingMacEntry.isPresent()) {
- elanForwardingEntriesHandler.updateElanInterfaceForwardingTablesList(
- elanName, interfaceName, existingMacEntry.get().getInterface(), existingMacEntry.get(),
- tx);
- } else {
- elanForwardingEntriesHandler.addElanInterfaceForwardingTableList(
- elanName, interfaceName, staticMacEntry, tx);
- }
- ListenableFutures.addErrorLogging(ElanUtils.waitForTransactionToComplete(tx), LOG,
- "Error in update: identifier={}, original={}, update={}", identifier, original, update);
+ ListenableFutures.addErrorLogging(ElanUtils.waitForTransactionToComplete(
+ txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, tx -> {
+ Optional<MacEntry> existingMacEntry = tx.read(macEntryIdentifier).get();
+ if (existingMacEntry.isPresent()) {
+ elanForwardingEntriesHandler.updateElanInterfaceForwardingTablesList(
+ elanName, interfaceName, existingMacEntry.get().getInterface(), existingMacEntry.get(),
+ tx);
+ } else {
+ elanForwardingEntriesHandler.addElanInterfaceForwardingTableList(
+ elanName, interfaceName, staticMacEntry, tx);
+ }
+ })), LOG, "Error in update: identifier={}, original={}, update={}", identifier, original, update);
}
}
@Override
protected void add(InstanceIdentifier<ElanInterface> identifier, ElanInterface elanInterfaceAdded) {
- ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
+ ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL, operTx -> {
String elanInstanceName = elanInterfaceAdded.getElanInstanceName();
String interfaceName = elanInterfaceAdded.getName();
InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
ElanInstance elanInstance = elanInstanceCache.get(elanInstanceName).orNull();
if (elanInstance == null) {
- elanInstance = new ElanInstanceBuilder().setElanInstanceName(elanInstanceName)
- .setDescription(elanInterfaceAdded.getDescription()).build();
// Add the ElanInstance in the Configuration data-store
List<String> elanInterfaces = new ArrayList<>();
elanInterfaces.add(interfaceName);
- elanInstance = ElanUtils.updateOperationalDataStore(idManager, elanInstance, elanInterfaces, tx);
+ elanInstance = txRunner.applyWithNewReadWriteTransactionAndSubmit(CONFIGURATION,
+ confTx -> ElanUtils.updateOperationalDataStore(idManager,
+ new ElanInstanceBuilder().setElanInstanceName(elanInstanceName).setDescription(
+ elanInterfaceAdded.getDescription()).build(), elanInterfaces, confTx, operTx)).get();
}
Long elanTag = elanInstance.getElanTag();
InterfaceAddWorkerOnElan addWorker = new InterfaceAddWorkerOnElan(elanInstanceName, elanInterfaceAdded,
interfaceInfo, elanInstance, this);
jobCoordinator.enqueueJob(elanInstanceName, addWorker, ElanConstants.JOB_MAX_RETRIES);
- }), LOG, "Error procedding added ELAN interface");
+ }), LOG, "Error processing added ELAN interface");
}
List<ListenableFuture<Void>> handleunprocessedElanInterfaces(ElanInstance elanInstance) {
}
void programRemoteDmacFlow(ElanInstance elanInstance, InterfaceInfo interfaceInfo,
- WriteTransaction writeFlowGroupTx) {
+ TypedWriteTransaction<Configuration> writeFlowGroupTx) {
ElanDpnInterfacesList elanDpnInterfacesList = elanUtils
.getElanDpnInterfacesList(elanInstance.getElanInstanceName());
List<DpnInterfaces> dpnInterfaceLists = null;
}
}
+ private static class AddElanInterfaceHolder {
+ private DpnInterfaces dpnInterfaces = null;
+ private boolean isFirstInterfaceInDpn = false;
+ private BigInteger dpId;
+ }
+
@SuppressWarnings("checkstyle:ForbidCertainMethod")
List<ListenableFuture<Void>> addElanInterface(ElanInterface elanInterface,
InterfaceInfo interfaceInfo, ElanInstance elanInstance) {
String interfaceName = elanInterface.getName();
String elanInstanceName = elanInterface.getElanInstanceName();
- Elan elanInfo = ElanUtils.getElanByName(broker, elanInstanceName);
- WriteTransaction tx = broker.newWriteOnlyTransaction();
- if (elanInfo == null) {
- List<String> elanInterfaces = new ArrayList<>();
- elanInterfaces.add(interfaceName);
- ElanUtils.updateOperationalDataStore(idManager, elanInstance, elanInterfaces, tx);
- } else {
- createElanStateList(elanInstanceName, interfaceName, tx);
- }
- boolean isFirstInterfaceInDpn = false;
- // Specific actions to the DPN where the ElanInterface has been added,
- // for example, programming the
- // External tunnel table if needed or adding the ElanInterface to the
- // DpnInterfaces in the operational DS.
- BigInteger dpId = interfaceInfo.getDpId();
- DpnInterfaces dpnInterfaces = null;
- if (dpId != null && !dpId.equals(ElanConstants.INVALID_DPN)) {
- synchronized (elanInstanceName.intern()) {
- InstanceIdentifier<DpnInterfaces> elanDpnInterfaces = ElanUtils
- .getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId);
- Optional<DpnInterfaces> existingElanDpnInterfaces = ElanUtils.read(broker,
- LogicalDatastoreType.OPERATIONAL, elanDpnInterfaces);
- if (ElanUtils.isVlan(elanInstance)) {
- isFirstInterfaceInDpn = checkIfFirstInterface(interfaceName,
+ List<ListenableFuture<Void>> futures = new ArrayList<>();
+ AddElanInterfaceHolder holder = new AddElanInterfaceHolder();
+ futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, operTx -> {
+ Elan elanInfo = ElanUtils.getElanByName(broker, elanInstanceName);
+ if (elanInfo == null) {
+ List<String> elanInterfaces = new ArrayList<>();
+ elanInterfaces.add(interfaceName);
+ futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
+ confTx -> ElanUtils.updateOperationalDataStore(idManager, elanInstance, elanInterfaces, confTx,
+ operTx)));
+ } else {
+ createElanStateList(elanInstanceName, interfaceName, operTx);
+ }
+ // Specific actions to the DPN where the ElanInterface has been added,
+ // for example, programming the
+ // External tunnel table if needed or adding the ElanInterface to the
+ // DpnInterfaces in the operational DS.
+ holder.dpId = interfaceInfo.getDpId();
+ if (holder.dpId != null && !holder.dpId.equals(ElanConstants.INVALID_DPN)) {
+ synchronized (elanInstanceName.intern()) {
+ InstanceIdentifier<DpnInterfaces> elanDpnInterfaces = ElanUtils
+ .getElanDpnInterfaceOperationalDataPath(elanInstanceName, holder.dpId);
+ Optional<DpnInterfaces> existingElanDpnInterfaces = operTx.read(elanDpnInterfaces).get();
+ if (ElanUtils.isVlan(elanInstance)) {
+ holder.isFirstInterfaceInDpn = checkIfFirstInterface(interfaceName,
elanInstanceName, existingElanDpnInterfaces);
- } else {
- isFirstInterfaceInDpn = !existingElanDpnInterfaces.isPresent();
- }
- if (isFirstInterfaceInDpn) {
- // ELAN's 1st ElanInterface added to this DPN
- if (!existingElanDpnInterfaces.isPresent()) {
- dpnInterfaces = createElanInterfacesList(elanInstanceName, interfaceName, dpId, tx);
+ } else {
+ holder.isFirstInterfaceInDpn = !existingElanDpnInterfaces.isPresent();
+ }
+ if (holder.isFirstInterfaceInDpn) {
+ // ELAN's 1st ElanInterface added to this DPN
+ if (!existingElanDpnInterfaces.isPresent()) {
+ holder.dpnInterfaces =
+ createElanInterfacesList(elanInstanceName, interfaceName, holder.dpId, operTx);
+ } else {
+ List<String> elanInterfaces = existingElanDpnInterfaces.get().getInterfaces();
+ elanInterfaces.add(interfaceName);
+ holder.dpnInterfaces = updateElanDpnInterfacesList(elanInstanceName, holder.dpId,
+ elanInterfaces, operTx);
+ }
+ // The 1st ElanInterface in a DPN must program the Ext Tunnel
+ // table, but only if Elan has VNI
+ if (isVxlanNetworkOrVxlanSegment(elanInstance)) {
+ setExternalTunnelTable(holder.dpId, elanInstance);
+ }
+ elanL2GatewayUtils.installElanL2gwDevicesLocalMacsInDpn(holder.dpId, elanInstance,
+ interfaceName);
} else {
List<String> elanInterfaces = existingElanDpnInterfaces.get().getInterfaces();
elanInterfaces.add(interfaceName);
- dpnInterfaces = updateElanDpnInterfacesList(elanInstanceName, dpId,
- elanInterfaces, tx);
- }
- // The 1st ElanInterface in a DPN must program the Ext Tunnel
- // table, but only if Elan has VNI
- if (isVxlanNetworkOrVxlanSegment(elanInstance)) {
- setExternalTunnelTable(dpId, elanInstance);
- }
- elanL2GatewayUtils.installElanL2gwDevicesLocalMacsInDpn(dpId, elanInstance, interfaceName);
- } else {
- List<String> elanInterfaces = existingElanDpnInterfaces.get().getInterfaces();
- elanInterfaces.add(interfaceName);
- if (elanInterfaces.size() == 1) { // 1st dpn interface
- elanL2GatewayUtils.installElanL2gwDevicesLocalMacsInDpn(dpId, elanInstance, interfaceName);
+ if (elanInterfaces.size() == 1) { // 1st dpn interface
+ elanL2GatewayUtils.installElanL2gwDevicesLocalMacsInDpn(holder.dpId, elanInstance,
+ interfaceName);
+ }
+ holder.dpnInterfaces =
+ updateElanDpnInterfacesList(elanInstanceName, holder.dpId, elanInterfaces, operTx);
}
- dpnInterfaces = updateElanDpnInterfacesList(elanInstanceName, dpId, elanInterfaces, tx);
}
}
- }
- // add code to install Local/Remote BC group, unknow DMAC entry,
- // terminating service table flow entry
- // call bindservice of interfacemanager to create ingress table flow
- // enty.
- // Add interface to the ElanInterfaceForwardingEntires Container
- createElanInterfaceTablesList(interfaceName, tx);
- List<ListenableFuture<Void>> futures = new ArrayList<>();
- futures.add(ElanUtils.waitForTransactionToComplete(tx));
- installEntriesForFirstInterfaceonDpn(elanInstance, interfaceInfo, dpnInterfaces, isFirstInterfaceInDpn);
+ // add code to install Local/Remote BC group, unknow DMAC entry,
+ // terminating service table flow entry
+ // call bindservice of interfacemanager to create ingress table flow
+ // enty.
+ // Add interface to the ElanInterfaceForwardingEntires Container
+ createElanInterfaceTablesList(interfaceName, operTx);
+ }));
+ futures.forEach(ElanUtils::waitForTransactionToComplete);
+ installEntriesForFirstInterfaceonDpn(elanInstance, interfaceInfo, holder.dpnInterfaces,
+ holder.isFirstInterfaceInDpn);
// add the vlan provider interface to remote BC group for the elan
// for internal vlan networks
if (ElanUtils.isVlan(elanInstance) && !elanInstance.isExternal()) {
if (interfaceManager.isExternalInterface(interfaceName)) {
LOG.debug("adding vlan prv intf {} to elan {} BC group", interfaceName, elanInstanceName);
- handleExternalInterfaceEvent(elanInstance, dpnInterfaces, dpId);
+ handleExternalInterfaceEvent(elanInstance, holder.dpnInterfaces, holder.dpId);
}
}
- if (isFirstInterfaceInDpn && isVxlanNetworkOrVxlanSegment(elanInstance)) {
+ if (holder.isFirstInterfaceInDpn && isVxlanNetworkOrVxlanSegment(elanInstance)) {
//update the remote-DPNs remoteBC group entry with Tunnels
- LOG.trace("update remote bc group for elan {} on other DPNs for newly added dpn {}", elanInstance, dpId);
- setElanAndEtreeBCGrouponOtherDpns(elanInstance, dpId);
+ LOG.trace("update remote bc group for elan {} on other DPNs for newly added dpn {}", elanInstance,
+ holder.dpId);
+ setElanAndEtreeBCGrouponOtherDpns(elanInstance, holder.dpId);
}
String jobKey = ElanUtils.getElanInterfaceJobKey(interfaceName);
InterfaceAddWorkerOnElanInterface addWorker = new InterfaceAddWorkerOnElanInterface(jobKey,
- elanInterface, interfaceInfo, elanInstance, isFirstInterfaceInDpn, this);
+ elanInterface, interfaceInfo, elanInstance, holder.isFirstInterfaceInDpn, this);
jobCoordinator.enqueueJob(jobKey, addWorker, ElanConstants.JOB_MAX_RETRIES);
return futures;
}
ElanInterface elanInterface, InterfaceInfo interfaceInfo, boolean isFirstInterfaceInDpn) {
String elanInstanceName = elanInstance.getElanInstanceName();
String interfaceName = elanInterface.getName();
- WriteTransaction tx = broker.newWriteOnlyTransaction();
+ List<ListenableFuture<Void>> futures = new ArrayList<>();
BigInteger dpId = interfaceInfo.getDpId();
- WriteTransaction writeFlowGroupTx = broker.newWriteOnlyTransaction();
- installEntriesForElanInterface(elanInstance, elanInterface, interfaceInfo,
- isFirstInterfaceInDpn, tx, writeFlowGroupTx);
-
- List<StaticMacEntries> staticMacEntriesList = elanInterface.getStaticMacEntries();
- List<PhysAddress> staticMacAddresses = Lists.newArrayList();
-
boolean isInterfaceOperational = isOperational(interfaceInfo);
- if (ElanUtils.isNotEmpty(staticMacEntriesList)) {
- for (StaticMacEntries staticMacEntry : staticMacEntriesList) {
- InstanceIdentifier<MacEntry> macId = getMacEntryOperationalDataPath(elanInstanceName,
- staticMacEntry.getMacAddress());
- Optional<MacEntry> existingMacEntry = ElanUtils.read(broker,
- LogicalDatastoreType.OPERATIONAL, macId);
- if (existingMacEntry.isPresent()) {
- elanForwardingEntriesHandler.updateElanInterfaceForwardingTablesList(
- elanInstanceName, interfaceName, existingMacEntry.get().getInterface(),
- existingMacEntry.get(), tx);
- } else {
- elanForwardingEntriesHandler
- .addElanInterfaceForwardingTableList(elanInstanceName, interfaceName, staticMacEntry, tx);
- }
+ futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, confTx -> {
+ futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, operTx -> {
+ installEntriesForElanInterface(elanInstance, elanInterface, interfaceInfo,
+ isFirstInterfaceInDpn, confTx, operTx);
+
+ List<StaticMacEntries> staticMacEntriesList = elanInterface.getStaticMacEntries();
+ List<PhysAddress> staticMacAddresses = Lists.newArrayList();
+
+ if (ElanUtils.isNotEmpty(staticMacEntriesList)) {
+ for (StaticMacEntries staticMacEntry : staticMacEntriesList) {
+ InstanceIdentifier<MacEntry> macId = getMacEntryOperationalDataPath(elanInstanceName,
+ staticMacEntry.getMacAddress());
+ Optional<MacEntry> existingMacEntry = ElanUtils.read(broker,
+ LogicalDatastoreType.OPERATIONAL, macId);
+ if (existingMacEntry.isPresent()) {
+ elanForwardingEntriesHandler.updateElanInterfaceForwardingTablesList(
+ elanInstanceName, interfaceName, existingMacEntry.get().getInterface(),
+ existingMacEntry.get(), operTx);
+ } else {
+ elanForwardingEntriesHandler.addElanInterfaceForwardingTableList(elanInstanceName,
+ interfaceName, staticMacEntry, operTx);
+ }
- if (isInterfaceOperational) {
- // Setting SMAC, DMAC, UDMAC in this DPN and also in other
- // DPNs
- String macAddress = staticMacEntry.getMacAddress().getValue();
- LOG.info("programming smac and dmacs for {} on source and other DPNs for elan {} and interface {}",
- macAddress, elanInstanceName, interfaceName);
- elanUtils.setupMacFlows(elanInstance, interfaceInfo, ElanConstants.STATIC_MAC_TIMEOUT,
- staticMacEntry.getMacAddress().getValue(), true, writeFlowGroupTx);
- }
- }
+ if (isInterfaceOperational) {
+ // Setting SMAC, DMAC, UDMAC in this DPN and also in other
+ // DPNs
+ String macAddress = staticMacEntry.getMacAddress().getValue();
+ LOG.info(
+ "programming smac and dmacs for {} on source and other DPNs for elan {} and interface"
+ + " {}",
+ macAddress, elanInstanceName, interfaceName);
+ elanUtils.setupMacFlows(elanInstance, interfaceInfo, ElanConstants.STATIC_MAC_TIMEOUT,
+ staticMacEntry.getMacAddress().getValue(), true, confTx);
+ }
+ }
- if (isInterfaceOperational) {
- // Add MAC in TOR's remote MACs via OVSDB. Outside of the loop
- // on purpose.
- for (StaticMacEntries staticMacEntry : staticMacEntriesList) {
- staticMacAddresses.add(staticMacEntry.getMacAddress());
+ if (isInterfaceOperational) {
+ // Add MAC in TOR's remote MACs via OVSDB. Outside of the loop
+ // on purpose.
+ for (StaticMacEntries staticMacEntry : staticMacEntriesList) {
+ staticMacAddresses.add(staticMacEntry.getMacAddress());
+ }
+ elanL2GatewayUtils.scheduleAddDpnMacInExtDevices(elanInstance.getElanInstanceName(), dpId,
+ staticMacAddresses);
+ }
}
- elanL2GatewayUtils.scheduleAddDpnMacInExtDevices(elanInstance.getElanInstanceName(), dpId,
- staticMacAddresses);
- }
- }
- List<ListenableFuture<Void>> futures = new ArrayList<>();
- futures.add(ElanUtils.waitForTransactionToComplete(tx));
- futures.add(ElanUtils.waitForTransactionToComplete(writeFlowGroupTx));
+ }));
+ }));
+ futures.forEach(ElanUtils::waitForTransactionToComplete);
if (isInterfaceOperational && !interfaceManager.isExternalInterface(interfaceName)) {
//At this point, the interface is operational and D/SMAC flows have been configured, mark the port active
try {
if (dpnInterfaces.getInterfaces().contains(elanInstanceName)) {
dummyInterfaceCount++;
}
- if (dpnInterfaces.getInterfaces().size() - dummyInterfaceCount == 0) {
- return true;
- }
- return false;
+ return dpnInterfaces.getInterfaces().size() - dummyInterfaceCount == 0;
}
private InstanceIdentifier<MacEntry> getMacEntryOperationalDataPath(String elanName, PhysAddress physAddress) {
}
private void installEntriesForElanInterface(ElanInstance elanInstance, ElanInterface elanInterface,
- InterfaceInfo interfaceInfo, boolean isFirstInterfaceInDpn, WriteTransaction tx,
- WriteTransaction writeFlowGroupTx) {
+ InterfaceInfo interfaceInfo, boolean isFirstInterfaceInDpn, TypedWriteTransaction<Configuration> confTx,
+ TypedWriteTransaction<Operational> operTx) {
if (!isOperational(interfaceInfo)) {
return;
}
BigInteger dpId = interfaceInfo.getDpId();
if (!elanUtils.isOpenstackVniSemanticsEnforced()) {
- elanUtils.setupTermDmacFlows(interfaceInfo, mdsalManager, writeFlowGroupTx);
+ elanUtils.setupTermDmacFlows(interfaceInfo, mdsalManager, confTx);
}
- setupFilterEqualsTable(elanInstance, interfaceInfo, writeFlowGroupTx);
+ setupFilterEqualsTable(elanInstance, interfaceInfo, confTx);
if (isFirstInterfaceInDpn) {
// Terminating Service , UnknownDMAC Table.
// The 1st ELAN Interface in a DPN must program the INTERNAL_TUNNEL_TABLE, but only if the network type
// for ELAN Instance is VxLAN
if (isVxlanNetworkOrVxlanSegment(elanInstance)) {
- setupTerminateServiceTable(elanInstance, dpId, writeFlowGroupTx);
+ setupTerminateServiceTable(elanInstance, dpId, confTx);
}
- setupUnknownDMacTable(elanInstance, dpId, writeFlowGroupTx);
+ setupUnknownDMacTable(elanInstance, dpId, confTx);
/*
* Install remote DMAC flow. This is required since this DPN is
* added later to the elan instance and remote DMACs of other
if (!interfaceManager.isExternalInterface(interfaceInfo.getInterfaceName())) {
LOG.info("Programming remote dmac flows on the newly connected dpn {} for elan {} ", dpId,
elanInstance.getElanInstanceName());
- programRemoteDmacFlow(elanInstance, interfaceInfo, writeFlowGroupTx);
+ programRemoteDmacFlow(elanInstance, interfaceInfo, confTx);
}
}
// bind the Elan service to the Interface
- bindService(elanInstance, elanInterface, interfaceInfo.getInterfaceTag(), tx);
+ bindService(elanInstance, elanInterface, interfaceInfo.getInterfaceTag(), confTx);
}
public void installEntriesForFirstInterfaceonDpn(ElanInstance elanInfo, InterfaceInfo interfaceInfo,
}
public void setupFilterEqualsTable(ElanInstance elanInfo, InterfaceInfo interfaceInfo,
- WriteTransaction writeFlowGroupTx) {
+ TypedWriteTransaction<Configuration> writeFlowGroupTx) {
int ifTag = interfaceInfo.getInterfaceTag();
Flow flow = MDSALUtil.buildFlowNew(NwConstants.ELAN_FILTER_EQUALS_TABLE,
getFlowRef(NwConstants.ELAN_FILTER_EQUALS_TABLE, ifTag, "group"), 9, elanInfo.getElanInstanceName(), 0,
ElanUtils.getTunnelIdMatchForFilterEqualsLPortTag(ifTag),
elanUtils.getInstructionsInPortForOutGroup(interfaceInfo.getInterfaceName()));
- mdsalManager.addFlowToTx(interfaceInfo.getDpId(), flow, writeFlowGroupTx);
+ mdsalManager.addFlow(writeFlowGroupTx, interfaceInfo.getDpId(), flow);
Flow flowEntry = MDSALUtil.buildFlowNew(NwConstants.ELAN_FILTER_EQUALS_TABLE,
getFlowRef(NwConstants.ELAN_FILTER_EQUALS_TABLE, ifTag, "drop"), 10, elanInfo.getElanInstanceName(), 0,
0, ElanConstants.COOKIE_ELAN_FILTER_EQUALS.add(BigInteger.valueOf(ifTag)),
getMatchesForFilterEqualsLPortTag(ifTag), MDSALUtil.buildInstructionsDrop());
- mdsalManager.addFlowToTx(interfaceInfo.getDpId(), flowEntry, writeFlowGroupTx);
+ mdsalManager.addFlow(writeFlowGroupTx, interfaceInfo.getDpId(), flowEntry);
}
public void removeFilterEqualsTable(ElanInstance elanInfo, InterfaceInfo interfaceInfo,
mdsalManager.removeFlow(flowTx, interfaceInfo.getDpId(), flowEntity);
}
- private List<Bucket> getRemoteBCGroupBucketInfos(ElanInstance elanInfo, int bucketKeyStart,
- InterfaceInfo interfaceInfo, long elanTag) {
- return elanL2GatewayMulticastUtils.getRemoteBCGroupBuckets(elanInfo, null, interfaceInfo.getDpId(),
- bucketKeyStart, elanTag);
- }
-
private void setElanAndEtreeBCGrouponOtherDpns(ElanInstance elanInfo, BigInteger dpId) {
int elanTag = elanInfo.getElanTag().intValue();
long groupId = ElanUtils.getElanRemoteBCGId(elanTag);
}
}
- /**
- * Returns the bucket info with the given interface as the only bucket.
- */
- private Bucket getLocalBCGroupBucketInfo(InterfaceInfo interfaceInfo, int bucketIdStart) {
- return MDSALUtil.buildBucket(getInterfacePortActions(interfaceInfo), MDSALUtil.GROUP_WEIGHT, bucketIdStart,
- MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP);
- }
-
private List<MatchInfo> buildMatchesForVni(Long vni) {
List<MatchInfo> mkMatches = new ArrayList<>();
MatchInfo match = new MatchTunnelId(BigInteger.valueOf(vni));
ElanInterfaceMac elanInterfaceMac = elanUtils.getElanInterfaceMacByInterfaceName(interfaceName);
if (elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null) {
List<MacEntry> macEntries = elanInterfaceMac.getMacEntry();
- WriteTransaction writeFlowTx = broker.newWriteOnlyTransaction();
- for (MacEntry macEntry : macEntries) {
- String macAddress = macEntry.getMacAddress().getValue();
- LOG.info("Installing remote dmac for mac address {} and interface {}", macAddress, interfaceName);
- synchronized (ElanUtils.getElanMacDPNKey(elanInfo.getElanTag(), macAddress,
- interfaceInfo.getDpId())) {
- LOG.info("Acquired lock for mac : {}, proceeding with remote dmac install operation", macAddress);
- elanUtils.setupDMacFlowOnRemoteDpn(elanInfo, interfaceInfo, dstDpId, macAddress,
- writeFlowTx);
- }
- }
- return Collections.singletonList(ElanUtils.waitForTransactionToComplete(writeFlowTx));
+ return Collections.singletonList(ElanUtils.waitForTransactionToComplete(
+ txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
+ for (MacEntry macEntry : macEntries) {
+ String macAddress = macEntry.getMacAddress().getValue();
+ LOG.info("Installing remote dmac for mac address {} and interface {}", macAddress,
+ interfaceName);
+ synchronized (ElanUtils.getElanMacDPNKey(elanInfo.getElanTag(), macAddress,
+ interfaceInfo.getDpId())) {
+ LOG.info("Acquired lock for mac : {}, proceeding with remote dmac install operation",
+ macAddress);
+ elanUtils.setupDMacFlowOnRemoteDpn(elanInfo, interfaceInfo, dstDpId, macAddress, tx);
+ }
+ }
+ })));
}
return Collections.emptyList();
}
}
public void removeLocalBroadcastGroup(ElanInstance elanInfo, InterfaceInfo interfaceInfo,
- WriteTransaction deleteFlowGroupTx) {
+ TypedReadWriteTransaction<Configuration> deleteFlowGroupTx)
+ throws ExecutionException, InterruptedException {
BigInteger dpnId = interfaceInfo.getDpId();
long groupId = ElanUtils.getElanLocalBCGId(elanInfo.getElanTag());
- List<Bucket> listBuckets = new ArrayList<>();
- int bucketId = 0;
- listBuckets.add(getLocalBCGroupBucketInfo(interfaceInfo, bucketId));
- // listBuckets.addAll(getRemoteBCGroupBucketInfos(elanInfo, 1,
- // interfaceInfo));
- Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll,
- MDSALUtil.buildBucketLists(listBuckets));
- LOG.trace("deleted the localBroadCast Group:{}", group);
- mdsalManager.removeGroupToTx(dpnId, group, deleteFlowGroupTx);
+ LOG.trace("deleted the localBroadCast Group:{}", groupId);
+ mdsalManager.removeGroup(deleteFlowGroupTx, dpnId, groupId);
}
public void removeElanBroadcastGroup(ElanInstance elanInfo, InterfaceInfo interfaceInfo,
- WriteTransaction deleteFlowGroupTx) {
- int bucketId = 0;
- int actionKey = 0;
- Long elanTag = elanInfo.getElanTag();
- List<Bucket> listBuckets = new ArrayList<>();
- List<Action> listAction = new ArrayList<>();
- listAction.add(new ActionGroup(++actionKey, ElanUtils.getElanLocalBCGId(elanTag)).buildAction());
- listBuckets.add(MDSALUtil.buildBucket(listAction, MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT,
- MDSALUtil.WATCH_GROUP));
- bucketId++;
- listBuckets.addAll(getRemoteBCGroupBucketInfos(elanInfo, bucketId, interfaceInfo, elanTag));
+ TypedReadWriteTransaction<Configuration> deleteFlowGroupTx)
+ throws ExecutionException, InterruptedException {
BigInteger dpnId = interfaceInfo.getDpId();
long groupId = ElanUtils.getElanRemoteBCGId(elanInfo.getElanTag());
- Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll,
- MDSALUtil.buildBucketLists(listBuckets));
- LOG.trace("deleting the remoteBroadCast group:{}", group);
- mdsalManager.removeGroupToTx(dpnId, group, deleteFlowGroupTx);
+ LOG.trace("deleting the remoteBroadCast group:{}", groupId);
+ mdsalManager.removeGroup(deleteFlowGroupTx, dpnId, groupId);
}
/**
mdsalManager.removeFlow(flowEntity);
}
- public void setupTerminateServiceTable(ElanInstance elanInfo, BigInteger dpId, WriteTransaction writeFlowGroupTx) {
+ public void setupTerminateServiceTable(ElanInstance elanInfo, BigInteger dpId,
+ TypedWriteTransaction<Configuration> writeFlowGroupTx) {
setupTerminateServiceTable(elanInfo, dpId, elanInfo.getElanTag(), writeFlowGroupTx);
setupEtreeTerminateServiceTable(elanInfo, dpId, writeFlowGroupTx);
}
public void setupTerminateServiceTable(ElanInstance elanInfo, BigInteger dpId, long elanTag,
- WriteTransaction writeFlowGroupTx) {
+ TypedWriteTransaction<Configuration> writeFlowGroupTx) {
List<? extends MatchInfoBase> listMatchInfoBase;
List<InstructionInfo> instructionInfos;
long serviceId;
getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE, serviceId), 5, String.format("%s:%d", "ITM Flow Entry ",
elanTag), 0, 0, ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(elanTag)), listMatchInfoBase,
instructionInfos);
- mdsalManager.addFlowToTx(flowEntity, writeFlowGroupTx);
+ mdsalManager.addFlow(writeFlowGroupTx, flowEntity);
}
private void setupEtreeTerminateServiceTable(ElanInstance elanInfo, BigInteger dpId,
- WriteTransaction writeFlowGroupTx) {
+ TypedWriteTransaction<Configuration> writeFlowGroupTx) {
EtreeInstance etreeInstance = elanInfo.augmentation(EtreeInstance.class);
if (etreeInstance != null) {
setupTerminateServiceTable(elanInfo, dpId, etreeInstance.getEtreeLeafTagVal().getValue(), writeFlowGroupTx);
}
}
- public void setupUnknownDMacTable(ElanInstance elanInfo, BigInteger dpId, WriteTransaction writeFlowGroupTx) {
+ public void setupUnknownDMacTable(ElanInstance elanInfo, BigInteger dpId,
+ TypedWriteTransaction<Configuration> writeFlowGroupTx) {
long elanTag = elanInfo.getElanTag();
installLocalUnknownFlow(elanInfo, dpId, elanTag, writeFlowGroupTx);
installRemoteUnknownFlow(elanInfo, dpId, elanTag, writeFlowGroupTx);
}
private void setupEtreeUnknownDMacTable(ElanInstance elanInfo, BigInteger dpId, long elanTag,
- WriteTransaction writeFlowGroupTx) {
+ TypedWriteTransaction<Configuration> writeFlowGroupTx) {
EtreeLeafTagName etreeLeafTag = elanEtreeUtils.getEtreeLeafTagByElanTag(elanTag);
if (etreeLeafTag != null) {
long leafTag = etreeLeafTag.getEtreeLeafTag().getValue();
}
private void installLocalUnknownFlow(ElanInstance elanInfo, BigInteger dpId, long elanTag,
- WriteTransaction writeFlowGroupTx) {
+ TypedWriteTransaction<Configuration> writeFlowGroupTx) {
FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.ELAN_UNKNOWN_DMAC_TABLE,
getUnknownDmacFlowRef(NwConstants.ELAN_UNKNOWN_DMAC_TABLE, elanTag,/* SH flag */false),
5, elanInfo.getElanInstanceName(), 0, 0,
getMatchesForElanTag(elanTag, /* SH flag */false),
getInstructionsForOutGroup(ElanUtils.getElanRemoteBCGId(elanTag)));
- mdsalManager.addFlowToTx(flowEntity, writeFlowGroupTx);
+ mdsalManager.addFlow(writeFlowGroupTx, flowEntity);
}
private void installRemoteUnknownFlow(ElanInstance elanInfo, BigInteger dpId, long elanTag,
- WriteTransaction writeFlowGroupTx) {
+ TypedWriteTransaction<Configuration> writeFlowGroupTx) {
// only if ELAN can connect to external network, perform the following
if (isVxlanNetworkOrVxlanSegment(elanInfo) || ElanUtils.isVlan(elanInfo) || ElanUtils.isFlat(elanInfo)) {
ElanConstants.COOKIE_ELAN_UNKNOWN_DMAC.add(BigInteger.valueOf(elanTag)),
getMatchesForElanTag(elanTag, /* SH flag */true),
getInstructionsForOutGroup(ElanUtils.getElanLocalBCGId(elanTag)));
- mdsalManager.addFlowToTx(flowEntity, writeFlowGroupTx);
+ mdsalManager.addFlow(writeFlowGroupTx, flowEntity);
}
}
- private void removeUnknownDmacFlow(BigInteger dpId, ElanInstance elanInfo, WriteTransaction deleteFlowGroupTx,
- long elanTag) {
+ private void removeUnknownDmacFlow(BigInteger dpId, ElanInstance elanInfo,
+ TypedReadWriteTransaction<Configuration> deleteFlowGroupTx, long elanTag)
+ throws ExecutionException, InterruptedException {
Flow flow = new FlowBuilder().setId(new FlowId(getUnknownDmacFlowRef(NwConstants.ELAN_UNKNOWN_DMAC_TABLE,
elanTag, SH_FLAG_UNSET))).setTableId(NwConstants.ELAN_UNKNOWN_DMAC_TABLE).build();
- mdsalManager.removeFlowToTx(dpId, flow, deleteFlowGroupTx);
+ mdsalManager.removeFlow(deleteFlowGroupTx, dpId, flow);
if (isVxlanNetworkOrVxlanSegment(elanInfo)) {
Flow flow2 = new FlowBuilder().setId(new FlowId(getUnknownDmacFlowRef(NwConstants.ELAN_UNKNOWN_DMAC_TABLE,
elanTag, SH_FLAG_SET))).setTableId(NwConstants.ELAN_UNKNOWN_DMAC_TABLE)
.build();
- mdsalManager.removeFlowToTx(dpId, flow2, deleteFlowGroupTx);
+ mdsalManager.removeFlow(deleteFlowGroupTx, dpId, flow2);
}
}
elanUtils.removeTerminatingServiceAction(dpId, (int) elanTag);
}
- private void bindService(ElanInstance elanInfo, ElanInterface elanInterface, int lportTag, WriteTransaction tx) {
+ private void bindService(ElanInstance elanInfo, ElanInterface elanInterface, int lportTag,
+ TypedWriteTransaction<Configuration> tx) {
if (isStandardElanService(elanInterface)) {
bindElanService(elanInfo.getElanTag(), elanInfo.getElanInstanceName(),
elanInterface.getName(), lportTag, tx);
}
private void bindElanService(long elanTag, String elanInstanceName, String interfaceName, int lportTag,
- WriteTransaction tx) {
+ TypedWriteTransaction<Configuration> tx) {
int instructionKey = 0;
List<Instruction> instructions = new ArrayList<>();
instructions.add(MDSALUtil.buildAndGetWriteMetadaInstruction(ElanHelper.getElanMetadataLabel(elanTag),
Optional<BoundServices> existingElanService = ElanUtils.read(broker, LogicalDatastoreType.CONFIGURATION,
bindServiceId);
if (!existingElanService.isPresent()) {
- tx.put(LogicalDatastoreType.CONFIGURATION, bindServiceId, serviceInfo,
- WriteTransaction.CREATE_MISSING_PARENTS);
+ tx.put(bindServiceId, serviceInfo, CREATE_MISSING_PARENTS);
}
}
private void bindEtreeService(ElanInstance elanInfo, ElanInterface elanInterface, int lportTag,
- WriteTransaction tx) {
+ TypedWriteTransaction<Configuration> tx) {
if (elanInterface.augmentation(EtreeInterface.class).getEtreeInterfaceType() == EtreeInterfaceType.Root) {
bindElanService(elanInfo.getElanTag(), elanInfo.getElanInstanceName(), elanInterface.getName(),
lportTag, tx);
return elanInterface.augmentation(EtreeInterface.class) == null;
}
- protected void unbindService(String interfaceName, ReadWriteTransaction tx) throws ReadFailedException {
+ protected void unbindService(String interfaceName, TypedReadWriteTransaction<Configuration> tx)
+ throws ExecutionException, InterruptedException {
short elanServiceIndex = ServiceIndex.getIndex(NwConstants.ELAN_SERVICE_NAME, NwConstants.ELAN_SERVICE_INDEX);
InstanceIdentifier<BoundServices> bindServiceId = ElanUtils.buildServiceId(interfaceName, elanServiceIndex);
- if (tx.read(LogicalDatastoreType.CONFIGURATION, bindServiceId).checkedGet().isPresent()) {
- tx.delete(LogicalDatastoreType.CONFIGURATION, bindServiceId);
+ if (tx.read(bindServiceId).get().isPresent()) {
+ tx.delete(bindServiceId);
}
}
}
private DpnInterfaces updateElanDpnInterfacesList(String elanInstanceName, BigInteger dpId,
- List<String> interfaceNames, WriteTransaction tx) {
+ List<String> interfaceNames, TypedWriteTransaction<Operational> tx) {
DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId).setInterfaces(interfaceNames)
.withKey(new DpnInterfacesKey(dpId)).build();
- tx.put(LogicalDatastoreType.OPERATIONAL,
- ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId), dpnInterface,
- WriteTransaction.CREATE_MISSING_PARENTS);
+ tx.put(ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId), dpnInterface,
+ CREATE_MISSING_PARENTS);
return dpnInterface;
}
* @param dpId
* the dp id
*/
- private void deleteElanDpnInterface(String elanInstanceName, BigInteger dpId, WriteTransaction tx) {
+ private void deleteElanDpnInterface(String elanInstanceName, BigInteger dpId,
+ TypedReadWriteTransaction<Operational> tx) throws ExecutionException, InterruptedException {
InstanceIdentifier<DpnInterfaces> dpnInterfacesId = ElanUtils
.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId);
- Optional<DpnInterfaces> dpnInterfaces = ElanUtils.read(broker,
- LogicalDatastoreType.OPERATIONAL, dpnInterfacesId);
+ Optional<DpnInterfaces> dpnInterfaces = tx.read(dpnInterfacesId).get();
if (dpnInterfaces.isPresent()) {
- tx.delete(LogicalDatastoreType.OPERATIONAL, dpnInterfacesId);
+ tx.delete(dpnInterfacesId);
}
}
private DpnInterfaces createElanInterfacesList(String elanInstanceName, String interfaceName, BigInteger dpId,
- WriteTransaction tx) {
+ TypedWriteTransaction<Operational> tx) {
List<String> interfaceNames = new ArrayList<>();
interfaceNames.add(interfaceName);
DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId).setInterfaces(interfaceNames)
.withKey(new DpnInterfacesKey(dpId)).build();
- tx.put(LogicalDatastoreType.OPERATIONAL,
- ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId), dpnInterface,
- WriteTransaction.CREATE_MISSING_PARENTS);
+ tx.put(ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId), dpnInterface,
+ CREATE_MISSING_PARENTS);
return dpnInterface;
}
- private void createElanInterfaceTablesList(String interfaceName, WriteTransaction tx) {
+ private void createElanInterfaceTablesList(String interfaceName, TypedReadWriteTransaction<Operational> tx)
+ throws ExecutionException, InterruptedException {
InstanceIdentifier<ElanInterfaceMac> elanInterfaceMacTables = ElanUtils
.getElanInterfaceMacEntriesOperationalDataPath(interfaceName);
- Optional<ElanInterfaceMac> interfaceMacTables = ElanUtils.read(broker,
- LogicalDatastoreType.OPERATIONAL, elanInterfaceMacTables);
+ Optional<ElanInterfaceMac> interfaceMacTables = tx.read(elanInterfaceMacTables).get();
// Adding new Elan Interface Port to the operational DataStore without
// Static-Mac Entries..
if (!interfaceMacTables.isPresent()) {
ElanInterfaceMac elanInterfaceMacTable = new ElanInterfaceMacBuilder().setElanInterface(interfaceName)
.withKey(new ElanInterfaceMacKey(interfaceName)).build();
- tx.put(LogicalDatastoreType.OPERATIONAL,
- ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName), elanInterfaceMacTable,
- WriteTransaction.CREATE_MISSING_PARENTS);
+ tx.put(ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName), elanInterfaceMacTable,
+ CREATE_MISSING_PARENTS);
}
}
- private void createElanStateList(String elanInstanceName, String interfaceName, WriteTransaction tx) {
+ private void createElanStateList(String elanInstanceName, String interfaceName,
+ TypedReadWriteTransaction<Operational> tx) throws ExecutionException, InterruptedException {
InstanceIdentifier<Elan> elanInstance = ElanUtils.getElanInstanceOperationalDataPath(elanInstanceName);
- Optional<Elan> elanInterfaceLists = ElanUtils.read(broker,
- LogicalDatastoreType.OPERATIONAL, elanInstance);
+ Optional<Elan> elanInterfaceLists = tx.read(elanInstance).get();
// Adding new Elan Interface Port to the operational DataStore without
// Static-Mac Entries..
if (elanInterfaceLists.isPresent()) {
interfaceLists.add(interfaceName);
Elan elanState = new ElanBuilder().setName(elanInstanceName).setElanInterfaces(interfaceLists)
.withKey(new ElanKey(elanInstanceName)).build();
- tx.put(LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanInstanceName),
- elanState, WriteTransaction.CREATE_MISSING_PARENTS);
+ tx.put(ElanUtils.getElanInstanceOperationalDataPath(elanInstanceName), elanState, CREATE_MISSING_PARENTS);
}
}
import org.opendaylight.genius.infra.Datastore.Operational;
import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
-import org.opendaylight.genius.infra.TransactionAdapter;
import org.opendaylight.genius.infra.TypedReadWriteTransaction;
import org.opendaylight.genius.infra.TypedWriteTransaction;
import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo;
interfaceTx.put(elanMacEntryId, macEntry);
ElanInstance elanInstance = elanInstanceCache.get(elanName).orNull();
elanUtils.setupMacFlows(elanInstance, interfaceManager.getInterfaceInfo(interfaceName), macTimeOut,
- macAddress, true, TransactionAdapter.toWriteTransaction(flowTx));
+ macAddress, true, flowTx);
}
}
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
-import org.opendaylight.genius.infra.TransactionAdapter;
import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo;
import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
import org.opendaylight.genius.mdsalutil.MetaDataUtil;
futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL, operTx -> {
elanUtils.setupMacFlows(elanInstance, interfaceInfo, elanInstance.getMacTimeout(),
- macAddress, !isVlanOrFlatProviderIface, TransactionAdapter.toWriteTransaction(tx));
+ macAddress, !isVlanOrFlatProviderIface, tx);
InstanceIdentifier<MacEntry> macEntryId =
ElanUtils.getInterfaceMacEntriesIdentifierOperationalDataPath(interfaceName, physAddress);
operTx.put(macEntryId, newMacEntry, WriteTransaction.CREATE_MISSING_PARENTS);
*/
package org.opendaylight.netvirt.elan.l2gw.ha;
-import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.CONFIGURATION;
+import static org.opendaylight.controller.md.sal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.OPERATIONAL;
import com.google.common.base.Optional;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
+import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.genius.infra.Datastore;
+import org.opendaylight.genius.infra.Datastore.Configuration;
+import org.opendaylight.genius.infra.Datastore.Operational;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
+import org.opendaylight.genius.infra.TypedWriteTransaction;
import org.opendaylight.genius.utils.hwvtep.HwvtepNodeHACache;
import org.opendaylight.netvirt.elan.l2gw.ha.commands.SwitchesCmd;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
return otherConfigsBuilder;
}
- public static Node readNode(ReadWriteTransaction tx, LogicalDatastoreType storeType,
- InstanceIdentifier<Node> nodeId)
- throws ReadFailedException {
- Optional<Node> optional = tx.read(storeType, nodeId).checkedGet();
- if (optional.isPresent()) {
- return optional.get();
- }
- return null;
- }
-
public static String convertToGlobalNodeId(String psNodeId) {
int idx = psNodeId.indexOf(PHYSICALSWITCH);
if (idx > 0) {
}
public static boolean isEmpty(Collection collection) {
- if (collection == null || collection.isEmpty()) {
- return true;
- }
- return false;
+ return collection == null || collection.isEmpty();
}
public static Node getOriginal(DataObjectModification<Node> mod) {
* @param haNodePath Ha node path
* @param haGlobalCfg HA global node object
*/
- public static void buildGlobalConfigForHANode(ReadWriteTransaction tx,
+ public static void buildGlobalConfigForHANode(TypedWriteTransaction<Configuration> tx,
Node childNode,
InstanceIdentifier<Node> haNodePath,
Optional<Node> haGlobalCfg) {
nodeBuilder.setNodeId(haNodePath.firstKeyOf(Node.class).getNodeId());
nodeBuilder.addAugmentation(HwvtepGlobalAugmentation.class, hwvtepGlobalBuilder.build());
Node configHANode = nodeBuilder.build();
- tx.merge(CONFIGURATION, haNodePath, configHANode,Boolean.TRUE);
+ tx.merge(haNodePath, configHANode, CREATE_MISSING_PARENTS);
}
- public static void deleteNodeIfPresent(ReadWriteTransaction tx,
- LogicalDatastoreType logicalDatastoreType,
- InstanceIdentifier<?> iid) throws ReadFailedException {
- if (tx.read(logicalDatastoreType, iid).checkedGet().isPresent()) {
+ public static <D extends Datastore> void deleteNodeIfPresent(TypedReadWriteTransaction<D> tx,
+ InstanceIdentifier<?> iid) throws ExecutionException, InterruptedException {
+ if (tx.read(iid).get().isPresent()) {
LOG.info("Deleting child node {}", getNodeIdVal(iid));
- tx.delete(logicalDatastoreType, iid);
+ tx.delete(iid);
}
}
* @param key Node object
* @param haNode Ha Node from which to be deleted
* @param tx Transaction
- * @throws ReadFailedException Exception thrown if read fails
*/
- public static void deletePSNodesOfNode(InstanceIdentifier<Node> key,
- Node haNode,
- ReadWriteTransaction tx)
- throws ReadFailedException {
+ public static void deletePSNodesOfNode(InstanceIdentifier<Node> key, Node haNode,
+ TypedReadWriteTransaction<Configuration> tx) throws ExecutionException, InterruptedException {
//read from switches attribute and clean up them
HwvtepGlobalAugmentation globalAugmentation = haNode.augmentation(HwvtepGlobalAugmentation.class);
if (globalAugmentation == null) {
if (switches != null) {
for (Switches switche : switches) {
InstanceIdentifier<Node> psId = (InstanceIdentifier<Node>)switche.getSwitchRef().getValue();
- deleteNodeIfPresent(tx, CONFIGURATION, psId);
+ deleteNodeIfPresent(tx, psId);
deleted.put(psId, Boolean.TRUE);
}
}
//also read from managed by attribute of switches and cleanup them as a back up if the above cleanup fails
- Optional<Topology> topologyOptional = tx
- .read(CONFIGURATION, key.firstIdentifierOf(Topology.class)).checkedGet();
+ Optional<Topology> topologyOptional = tx .read(key.firstIdentifierOf(Topology.class)).get();
String deletedNodeId = key.firstKeyOf(Node.class).getNodeId().getValue();
if (topologyOptional.isPresent()) {
Topology topology = topologyOptional.get();
InstanceIdentifier<Node> psNodeId =
convertToInstanceIdentifier(psNode.getNodeId().getValue());
if (deleted.containsKey(psNodeId)) {
- deleteNodeIfPresent(tx, CONFIGURATION, psNodeId);
+ deleteNodeIfPresent(tx, psNodeId);
}
}
}
*
* @param haPath HA node path from whih switches will be deleted
* @param tx Transaction object
- * @throws ReadFailedException Exception thrown if read fails
*/
public static void deleteSwitchesManagedByNode(InstanceIdentifier<Node> haPath,
- ReadWriteTransaction tx)
- throws ReadFailedException {
+ TypedReadWriteTransaction<Operational> tx) throws ExecutionException, InterruptedException {
- Optional<Node> nodeOptional = tx.read(OPERATIONAL, haPath).checkedGet();
+ Optional<Node> nodeOptional = tx.read(haPath).get();
if (!nodeOptional.isPresent()) {
return;
}
if (switches != null) {
for (Switches switche : switches) {
InstanceIdentifier<Node> id = (InstanceIdentifier<Node>)switche.getSwitchRef().getValue();
- deleteNodeIfPresent(tx, OPERATIONAL, id);
+ deleteNodeIfPresent(tx, id);
}
}
}
package org.opendaylight.netvirt.elan.l2gw.ha.handlers;
import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.genius.infra.Datastore.Configuration;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
import org.opendaylight.netvirt.elan.l2gw.ha.merge.GlobalAugmentationMerger;
import org.opendaylight.netvirt.elan.l2gw.ha.merge.GlobalNodeMerger;
import org.opendaylight.netvirt.elan.l2gw.ha.merge.PSAugmentationMerger;
*/
public void copyHAGlobalUpdateToChild(InstanceIdentifier<Node> haChildNodeId,
DataObjectModification<Node> mod,
- ReadWriteTransaction tx) {
+ TypedReadWriteTransaction<Configuration> tx) {
globalAugmentationMerger.mergeConfigUpdate(haChildNodeId,
mod.getModifiedAugmentation(HwvtepGlobalAugmentation.class), tx);
globalNodeMerger.mergeConfigUpdate(haChildNodeId, mod, tx);
*/
public void copyHAPSUpdateToChild(InstanceIdentifier<Node> haChildNodeId,
DataObjectModification<Node> mod,
- ReadWriteTransaction tx) {
+ TypedReadWriteTransaction<Configuration> tx) {
psAugmentationMerger.mergeConfigUpdate(haChildNodeId,
mod.getModifiedAugmentation(PhysicalSwitchAugmentation.class), tx);
package org.opendaylight.netvirt.elan.l2gw.ha.handlers;
import com.google.common.base.Optional;
+import java.util.concurrent.ExecutionException;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.genius.infra.Datastore.Configuration;
+import org.opendaylight.genius.infra.Datastore.Operational;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
import org.opendaylight.genius.utils.hwvtep.HwvtepNodeHACache;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
public void handleChildNodeConnected(Node connectedNode,
InstanceIdentifier<Node> connectedNodePath,
InstanceIdentifier<Node> haNodePath,
- ReadWriteTransaction tx)
- throws ReadFailedException {
+ TypedReadWriteTransaction<Configuration> confTx,
+ TypedReadWriteTransaction<Operational> operTx)
+ throws ReadFailedException, ExecutionException, InterruptedException {
if (haNodePath == null) {
return;
}
nodeConnectedHandler.handleNodeConnected(connectedNode, connectedNodePath, haNodePath,
- Optional.absent(), Optional.absent(), tx);
+ Optional.absent(), Optional.absent(), confTx, operTx);
}
@Override
InstanceIdentifier<Node> haNodePath,
Optional<Node> haGlobalCfg,
Optional<Node> haPSCfg,
- ReadWriteTransaction tx)
- throws ReadFailedException {
+ TypedReadWriteTransaction<Configuration> confTx,
+ TypedReadWriteTransaction<Operational> operTx)
+ throws ReadFailedException, ExecutionException, InterruptedException {
if (haNodePath == null) {
return;
}
nodeConnectedHandler.handleNodeConnected(connectedNode, connectedNodePath, haNodePath,
- haGlobalCfg, haPSCfg, tx);
+ haGlobalCfg, haPSCfg, confTx, operTx);
}
@Override
public void copyChildGlobalOpUpdateToHAParent(InstanceIdentifier<Node> haPath,
DataObjectModification<Node> mod,
- ReadWriteTransaction tx) {
+ TypedReadWriteTransaction<Operational> tx) {
if (haPath == null) {
return;
}
public void copyChildPsOpUpdateToHAParent(Node updatedSrcPSNode,
InstanceIdentifier<Node> haPath,
DataObjectModification<Node> mod,
- ReadWriteTransaction tx) {
+ TypedReadWriteTransaction<Operational> tx) {
if (haPath == null) {
return;
}
@Override
public void copyHAPSUpdateToChild(InstanceIdentifier<Node> haChildNodeId,
DataObjectModification<Node> mod,
- ReadWriteTransaction tx) {
+ TypedReadWriteTransaction<Configuration> tx) {
if (haChildNodeId == null) {
return;
}
@Override
public void copyHAGlobalUpdateToChild(InstanceIdentifier<Node> haChildNodeId,
DataObjectModification<Node> mod,
- ReadWriteTransaction tx) {
+ TypedReadWriteTransaction<Configuration> tx) {
if (haChildNodeId == null) {
return;
}
import com.google.common.base.Optional;
+import java.util.concurrent.ExecutionException;
import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.genius.infra.Datastore.Configuration;
+import org.opendaylight.genius.infra.Datastore.Operational;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
void handleChildNodeConnected(Node connectedNode,
InstanceIdentifier<Node> connectedNodePath,
InstanceIdentifier<Node> haNodePath,
- ReadWriteTransaction tx)
- throws ReadFailedException;
+ TypedReadWriteTransaction<Configuration> confTx,
+ TypedReadWriteTransaction<Operational> operTx)
+ throws ReadFailedException, ExecutionException, InterruptedException;
void handleChildNodeReConnected(Node connectedNode,
InstanceIdentifier<Node> connectedNodePath,
InstanceIdentifier<Node> haNodePath,
Optional<Node> haGlobalCfg,
Optional<Node> haPSCfg,
- ReadWriteTransaction tx)
- throws ReadFailedException;
+ TypedReadWriteTransaction<Configuration> confTx,
+ TypedReadWriteTransaction<Operational> operTx)
+ throws ReadFailedException, ExecutionException, InterruptedException;
void copyChildGlobalOpUpdateToHAParent(InstanceIdentifier<Node> haPath,
DataObjectModification<Node> mod,
- ReadWriteTransaction tx);
+ TypedReadWriteTransaction<Operational> tx);
void copyChildPsOpUpdateToHAParent(Node updatedSrcPSNode,
InstanceIdentifier<Node> haPath,
DataObjectModification<Node> mod,
- ReadWriteTransaction tx);
+ TypedReadWriteTransaction<Operational> tx);
void copyHAPSUpdateToChild(InstanceIdentifier<Node> haChildPath,
DataObjectModification<Node> mod,
- ReadWriteTransaction tx)
+ TypedReadWriteTransaction<Configuration> tx)
;
void copyHAGlobalUpdateToChild(InstanceIdentifier<Node> haChildPath,
DataObjectModification<Node> mod,
- ReadWriteTransaction tx)
+ TypedReadWriteTransaction<Configuration> tx)
;
}
package org.opendaylight.netvirt.elan.l2gw.ha.handlers;
import com.google.common.base.Optional;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import java.util.concurrent.ExecutionException;
+import org.opendaylight.genius.infra.Datastore;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
public interface INodeCopier {
- void copyGlobalNode(Optional<Node> globalNodeOptional,
+ <D extends Datastore> void copyGlobalNode(Optional<Node> globalNodeOptional,
InstanceIdentifier<Node> srcPath,
InstanceIdentifier<Node> dstPath,
- LogicalDatastoreType logicalDatastoreType,
- ReadWriteTransaction tx) throws ReadFailedException;
+ Class<D> datastoreType,
+ TypedReadWriteTransaction<D> tx)
+ throws ExecutionException, InterruptedException;
- void copyPSNode(Optional<Node> psNodeOptional,
+ <D extends Datastore> void copyPSNode(Optional<Node> psNodeOptional,
InstanceIdentifier<Node> srcPsPath,
InstanceIdentifier<Node> dstPsPath,
InstanceIdentifier<Node> dstGlobalPath,
- LogicalDatastoreType logicalDatastoreType,
- ReadWriteTransaction tx) throws ReadFailedException;
+ Class<D> datastoreType,
+ TypedReadWriteTransaction<D> tx)
+ throws ExecutionException, InterruptedException;
}
*/
package org.opendaylight.netvirt.elan.l2gw.ha.handlers;
-import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.CONFIGURATION;
-import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.OPERATIONAL;
+import static org.opendaylight.controller.md.sal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
import com.google.common.base.Optional;
import java.util.List;
+import java.util.concurrent.ExecutionException;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-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.ReadFailedException;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.genius.infra.Datastore.Configuration;
+import org.opendaylight.genius.infra.Datastore.Operational;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
import org.opendaylight.genius.utils.hwvtep.HwvtepNodeHACache;
+import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
import org.opendaylight.netvirt.elan.l2gw.ha.HwvtepHAUtil;
import org.opendaylight.netvirt.elan.l2gw.ha.listeners.HAJobScheduler;
import org.opendaylight.netvirt.elan.l2gw.ha.merge.GlobalAugmentationMerger;
private final PSAugmentationMerger psAugmentationMerger = PSAugmentationMerger.getInstance();
private final GlobalNodeMerger globalNodeMerger = GlobalNodeMerger.getInstance();
private final PSNodeMerger psNodeMerger = PSNodeMerger.getInstance();
- private final DataBroker db;
+ private final ManagedNewTransactionRunner txRunner;
private final HwvtepNodeHACache hwvtepNodeHACache;
public NodeConnectedHandler(final DataBroker db, final HwvtepNodeHACache hwvtepNodeHACache) {
- this.db = db;
+ this.txRunner = new ManagedNewTransactionRunnerImpl(db);
this.hwvtepNodeHACache = hwvtepNodeHACache;
}
* @param haNodePath Ha Iid
* @param haGlobalCfg Ha Global Config Node
* @param haPSCfg Ha Physical Config Node
- * @param tx Transaction
- * @throws ReadFailedException Exception thrown if read fails
+ * @param operTx Transaction
*/
- @SuppressWarnings("checkstyle:ForbidCertainMethod")
public void handleNodeConnected(Node childNode,
InstanceIdentifier<Node> childNodePath,
InstanceIdentifier<Node> haNodePath,
Optional<Node> haGlobalCfg,
Optional<Node> haPSCfg,
- ReadWriteTransaction tx)
- throws ReadFailedException {
- HwvtepHAUtil.buildGlobalConfigForHANode(tx, childNode, haNodePath, haGlobalCfg);
- copyChildOpToHA(childNode, haNodePath, tx);
- readAndCopyChildPSOpToHAPS(childNode, haNodePath, tx);
+ TypedReadWriteTransaction<Configuration> confTx,
+ TypedReadWriteTransaction<Operational> operTx)
+ throws ExecutionException, InterruptedException {
+ HwvtepHAUtil.buildGlobalConfigForHANode(confTx, childNode, haNodePath, haGlobalCfg);
+ copyChildOpToHA(childNode, haNodePath, operTx);
+ readAndCopyChildPSOpToHAPS(childNode, haNodePath, operTx);
if (haGlobalCfg.isPresent()) {
//copy ha config to newly connected child case of reconnected child
if (haPSCfg.isPresent()) {
(created in the device)
*/
HAJobScheduler.getInstance().submitJob(() -> {
- try {
- hwvtepNodeHACache.updateConnectedNodeStatus(childNodePath);
- LOG.info("HA child reconnected handleNodeReConnected {}",
+ ListenableFutures.addErrorLogging(
+ txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, jobTx -> {
+ hwvtepNodeHACache.updateConnectedNodeStatus(childNodePath);
+ LOG.info("HA child reconnected handleNodeReConnected {}",
childNode.getNodeId().getValue());
- ReadWriteTransaction tx1 = db.newReadWriteTransaction();
- copyHAPSConfigToChildPS(haPSCfg.get(), childNodePath, tx1);
- tx1.submit().checkedGet();
- } catch (TransactionCommitFailedException e) {
- LOG.error("Failed to process ", e);
- }
+ copyHAPSConfigToChildPS(haPSCfg.get(), childNodePath, jobTx);
+ }), LOG, "Failed to process");
});
}
- copyHANodeConfigToChild(haGlobalCfg.get(), childNodePath, tx);
+ copyHANodeConfigToChild(haGlobalCfg.get(), childNodePath, confTx);
}
- deleteChildPSConfigIfHAPSConfigIsMissing(haGlobalCfg, childNode, tx);
+ deleteChildPSConfigIfHAPSConfigIsMissing(haGlobalCfg, childNode, confTx);
}
private void deleteChildPSConfigIfHAPSConfigIsMissing(Optional<Node> haPSCfg,
Node childNode,
- ReadWriteTransaction tx) throws ReadFailedException {
+ TypedReadWriteTransaction<Configuration> tx)
+ throws ExecutionException, InterruptedException {
if (haPSCfg.isPresent()) {
return;
}
List<Switches> switches = augmentation.getSwitches();
if (switches != null) {
for (Switches ps : switches) {
- HwvtepHAUtil.deleteNodeIfPresent(tx, CONFIGURATION, ps.getSwitchRef().getValue());
+ HwvtepHAUtil.deleteNodeIfPresent(tx, ps.getSwitchRef().getValue());
}
}
} else {
* @param childGlobalNode Ha Global Child node
* @param haNodePath Ha node path
* @param tx Transaction
- * @throws ReadFailedException Exception thrown if read fails
*/
void readAndCopyChildPSOpToHAPS(Node childGlobalNode,
InstanceIdentifier<Node> haNodePath,
- ReadWriteTransaction tx)
- throws ReadFailedException {
+ TypedReadWriteTransaction<Operational> tx)
+ throws ExecutionException, InterruptedException {
if (childGlobalNode == null || childGlobalNode.augmentation(HwvtepGlobalAugmentation.class) == null) {
return;
return;
}
for (Switches ps : switches) {
- Node childPsNode = HwvtepHAUtil.readNode(tx, OPERATIONAL,
- (InstanceIdentifier<Node>) ps.getSwitchRef().getValue());
+ Node childPsNode = tx.read((InstanceIdentifier<Node>) ps.getSwitchRef().getValue()).get().orNull();
if (childPsNode != null) {
InstanceIdentifier<Node> haPsPath = HwvtepHAUtil.convertPsPath(childPsNode, haNodePath);
copyChildPSOpToHAPS(childPsNode, haNodePath, haPsPath, tx);
*/
private void copyHANodeConfigToChild(Node srcNode,
InstanceIdentifier<Node> childPath,
- ReadWriteTransaction tx) {
+ TypedReadWriteTransaction<Configuration> tx) {
if (srcNode == null) {
return;
}
globalNodeMerger.mergeConfigData(nodeBuilder, srcNode, childPath);
nodeBuilder.addAugmentation(HwvtepGlobalAugmentation.class, dstBuilder.build());
Node dstNode = nodeBuilder.build();
- tx.put(CONFIGURATION, childPath, dstNode, WriteTransaction.CREATE_MISSING_PARENTS);
+ tx.put(childPath, dstNode, CREATE_MISSING_PARENTS);
}
/**
* @param childNode HA Child Node
* @param haNodePath HA node path
* @param tx Transaction
- * @throws ReadFailedException Exception thrown if read fails
*/
private void copyChildOpToHA(Node childNode,
InstanceIdentifier<Node> haNodePath,
- ReadWriteTransaction tx)
- throws ReadFailedException {
+ TypedReadWriteTransaction<Operational> tx)
+ throws ExecutionException, InterruptedException {
if (childNode == null) {
return;
}
NodeBuilder haNodeBuilder = HwvtepHAUtil.getNodeBuilderForPath(haNodePath);
HwvtepGlobalAugmentationBuilder haBuilder = new HwvtepGlobalAugmentationBuilder();
- Optional<Node> existingHANodeOptional = tx.read(OPERATIONAL, haNodePath).checkedGet();
+ Optional<Node> existingHANodeOptional = tx.read(haNodePath).get();
Node existingHANode = existingHANodeOptional.isPresent() ? existingHANodeOptional.get() : null;
HwvtepGlobalAugmentation existingHAData = HwvtepHAUtil.getGlobalAugmentationOfNode(existingHANode);
haBuilder.setDbVersion(childData.getDbVersion());
haNodeBuilder.addAugmentation(HwvtepGlobalAugmentation.class, haBuilder.build());
Node haNode = haNodeBuilder.build();
- tx.merge(OPERATIONAL, haNodePath, haNode, true);
+ tx.merge(haNodePath, haNode, CREATE_MISSING_PARENTS);
}
/**
*/
public void copyHAPSConfigToChildPS(Node haPsNode,
InstanceIdentifier<Node> childPath,
- ReadWriteTransaction tx) {
+ TypedReadWriteTransaction<Configuration> tx) {
InstanceIdentifier<Node> childPsPath = HwvtepHAUtil.convertPsPath(haPsNode, childPath);
NodeBuilder childPsBuilder = HwvtepHAUtil.getNodeBuilderForPath(childPsPath);
childPsBuilder.addAugmentation(PhysicalSwitchAugmentation.class, dstBuilder.build());
Node childPSNode = childPsBuilder.build();
- tx.put(CONFIGURATION, childPsPath, childPSNode, WriteTransaction.CREATE_MISSING_PARENTS);
+ tx.put(childPsPath, childPSNode, CREATE_MISSING_PARENTS);
}
/**
* @param haPath HA node path
* @param haPspath Ha Physical Switch Node path
* @param tx Transaction
- * @throws ReadFailedException Exception thrown if read fails
*/
public void copyChildPSOpToHAPS(Node childPsNode,
InstanceIdentifier<Node> haPath,
InstanceIdentifier<Node> haPspath,
- ReadWriteTransaction tx)
- throws ReadFailedException {
+ TypedReadWriteTransaction<Operational> tx)
+ throws ExecutionException, InterruptedException {
NodeBuilder haPSNodeBuilder = HwvtepHAUtil.getNodeBuilderForPath(haPspath);
PhysicalSwitchAugmentationBuilder dstBuilder = new PhysicalSwitchAugmentationBuilder();
PhysicalSwitchAugmentation src = childPsNode.augmentation(PhysicalSwitchAugmentation.class);
- Node existingHAPSNode = HwvtepHAUtil.readNode(tx, OPERATIONAL, haPspath);
+ Node existingHAPSNode = tx.read(haPspath).get().orNull();
PhysicalSwitchAugmentation existingHAPSAugumentation =
HwvtepHAUtil.getPhysicalSwitchAugmentationOfNode(existingHAPSNode);
haPSNodeBuilder.addAugmentation(PhysicalSwitchAugmentation.class, dstBuilder.build());
Node haPsNode = haPSNodeBuilder.build();
- tx.merge(OPERATIONAL, haPspath, haPsNode, true);
+ tx.merge(haPspath, haPsNode, CREATE_MISSING_PARENTS);
}
}
*/
package org.opendaylight.netvirt.elan.l2gw.ha.handlers;
-import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.CONFIGURATION;
-import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.OPERATIONAL;
+import static org.opendaylight.controller.md.sal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
import com.google.common.base.Optional;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.MoreExecutors;
+import java.util.concurrent.ExecutionException;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
-import org.opendaylight.netvirt.elan.l2gw.ha.BatchedTransaction;
+import org.opendaylight.genius.infra.Datastore;
+import org.opendaylight.genius.infra.Datastore.Configuration;
+import org.opendaylight.genius.infra.Datastore.Operational;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
+import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
import org.opendaylight.netvirt.elan.l2gw.ha.HwvtepHAUtil;
import org.opendaylight.netvirt.elan.l2gw.ha.listeners.HAJobScheduler;
import org.opendaylight.netvirt.elan.l2gw.ha.merge.GlobalAugmentationMerger;
private final PSAugmentationMerger psAugmentationMerger = PSAugmentationMerger.getInstance();
private final GlobalNodeMerger globalNodeMerger = GlobalNodeMerger.getInstance();
private final PSNodeMerger psNodeMerger = PSNodeMerger.getInstance();
- private final DataBroker db;
+ private final ManagedNewTransactionRunner txRunner;
@Inject
public NodeCopier(DataBroker db) {
- this.db = db;
+ this.txRunner = new ManagedNewTransactionRunnerImpl(db);
}
@Override
- public void copyGlobalNode(Optional<Node> srcGlobalNodeOptional,
+ public <D extends Datastore> void copyGlobalNode(Optional<Node> srcGlobalNodeOptional,
InstanceIdentifier<Node> srcPath,
InstanceIdentifier<Node> dstPath,
- LogicalDatastoreType logicalDatastoreType,
- ReadWriteTransaction tx) throws ReadFailedException {
- if (!srcGlobalNodeOptional.isPresent() && logicalDatastoreType == CONFIGURATION) {
- Futures.addCallback(tx.read(logicalDatastoreType, srcPath), new FutureCallback<Optional<Node>>() {
+ Class<D> datastoreType,
+ TypedReadWriteTransaction<D> tx)
+ throws ExecutionException, InterruptedException {
+ if (!srcGlobalNodeOptional.isPresent() && Configuration.class.equals(datastoreType)) {
+ Futures.addCallback(tx.read(srcPath), new FutureCallback<Optional<Node>>() {
@Override
public void onSuccess(Optional<Node> nodeOptional) {
- HAJobScheduler.getInstance().submitJob(() -> {
- try {
- ReadWriteTransaction tx1 = new BatchedTransaction();
+ HAJobScheduler.getInstance().submitJob(() -> ListenableFutures.addErrorLogging(
+ txRunner.callWithNewReadWriteTransactionAndSubmit(datastoreType, tx -> {
if (nodeOptional.isPresent()) {
- copyGlobalNode(nodeOptional, srcPath, dstPath, logicalDatastoreType, tx1);
+ copyGlobalNode(nodeOptional, srcPath, dstPath, datastoreType, tx);
} else {
- /**
+ /*
* In case the Parent HA Global Node is not present and Child HA node is present
- * It means that both the child are disconnected/removed hence the parent is deleted.
+ * It means that both the child are disconnected/removed hence the parent is
+ * deleted.
* @see org.opendaylight.netvirt.elan.l2gw.ha.listeners.HAOpNodeListener
* OnGLobalNode() delete function
* So we should delete the existing config child node as cleanup
*/
- HwvtepHAUtil.deleteNodeIfPresent(tx1, logicalDatastoreType, dstPath);
+ HwvtepHAUtil.deleteNodeIfPresent(tx, dstPath);
}
- } catch (ReadFailedException e) {
- LOG.error("Failed to read source node {}",srcPath);
- }
- });
+ }), LOG, "Failed to read source node {}", srcPath));
}
@Override
public void onFailure(Throwable throwable) {
}
- });
+ }, MoreExecutors.directExecutor());
return;
}
HwvtepGlobalAugmentation srcGlobalAugmentation =
srcGlobalNodeOptional.get().augmentation(HwvtepGlobalAugmentation.class);
if (srcGlobalAugmentation == null) {
- /**
+ /*
* If Source HA Global Node is not present
* It means that both the child are disconnected/removed hence the parent is deleted.
* @see org.opendaylight.netvirt.elan.l2gw.ha.listeners.HAOpNodeListener OnGLobalNode() delete function
* So we should delete the existing config child node as cleanup
*/
- HwvtepHAUtil.deleteNodeIfPresent(tx, logicalDatastoreType, dstPath);
+ HwvtepHAUtil.deleteNodeIfPresent(tx, dstPath);
return;
}
NodeBuilder haNodeBuilder = HwvtepHAUtil.getNodeBuilderForPath(dstPath);
HwvtepGlobalAugmentationBuilder haBuilder = new HwvtepGlobalAugmentationBuilder();
- Optional<Node> existingDstGlobalNodeOptional = tx.read(logicalDatastoreType, dstPath).checkedGet();
+ Optional<Node> existingDstGlobalNodeOptional = tx.read(dstPath).get();
Node existingDstGlobalNode =
existingDstGlobalNodeOptional.isPresent() ? existingDstGlobalNodeOptional.get() : null;
HwvtepGlobalAugmentation existingHAGlobalData = HwvtepHAUtil.getGlobalAugmentationOfNode(existingDstGlobalNode);
existingDstGlobalNode, srcGlobalNodeOptional.get(), dstPath);
- if (OPERATIONAL == logicalDatastoreType) {
+ if (Operational.class.equals(datastoreType)) {
haBuilder.setManagers(HwvtepHAUtil.buildManagersForHANode(srcGlobalNodeOptional.get(),
existingDstGlobalNodeOptional));
//Also update the manager section in config which helps in cluster reboot scenarios
- haBuilder.getManagers().forEach((manager) -> {
- InstanceIdentifier<Managers> managerIid = dstPath.augmentation(HwvtepGlobalAugmentation.class)
- .child(Managers.class, manager.key());
- tx.put(CONFIGURATION, managerIid, manager, true);
- });
+ ListenableFutures.addErrorLogging(
+ txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
+ confTx -> haBuilder.getManagers().forEach(manager -> {
+ InstanceIdentifier<Managers> managerIid =
+ dstPath.augmentation(HwvtepGlobalAugmentation.class).child(Managers.class, manager.key());
+ confTx.put(managerIid, manager, CREATE_MISSING_PARENTS);
+ })), LOG, "Error updating the manager section in config");
}
haBuilder.setDbVersion(srcGlobalAugmentation.getDbVersion());
haNodeBuilder.addAugmentation(HwvtepGlobalAugmentation.class, haBuilder.build());
Node haNode = haNodeBuilder.build();
- if (OPERATIONAL == logicalDatastoreType) {
- tx.merge(logicalDatastoreType, dstPath, haNode, true);
+ if (Operational.class.equals(datastoreType)) {
+ tx.merge(dstPath, haNode, CREATE_MISSING_PARENTS);
} else {
- tx.put(logicalDatastoreType, dstPath, haNode, true);
+ tx.put(dstPath, haNode, CREATE_MISSING_PARENTS);
}
}
@Override
- public void copyPSNode(Optional<Node> srcPsNodeOptional,
+ public <D extends Datastore> void copyPSNode(Optional<Node> srcPsNodeOptional,
InstanceIdentifier<Node> srcPsPath,
InstanceIdentifier<Node> dstPsPath,
InstanceIdentifier<Node> dstGlobalPath,
- LogicalDatastoreType logicalDatastoreType,
- ReadWriteTransaction tx) throws ReadFailedException {
- if (!srcPsNodeOptional.isPresent() && logicalDatastoreType == CONFIGURATION) {
- Futures.addCallback(tx.read(logicalDatastoreType, srcPsPath), new FutureCallback<Optional<Node>>() {
+ Class<D> datastoreType,
+ TypedReadWriteTransaction<D> tx)
+ throws ExecutionException, InterruptedException {
+ if (!srcPsNodeOptional.isPresent() && Configuration.class.equals(datastoreType)) {
+ Futures.addCallback(tx.read(srcPsPath), new FutureCallback<Optional<Node>>() {
@Override
public void onSuccess(Optional<Node> nodeOptional) {
HAJobScheduler.getInstance().submitJob(() -> {
- try {
- ReadWriteTransaction tx1 = new BatchedTransaction();
- if (nodeOptional.isPresent()) {
- copyPSNode(nodeOptional,
- srcPsPath, dstPsPath, dstGlobalPath, logicalDatastoreType, tx1);
- } else {
- /**
- * Deleting node please refer @see #copyGlobalNode for explanation
- */
- HwvtepHAUtil.deleteNodeIfPresent(tx1, logicalDatastoreType, dstPsPath);
- }
- } catch (ReadFailedException e) {
- LOG.error("Failed to read src node {}", srcPsNodeOptional.get());
- }
+ ListenableFutures.addErrorLogging(
+ txRunner.callWithNewReadWriteTransactionAndSubmit(datastoreType, tx -> {
+ if (nodeOptional.isPresent()) {
+ copyPSNode(nodeOptional,
+ srcPsPath, dstPsPath, dstGlobalPath, datastoreType, tx);
+ } else {
+ /*
+ * Deleting node please refer @see #copyGlobalNode for explanation
+ */
+ HwvtepHAUtil.deleteNodeIfPresent(tx, dstPsPath);
+ }
+ }), LOG, "Failed to read source node {}", srcPsNodeOptional.get());
});
}
PhysicalSwitchAugmentation srcPsAugmenatation =
srcPsNodeOptional.get().augmentation(PhysicalSwitchAugmentation.class);
- Node existingDstPsNode = HwvtepHAUtil.readNode(tx, logicalDatastoreType, dstPsPath);
+ Node existingDstPsNode = tx.read(dstPsPath).get().orNull();
PhysicalSwitchAugmentation existingDstPsAugmentation =
HwvtepHAUtil.getPhysicalSwitchAugmentationOfNode(existingDstPsNode);
- if (OPERATIONAL == logicalDatastoreType) {
+ if (Operational.class.equals(datastoreType)) {
psAugmentationMerger.mergeOperationalData(dstPsAugmentationBuilder, existingDstPsAugmentation,
srcPsAugmenatation, dstPsPath);
psNodeMerger.mergeOperationalData(dstPsNodeBuilder, existingDstPsNode, srcPsNodeOptional.get(), dstPsPath);
dstPsNodeBuilder.addAugmentation(PhysicalSwitchAugmentation.class, dstPsAugmentationBuilder.build());
Node dstPsNode = dstPsNodeBuilder.build();
- tx.merge(logicalDatastoreType, dstPsPath, dstPsNode, true);
- LOG.debug("Copied {} physical switch node from {} to {}", logicalDatastoreType, srcPsPath, dstPsPath);
+ tx.merge(dstPsPath, dstPsNode, CREATE_MISSING_PARENTS);
+ LOG.debug("Copied {} physical switch node from {} to {}", datastoreType, srcPsPath, dstPsPath);
}
public void mergeOpManagedByAttributes(PhysicalSwitchAugmentation psAugmentation,
package org.opendaylight.netvirt.elan.l2gw.ha.handlers;
import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.genius.infra.Datastore.Operational;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
import org.opendaylight.netvirt.elan.l2gw.ha.HwvtepHAUtil;
import org.opendaylight.netvirt.elan.l2gw.ha.merge.GlobalAugmentationMerger;
import org.opendaylight.netvirt.elan.l2gw.ha.merge.GlobalNodeMerger;
public void copyChildPsOpUpdateToHAParent(Node updatedSrcPSNode,
InstanceIdentifier<Node> haPath,
DataObjectModification<Node> mod,
- ReadWriteTransaction tx) {
+ TypedReadWriteTransaction<Operational> tx) {
InstanceIdentifier<Node> haPSPath = HwvtepHAUtil.convertPsPath(updatedSrcPSNode, haPath);
*/
public void copyChildGlobalOpUpdateToHAParent(InstanceIdentifier<Node> haPath,
DataObjectModification<Node> mod,
- ReadWriteTransaction tx) {
+ TypedReadWriteTransaction<Operational> tx) {
globalAugmentationMerger.mergeOpUpdate(haPath,
mod.getModifiedAugmentation(HwvtepGlobalAugmentation.class), tx);
*/
package org.opendaylight.netvirt.elan.l2gw.ha.listeners;
-import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.CONFIGURATION;
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
import com.google.common.base.Optional;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
+import java.util.concurrent.ExecutionException;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.genius.infra.Datastore.Configuration;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
import org.opendaylight.genius.utils.hwvtep.HwvtepNodeHACache;
import org.opendaylight.infrautils.metrics.MetricProvider;
import org.opendaylight.netvirt.elan.l2gw.ha.HwvtepHAUtil;
import org.slf4j.LoggerFactory;
@Singleton
-public class HAConfigNodeListener extends HwvtepNodeBaseListener {
+public class HAConfigNodeListener extends HwvtepNodeBaseListener<Configuration> {
private static final Logger LOG = LoggerFactory.getLogger(HAConfigNodeListener.class);
public HAConfigNodeListener(DataBroker db, HAEventHandler haEventHandler,
NodeCopier nodeCopier, HwvtepNodeHACache hwvtepNodeHACache,
MetricProvider metricProvider) throws Exception {
- super(LogicalDatastoreType.CONFIGURATION, db, hwvtepNodeHACache, metricProvider, true);
+ super(CONFIGURATION, db, hwvtepNodeHACache, metricProvider, true);
this.haEventHandler = haEventHandler;
this.nodeCopier = nodeCopier;
}
@Override
void onPsNodeAdd(InstanceIdentifier<Node> haPsPath,
Node haPSNode,
- ReadWriteTransaction tx) throws ReadFailedException {
+ TypedReadWriteTransaction<Configuration> tx)
+ throws ExecutionException, InterruptedException {
//copy the ps node data to children
String psId = haPSNode.getNodeId().getValue();
Set<InstanceIdentifier<Node>> childSwitchIds = getPSChildrenIdsForHAPSNode(psId);
HwvtepHAUtil.convertToGlobalNodeId(childPsPath.firstKeyOf(Node.class).getNodeId().getValue());
InstanceIdentifier<Node> childGlobalPath = HwvtepHAUtil.convertToInstanceIdentifier(nodeId);
nodeCopier.copyPSNode(Optional.fromNullable(haPSNode), haPsPath, childPsPath, childGlobalPath,
- LogicalDatastoreType.CONFIGURATION, tx);
+ CONFIGURATION, tx);
}
LOG.trace("Handle config ps node add {}", psId);
}
void onPsNodeUpdate(Node haPSUpdated,
Node haPSOriginal,
DataObjectModification<Node> mod,
- ReadWriteTransaction tx) {
+ TypedReadWriteTransaction<Configuration> tx) {
//copy the ps node data to children
String psId = haPSUpdated.getNodeId().getValue();
Set<InstanceIdentifier<Node>> childSwitchIds = getPSChildrenIdsForHAPSNode(psId);
Node haUpdated,
Node haOriginal,
DataObjectModification<Node> mod,
- ReadWriteTransaction tx) {
+ TypedReadWriteTransaction<Configuration> tx) {
Set<InstanceIdentifier<Node>> childNodeIds = getHwvtepNodeHACache().getChildrenForHANode(key);
for (InstanceIdentifier<Node> haChildNodeId : childNodeIds) {
haEventHandler.copyHAGlobalUpdateToChild(haChildNodeId, mod, tx);
@Override
void onPsNodeDelete(InstanceIdentifier<Node> key,
Node deletedPsNode,
- ReadWriteTransaction tx) throws ReadFailedException {
+ TypedReadWriteTransaction<Configuration> tx)
+ throws ExecutionException, InterruptedException {
//delete ps children nodes
String psId = deletedPsNode.getNodeId().getValue();
Set<InstanceIdentifier<Node>> childPsIds = getPSChildrenIdsForHAPSNode(psId);
for (InstanceIdentifier<Node> childPsId : childPsIds) {
- HwvtepHAUtil.deleteNodeIfPresent(tx, CONFIGURATION, childPsId);
+ HwvtepHAUtil.deleteNodeIfPresent(tx, childPsId);
}
}
@Override
void onGlobalNodeDelete(InstanceIdentifier<Node> key,
Node haNode,
- ReadWriteTransaction tx)
- throws ReadFailedException {
+ TypedReadWriteTransaction<Configuration> tx)
+ throws ExecutionException, InterruptedException {
//delete child nodes
Set<InstanceIdentifier<Node>> children = getHwvtepNodeHACache().getChildrenForHANode(key);
for (InstanceIdentifier<Node> childId : children) {
- HwvtepHAUtil.deleteNodeIfPresent(tx, CONFIGURATION, childId);
+ HwvtepHAUtil.deleteNodeIfPresent(tx, childId);
}
HwvtepHAUtil.deletePSNodesOfNode(key, haNode, tx);
}
*/
package org.opendaylight.netvirt.elan.l2gw.ha.listeners;
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+import static org.opendaylight.genius.infra.Datastore.OPERATIONAL;
+
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.genius.infra.Datastore;
import org.opendaylight.genius.utils.hwvtep.HwvtepNodeHACache;
import org.opendaylight.genius.utils.hwvtep.HwvtepSouthboundConstants;
import org.opendaylight.netvirt.elan.l2gw.ha.commands.LocalMcastCmd;
.child(Node.class).child(TerminationPoint.class);
private final DataBroker broker;
- private final List<HwvtepNodeDataListener<?>> listeners = new ArrayList<>();
+ private final List<HwvtepNodeDataListener<?, ?>> listeners = new ArrayList<>();
@Inject
public HAListeners(DataBroker broker, HwvtepNodeHACache hwvtepNodeHACache) {
registerListener(LogicalSwitches.class, new LogicalSwitchesCmd(), hwvtepNodeHACache);
PhysicalLocatorCmd physicalLocatorCmd = new PhysicalLocatorCmd();
- listeners.add(new PhysicalLocatorListener(broker, hwvtepNodeHACache, physicalLocatorCmd,
- LogicalDatastoreType.CONFIGURATION));
- listeners.add(new PhysicalLocatorListener(broker, hwvtepNodeHACache, physicalLocatorCmd,
- LogicalDatastoreType.OPERATIONAL));
+ listeners.add(new PhysicalLocatorListener(broker, hwvtepNodeHACache, physicalLocatorCmd, CONFIGURATION));
+ listeners.add(new PhysicalLocatorListener(broker, hwvtepNodeHACache, physicalLocatorCmd, OPERATIONAL));
}
@Override
private <T extends ChildOf<HwvtepGlobalAttributes>> void registerListener(Class<T> clazz,
MergeCommand<T, ?, ?> mergeCommand, HwvtepNodeHACache hwvtepNodeHACache) {
listeners.add(new GlobalAugmentationListener(broker, hwvtepNodeHACache, clazz, HwvtepNodeDataListener.class,
- mergeCommand, LogicalDatastoreType.CONFIGURATION));
+ mergeCommand, CONFIGURATION));
listeners.add(new GlobalAugmentationListener(broker, hwvtepNodeHACache, clazz, HwvtepNodeDataListener.class,
- mergeCommand, LogicalDatastoreType.OPERATIONAL));
+ mergeCommand, OPERATIONAL));
}
- private static class GlobalAugmentationListener<T extends DataObject
- & ChildOf<HwvtepGlobalAttributes>> extends HwvtepNodeDataListener<T> {
+ private static class GlobalAugmentationListener<D extends Datastore, T extends DataObject
+ & ChildOf<HwvtepGlobalAttributes>> extends HwvtepNodeDataListener<D, T> {
GlobalAugmentationListener(DataBroker broker, HwvtepNodeHACache hwvtepNodeHACache,
- Class<T> clazz, Class<HwvtepNodeDataListener<T>> eventClazz,
+ Class<T> clazz, Class<HwvtepNodeDataListener<D, T>> eventClazz,
MergeCommand<T, ?, ?> mergeCommand,
- LogicalDatastoreType datastoreType) {
+ Class<D> datastoreType) {
super(broker, hwvtepNodeHACache, clazz, eventClazz, mergeCommand, datastoreType);
}
}
}
- private static class PhysicalLocatorListener extends HwvtepNodeDataListener<TerminationPoint> {
+ private static class PhysicalLocatorListener<D extends Datastore>
+ extends HwvtepNodeDataListener<D, TerminationPoint> {
PhysicalLocatorListener(DataBroker broker, HwvtepNodeHACache hwvtepNodeHACache,
- MergeCommand<TerminationPoint, ?, ?> mergeCommand, LogicalDatastoreType datastoreType) {
+ MergeCommand<TerminationPoint, ?, ?> mergeCommand, Class<D> datastoreType) {
super(broker, hwvtepNodeHACache, TerminationPoint.class, (Class)PhysicalLocatorListener.class,
mergeCommand, datastoreType);
}
*/
package org.opendaylight.netvirt.elan.l2gw.ha.listeners;
+import static org.opendaylight.genius.infra.Datastore.OPERATIONAL;
+
import com.google.common.base.Optional;
import com.google.common.collect.Sets;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutionException;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import javax.inject.Inject;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.genius.infra.Datastore.Operational;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
import org.opendaylight.genius.utils.hwvtep.HwvtepNodeHACache;
import org.opendaylight.infrautils.metrics.MetricProvider;
import org.opendaylight.netvirt.elan.l2gw.ha.HwvtepHAUtil;
import org.slf4j.LoggerFactory;
@Singleton
-public class HAOpClusteredListener extends HwvtepNodeBaseListener implements ClusteredDataTreeChangeListener<Node> {
+public class HAOpClusteredListener extends HwvtepNodeBaseListener<Operational>
+ implements ClusteredDataTreeChangeListener<Node> {
private static final Logger LOG = LoggerFactory.getLogger(HAOpClusteredListener.class);
private final Set<InstanceIdentifier<Node>> connectedNodes = ConcurrentHashMap.newKeySet();
@Inject
public HAOpClusteredListener(DataBroker db, HwvtepNodeHACache hwvtepNodeHACache,
MetricProvider metricProvider) throws Exception {
- super(LogicalDatastoreType.OPERATIONAL, db, hwvtepNodeHACache, metricProvider, false);
+ super(OPERATIONAL, db, hwvtepNodeHACache, metricProvider, false);
LOG.info("Registering HAOpClusteredListener");
}
}
@Override
- synchronized void onGlobalNodeDelete(InstanceIdentifier<Node> key, Node added, ReadWriteTransaction tx) {
+ synchronized void onGlobalNodeDelete(InstanceIdentifier<Node> key, Node added,
+ TypedReadWriteTransaction<Operational> tx) {
connectedNodes.remove(key);
getHwvtepNodeHACache().updateDisconnectedNodeStatus(key);
}
@Override
- void onPsNodeDelete(InstanceIdentifier<Node> key, Node addedPSNode, ReadWriteTransaction tx) {
+ void onPsNodeDelete(InstanceIdentifier<Node> key, Node addedPSNode, TypedReadWriteTransaction<Operational> tx) {
connectedNodes.remove(key);
getHwvtepNodeHACache().updateDisconnectedNodeStatus(key);
}
@Override
- void onPsNodeAdd(InstanceIdentifier<Node> key, Node addedPSNode, ReadWriteTransaction tx) {
+ void onPsNodeAdd(InstanceIdentifier<Node> key, Node addedPSNode, TypedReadWriteTransaction<Operational> tx) {
connectedNodes.add(key);
getHwvtepNodeHACache().updateConnectedNodeStatus(key);
}
@Override
- public synchronized void onGlobalNodeAdd(InstanceIdentifier<Node> key, Node updated, ReadWriteTransaction tx) {
+ public synchronized void onGlobalNodeAdd(InstanceIdentifier<Node> key, Node updated,
+ TypedReadWriteTransaction<Operational> tx) {
connectedNodes. add(key);
HwvtepHAUtil.addToCacheIfHAChildNode(key, updated, getHwvtepNodeHACache());
getHwvtepNodeHACache().updateConnectedNodeStatus(key);
if (waitingJobs.containsKey(key) && !waitingJobs.get(key).isEmpty()) {
try {
HAJobScheduler jobScheduler = HAJobScheduler.getInstance();
- Optional<Node> nodeOptional = tx.read(LogicalDatastoreType.OPERATIONAL, key).checkedGet();
+ Optional<Node> nodeOptional = tx.read(key).get();
if (nodeOptional.isPresent()) {
waitingJobs.get(key).forEach(
(waitingJob) -> jobScheduler.submitJob(() -> waitingJob.accept(nodeOptional)));
} else {
LOG.error("Failed to read oper node {}", key);
}
- } catch (ReadFailedException e) {
+ } catch (InterruptedException | ExecutionException e) {
LOG.error("Failed to read oper node {}", key);
}
}
Node updatedChildNode,
Node beforeChildNode,
DataObjectModification<Node> mod,
- ReadWriteTransaction tx) {
+ TypedReadWriteTransaction<Operational> tx) {
boolean wasHAChild = getHwvtepNodeHACache().isHAEnabledDevice(childPath);
addToHACacheIfBecameHAChild(childPath, updatedChildNode, beforeChildNode);
boolean isHAChild = getHwvtepNodeHACache().isHAEnabledDevice(childPath);
*/
package org.opendaylight.netvirt.elan.l2gw.ha.listeners;
-import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.OPERATIONAL;
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+import static org.opendaylight.genius.infra.Datastore.OPERATIONAL;
import com.google.common.base.Optional;
import com.google.common.base.Strings;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
+import java.util.concurrent.ExecutionException;
import java.util.function.BiPredicate;
import java.util.stream.Collectors;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.genius.infra.Datastore.Operational;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
import org.opendaylight.genius.utils.hwvtep.HwvtepNodeHACache;
import org.opendaylight.infrautils.metrics.MetricProvider;
+import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
import org.opendaylight.netvirt.elan.l2gw.ha.HwvtepHAUtil;
import org.opendaylight.netvirt.elan.l2gw.ha.handlers.HAEventHandler;
import org.opendaylight.netvirt.elan.l2gw.ha.handlers.IHAEventHandler;
import org.slf4j.LoggerFactory;
@Singleton
-public class HAOpNodeListener extends HwvtepNodeBaseListener {
+public class HAOpNodeListener extends HwvtepNodeBaseListener<Operational> {
private static final Logger LOG = LoggerFactory.getLogger(HAOpNodeListener.class);
- static BiPredicate<String, InstanceIdentifier<Node>> IS_PS_CHILD_TO_GLOBAL_NODE = (globalNodeId, iid) -> {
- String psNodeId = iid.firstKeyOf(Node.class).getNodeId().getValue();
- return psNodeId.startsWith(globalNodeId) && psNodeId.contains("physicalswitch");
- };
+ private static final BiPredicate<String, InstanceIdentifier<Node>> IS_PS_CHILD_TO_GLOBAL_NODE =
+ (globalNodeId, iid) -> {
+ String psNodeId = iid.firstKeyOf(Node.class).getNodeId().getValue();
+ return psNodeId.startsWith(globalNodeId) && psNodeId.contains("physicalswitch");
+ };
private final IHAEventHandler haEventHandler;
private final HAOpClusteredListener haOpClusteredListener;
@Override
public void onGlobalNodeAdd(InstanceIdentifier<Node> childGlobalPath,
Node childNode,
- ReadWriteTransaction tx) {
+ TypedReadWriteTransaction<Operational> tx) {
//copy child global node to ha global node
//create ha global config node if not present
//copy ha global config node to child global config node
InstanceIdentifier<Node> haNodePath = getHwvtepNodeHACache().getParent(childGlobalPath);
LOG.trace("Ha enabled child node connected {}", childNode.getNodeId().getValue());
try {
- nodeCopier.copyGlobalNode(Optional.fromNullable(childNode),
- childGlobalPath, haNodePath, LogicalDatastoreType.OPERATIONAL, tx);
- nodeCopier.copyGlobalNode(Optional.fromNullable(null),
- haNodePath, childGlobalPath, LogicalDatastoreType.CONFIGURATION, tx);
- } catch (ReadFailedException e) {
+ nodeCopier.copyGlobalNode(Optional.fromNullable(childNode), childGlobalPath, haNodePath, OPERATIONAL, tx);
+ ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION,
+ confTx -> nodeCopier.copyGlobalNode(Optional.fromNullable(null), haNodePath, childGlobalPath,
+ CONFIGURATION, confTx)), LOG, "Error copying to configuration");
+ } catch (InterruptedException | ExecutionException e) {
LOG.error("Failed to read nodes {} , {} ", childGlobalPath, haNodePath);
}
readAndCopyChildPsOpToParent(childNode, tx);
Node updatedChildNode,
Node originalChildNode,
DataObjectModification<Node> mod,
- ReadWriteTransaction tx) {
+ TypedReadWriteTransaction<Operational> tx) throws ReadFailedException {
String oldHAId = HwvtepHAUtil.getHAIdFromManagerOtherConfig(originalChildNode);
if (!Strings.isNullOrEmpty(oldHAId)) { //was already ha child
@Override
void onGlobalNodeDelete(InstanceIdentifier<Node> childGlobalPath,
Node childNode,
- ReadWriteTransaction tx) throws
- ReadFailedException {
+ TypedReadWriteTransaction<Operational> tx)
+ throws ExecutionException, InterruptedException {
haOpClusteredListener.onGlobalNodeDelete(childGlobalPath, childNode, tx);
if (isNotHAChild(childGlobalPath)) {
LOG.info("non ha child global delete {} ", getNodeId(childGlobalPath));
LOG.info("All child deleted for ha node {} ", HwvtepHAUtil.getNodeIdVal(haNodePath));
//ha ps delete is taken care by ps node delete
//HwvtepHAUtil.deleteSwitchesManagedBy-Node(haNodePath, tx);
- HwvtepHAUtil.deleteNodeIfPresent(tx, OPERATIONAL, haNodePath);
+ HwvtepHAUtil.deleteNodeIfPresent(tx, haNodePath);
} else {
LOG.info("not all child deleted {} connected {}", getNodeId(childGlobalPath),
haOpClusteredListener.getConnected(children));
@Override
void onPsNodeAdd(InstanceIdentifier<Node> childPsPath,
Node childPsNode,
- ReadWriteTransaction tx) {
+ TypedReadWriteTransaction<Operational> tx) {
//copy child ps oper node to ha ps oper node
//copy ha ps config node to child ps config
haOpClusteredListener.onPsNodeAdd(childPsPath, childPsNode, tx);
InstanceIdentifier<Node> haPsPath = HwvtepHAUtil.convertPsPath(childPsNode, haGlobalPath);
try {
nodeCopier.copyPSNode(Optional.fromNullable(childPsNode), childPsPath, haPsPath, haGlobalPath,
- LogicalDatastoreType.OPERATIONAL, tx);
- nodeCopier.copyPSNode(Optional.fromNullable(null), haPsPath, childPsPath, childGlobalPath,
- LogicalDatastoreType.CONFIGURATION, tx);
- } catch (ReadFailedException e) {
+ OPERATIONAL, tx);
+ ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION,
+ confTx -> nodeCopier.copyPSNode(Optional.fromNullable(null), haPsPath, childPsPath, childGlobalPath,
+ CONFIGURATION, confTx)), LOG, "Error copying to configuration");
+ } catch (InterruptedException | ExecutionException e) {
LOG.error("Failed to read nodes {} , {} ", childPsPath, haGlobalPath);
}
}
void onPsNodeUpdate(Node updatedChildPSNode,
Node originalChildPSNode,
DataObjectModification<Node> mod,
- ReadWriteTransaction tx) {
+ TypedReadWriteTransaction<Operational> tx) {
InstanceIdentifier<Node> childGlobalPath = HwvtepHAUtil.getGlobalNodePathFromPSNode(updatedChildPSNode);
if (isNotHAChild(childGlobalPath)) {
return;
@Override
void onPsNodeDelete(InstanceIdentifier<Node> childPsPath,
Node childPsNode,
- ReadWriteTransaction tx) throws ReadFailedException {
+ TypedReadWriteTransaction<Operational> tx)
+ throws ExecutionException, InterruptedException {
//one child ps node disconnected
//find if all child ps nodes disconnected then delete parent ps node
haOpClusteredListener.onPsNodeDelete(childPsPath, childPsNode, tx);
if (haOpClusteredListener.getConnected(childPsPaths).isEmpty()) {
InstanceIdentifier<Node> haPsPath = HwvtepHAUtil.convertPsPath(childPsNode, haGlobalPath);
LOG.info("All child deleted for ha ps node {} ", HwvtepHAUtil.getNodeIdVal(haPsPath));
- HwvtepHAUtil.deleteNodeIfPresent(tx, LogicalDatastoreType.OPERATIONAL, haPsPath);
+ HwvtepHAUtil.deleteNodeIfPresent(tx, haPsPath);
//HwvtepHAUtil.deleteGlobalNodeSwitches(haGlobalPath, haPsPath, LogicalDatastoreType.OPERATIONAL, tx);
} else {
LOG.info("not all ha ps child deleted {} connected {}", getNodeId(childPsPath),
}
}
- private void readAndCopyChildPsOpToParent(Node childNode, ReadWriteTransaction tx) {
+ private void readAndCopyChildPsOpToParent(Node childNode, TypedReadWriteTransaction<Operational> tx) {
String childGlobalNodeId = childNode.getNodeId().getValue();
List<InstanceIdentifier> childPsIids = new ArrayList<>();
HwvtepGlobalAugmentation hwvtepGlobalAugmentation = childNode.augmentation(HwvtepGlobalAugmentation.class);
childPsIids.forEach((psIid) -> {
try {
InstanceIdentifier<Node> childPsIid = psIid;
- Optional<Node> childPsNode = tx.read(LogicalDatastoreType.OPERATIONAL, childPsIid).checkedGet();
+ Optional<Node> childPsNode = tx.read(childPsIid).get();
if (childPsNode.isPresent()) {
LOG.debug("Child oper PS node found");
onPsNodeAdd(childPsIid, childPsNode.get(), tx);
} else {
LOG.debug("Child oper ps node not found {}", childPsIid);
}
- } catch (ReadFailedException e) {
+ } catch (InterruptedException | ExecutionException e) {
LOG.error("Failed to read child ps node {}", psIid);
}
});
import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.opendaylight.genius.datastoreutils.TaskRetryLooper;
+import org.opendaylight.genius.infra.Datastore;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
import org.opendaylight.genius.utils.hwvtep.HwvtepNodeHACache;
import org.opendaylight.genius.utils.hwvtep.HwvtepSouthboundConstants;
import org.opendaylight.infrautils.metrics.Labeled;
import org.opendaylight.infrautils.metrics.Meter;
import org.opendaylight.infrautils.metrics.MetricDescriptor;
import org.opendaylight.infrautils.metrics.MetricProvider;
-import org.opendaylight.netvirt.elan.l2gw.ha.BatchedTransaction;
+import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
import org.opendaylight.netvirt.elan.l2gw.ha.HwvtepHAUtil;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public abstract class HwvtepNodeBaseListener implements DataTreeChangeListener<Node>, AutoCloseable {
+public abstract class HwvtepNodeBaseListener<D extends Datastore>
+ implements DataTreeChangeListener<Node>, AutoCloseable {
private static final Logger LOG = LoggerFactory.getLogger(HwvtepNodeBaseListener.class);
private static final int STARTUP_LOOP_TICK = 500;
private final ListenerRegistration<HwvtepNodeBaseListener> registration;
private final DataBroker dataBroker;
+ final ManagedNewTransactionRunner txRunner;
private final HwvtepNodeHACache hwvtepNodeHACache;
- private final MetricProvider metricProvider;
- private final LogicalDatastoreType datastoreType;
+ private final Class<D> datastoreType;
private final Function<DataObject, String> noLogicalSwitch = (data) -> "No_Ls";
private final Labeled<Labeled<Labeled<Labeled<Labeled<Meter>>>>> childModCounter;
private final Labeled<Labeled<Labeled<Meter>>> nodeModCounter;
private final boolean updateMetrics;
- ImmutableMap<Class, Function<DataObject, String>> logicalSwitchExtractor =
- new ImmutableMap.Builder<Class, Function<DataObject, String>>()
- .put(LogicalSwitches.class, data -> ((LogicalSwitches) data).getHwvtepNodeName().getValue())
- .put(RemoteMcastMacs.class, data -> {
- return logicalSwitchNameFromIid(((RemoteMcastMacs) data).key().getLogicalSwitchRef()
- .getValue());
- })
- .put(RemoteUcastMacs.class, data -> {
- return logicalSwitchNameFromIid(((RemoteUcastMacs) data).key().getLogicalSwitchRef()
- .getValue());
- }).build();
+ private static final ImmutableMap<Class, Function<DataObject, String>> LOGICAL_SWITCH_EXTRACTOR =
+ new ImmutableMap.Builder<Class, Function<DataObject, String>>()
+ .put(LogicalSwitches.class, data -> ((LogicalSwitches) data).getHwvtepNodeName().getValue())
+ .put(RemoteMcastMacs.class,
+ data -> logicalSwitchNameFromIid(((RemoteMcastMacs) data).key().getLogicalSwitchRef().getValue()))
+ .put(RemoteUcastMacs.class, data -> logicalSwitchNameFromIid(
+ ((RemoteUcastMacs) data).key().getLogicalSwitchRef().getValue())).build();
- public HwvtepNodeBaseListener(LogicalDatastoreType datastoreType, DataBroker dataBroker,
+ public HwvtepNodeBaseListener(Class<D> datastoreType, DataBroker dataBroker,
HwvtepNodeHACache hwvtepNodeHACache, MetricProvider metricProvider,
boolean updateMetrics) throws Exception {
this.dataBroker = dataBroker;
+ this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
this.datastoreType = datastoreType;
this.hwvtepNodeHACache = hwvtepNodeHACache;
- this.metricProvider = metricProvider;
this.updateMetrics = updateMetrics;
this.childModCounter = metricProvider.newMeter(
MetricDescriptor.builder().anchor(this).project("netvirt").module("l2gw").id("child").build(),
this.nodeModCounter = metricProvider.newMeter(
MetricDescriptor.builder().anchor(this).project("netvirt").module("l2gw").id("node").build(),
"datastore", "modification", "nodeid");
- final DataTreeIdentifier<Node> treeId = new DataTreeIdentifier<>(datastoreType, getWildcardPath());
+ final DataTreeIdentifier<Node> treeId =
+ new DataTreeIdentifier<>(Datastore.toType(datastoreType), getWildcardPath());
TaskRetryLooper looper = new TaskRetryLooper(STARTUP_LOOP_TICK, STARTUP_LOOP_MAX_RETRIES);
registration = looper.loopUntilNoException(() ->
dataBroker.registerDataTreeChangeListener(treeId, HwvtepNodeBaseListener.this));
@Override
public void onDataTreeChanged(final Collection<DataTreeModification<Node>> changes) {
- HAJobScheduler.getInstance().submitJob(() -> {
- ReadWriteTransaction tx = getTx();
- try {
+ HAJobScheduler.getInstance().submitJob(() -> ListenableFutures.addErrorLogging(
+ txRunner.callWithNewReadWriteTransactionAndSubmit(datastoreType, tx -> {
processConnectedNodes(changes, tx);
processUpdatedNodes(changes, tx);
processDisconnectedNodes(changes, tx);
- tx.submit().get();
- } catch (InterruptedException | ExecutionException | ReadFailedException e) {
- LOG.error("Error processing data-tree changes", e);
- }
- });
+ }), LOG, "Error processing data-tree changes"));
}
private void processUpdatedNodes(Collection<DataTreeModification<Node>> changes,
- ReadWriteTransaction tx) {
+ TypedReadWriteTransaction<D> tx)
+ throws ReadFailedException, ExecutionException, InterruptedException {
for (DataTreeModification<Node> change : changes) {
final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
final DataObjectModification<Node> mod = change.getRootNode();
private String logicalSwitchNameFromChildMod(DataObjectModification<? extends DataObject> childMod) {
DataObject data = childMod.getDataAfter() != null ? childMod.getDataAfter() : childMod.getDataBefore();
- return logicalSwitchExtractor.getOrDefault(childMod.getModificationType().getClass(), noLogicalSwitch)
+ return LOGICAL_SWITCH_EXTRACTOR.getOrDefault(childMod.getModificationType().getClass(), noLogicalSwitch)
.apply(data);
}
String childClsName = childMod.getDataType().getClass().getSimpleName();
String modificationType = childMod.getModificationType().toString();
String logicalSwitchName = logicalSwitchNameFromChildMod(childMod);
- childModCounter.label(datastoreType.name())
+ childModCounter.label(Datastore.toType(datastoreType).name())
.label(modificationType)
.label(childClsName)
.label(nodeId)
}
private void processDisconnectedNodes(Collection<DataTreeModification<Node>> changes,
- ReadWriteTransaction tx)
- throws ReadFailedException {
+ TypedReadWriteTransaction<D> tx)
+ throws InterruptedException, ExecutionException, ReadFailedException {
for (DataTreeModification<Node> change : changes) {
final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
final DataObjectModification<Node> mod = change.getRootNode();
String nodeId = key.firstKeyOf(Node.class).getNodeId().getValue();
if (deleted != null) {
if (updateMetrics) {
- nodeModCounter.label(datastoreType.name())
+ nodeModCounter.label(Datastore.toType(datastoreType).name())
.label(DataObjectModification.ModificationType.DELETE.name()).label(nodeId).mark();
}
if (!nodeId.contains(HwvtepHAUtil.PHYSICALSWITCH)) {
}
void processConnectedNodes(Collection<DataTreeModification<Node>> changes,
- ReadWriteTransaction tx)
- throws ReadFailedException {
+ TypedReadWriteTransaction<D> tx)
+ throws ExecutionException, InterruptedException {
for (DataTreeModification<Node> change : changes) {
InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
DataObjectModification<Node> mod = change.getRootNode();
String nodeId = key.firstKeyOf(Node.class).getNodeId().getValue();
if (node != null) {
if (updateMetrics) {
- nodeModCounter.label(datastoreType.name())
+ nodeModCounter.label(Datastore.toType(datastoreType).name())
.label(DataObjectModification.ModificationType.WRITE.name()).label(nodeId).mark();
}
if (!nodeId.contains(HwvtepHAUtil.PHYSICALSWITCH)) {
}
}
- ReadWriteTransaction getTx() {
- return new BatchedTransaction();
- }
-
//default methods
- void onGlobalNodeDelete(InstanceIdentifier<Node> key, Node added, ReadWriteTransaction tx)
- throws ReadFailedException {
+ void onGlobalNodeDelete(InstanceIdentifier<Node> key, Node added, TypedReadWriteTransaction<D> tx)
+ throws ReadFailedException, ExecutionException, InterruptedException {
}
- void onPsNodeDelete(InstanceIdentifier<Node> key, Node addedPSNode, ReadWriteTransaction tx)
- throws ReadFailedException {
+ void onPsNodeDelete(InstanceIdentifier<Node> key, Node addedPSNode, TypedReadWriteTransaction<D> tx)
+ throws ReadFailedException, ExecutionException, InterruptedException {
}
- void onGlobalNodeAdd(InstanceIdentifier<Node> key, Node added, ReadWriteTransaction tx) {
+ void onGlobalNodeAdd(InstanceIdentifier<Node> key, Node added, TypedReadWriteTransaction<D> tx) {
}
- void onPsNodeAdd(InstanceIdentifier<Node> key, Node addedPSNode, ReadWriteTransaction tx)
- throws ReadFailedException {
+ void onPsNodeAdd(InstanceIdentifier<Node> key, Node addedPSNode, TypedReadWriteTransaction<D> tx)
+ throws InterruptedException, ExecutionException {
}
void onGlobalNodeUpdate(InstanceIdentifier<Node> key, Node updated, Node original,
- DataObjectModification<Node> mod, ReadWriteTransaction tx) {
+ DataObjectModification<Node> mod, TypedReadWriteTransaction<D> tx)
+ throws ReadFailedException, InterruptedException, ExecutionException {
}
void onPsNodeUpdate(Node updated, Node original,
- DataObjectModification<Node> mod, ReadWriteTransaction tx) {
+ DataObjectModification<Node> mod, TypedReadWriteTransaction<D> tx)
+ throws ReadFailedException, InterruptedException, ExecutionException {
}
import com.google.common.base.Optional;
import java.util.Objects;
import java.util.Set;
+import java.util.concurrent.ExecutionException;
import java.util.function.BiConsumer;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
+import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
+import org.opendaylight.genius.infra.Datastore;
+import org.opendaylight.genius.infra.Datastore.Operational;
import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
import org.opendaylight.genius.utils.hwvtep.HwvtepNodeHACache;
import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
import org.opendaylight.netvirt.elan.l2gw.ha.commands.MergeCommand;
* When an operational child node data is updated, it is copied to parent
* When a config parent node data is updated , it is copied to all its children.
*/
-public abstract class HwvtepNodeDataListener<T extends DataObject>
- extends AsyncDataTreeChangeListenerBase<T, HwvtepNodeDataListener<T>> {
+public abstract class HwvtepNodeDataListener<D extends Datastore, T extends DataObject>
+ extends AsyncDataTreeChangeListenerBase<T, HwvtepNodeDataListener<D, T>> {
private static final Logger LOG = LoggerFactory.getLogger(HwvtepNodeDataListener.class);
private final ManagedNewTransactionRunner txRunner;
+ private final SingleTransactionDataBroker singleTxBroker;
private final MergeCommand<T, ?, ?> mergeCommand;
- private final LogicalDatastoreType datastoreType;
+ private final Class<D> datastoreType;
private final BiConsumer<InstanceIdentifier<T>, T> addOperation;
private final BiConsumer<InstanceIdentifier<T>, T> removeOperation;
private final HwvtepNodeHACache hwvtepNodeHACache;
public HwvtepNodeDataListener(DataBroker broker,
HwvtepNodeHACache hwvtepNodeHACache,
Class<T> clazz,
- Class<HwvtepNodeDataListener<T>> eventClazz,
+ Class<HwvtepNodeDataListener<D, T>> eventClazz,
MergeCommand<T, ?, ?> mergeCommand,
- LogicalDatastoreType datastoreType) {
+ Class<D> datastoreType) {
super(clazz, eventClazz);
this.hwvtepNodeHACache = hwvtepNodeHACache;
this.txRunner = new ManagedNewTransactionRunnerImpl(broker);
+ this.singleTxBroker = new SingleTransactionDataBroker(broker);
this.mergeCommand = mergeCommand;
this.datastoreType = datastoreType;
- if (LogicalDatastoreType.OPERATIONAL == datastoreType) {
+ if (Operational.class.equals(datastoreType)) {
this.addOperation = this::copyToParent;
this.removeOperation = this::deleteFromParent;
} else {
HAJobScheduler.getInstance().submitJob(() -> removeOperation.accept(identifier, dataRemoved));
}
- private boolean isNodeConnected(InstanceIdentifier<T> identifier, ReadTransaction tx)
+ private boolean isNodeConnected(InstanceIdentifier<T> identifier)
throws ReadFailedException {
- return tx.read(LogicalDatastoreType.OPERATIONAL, identifier.firstIdentifierOf(Node.class))
- .checkedGet().isPresent();
+ return singleTxBroker.syncReadOptional(LogicalDatastoreType.OPERATIONAL,
+ identifier.firstIdentifierOf(Node.class)).isPresent();
}
private static <T extends DataObject> boolean isDataUpdated(Optional<T> existingDataOptional, T newData) {
LOG.trace("Copy child op data {} to parent {}", mergeCommand.getDescription(), getNodeId(parent));
T parentData = mergeCommand.transform(parent, data);
InstanceIdentifier<T> parentIdentifier = mergeCommand.generateId(parent, parentData);
- ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(
+ ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(datastoreType,
tx -> writeToMdsal(tx, parentData, parentIdentifier)), LOG, "Error copying to parent");
}
}
}
InstanceIdentifier<Node> parent = getHAParent(identifier);
if (parent != null) {
- ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(tx -> {
- if (isNodeConnected(identifier, tx)) {
+ ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(datastoreType, tx -> {
+ if (isNodeConnected(identifier)) {
LOG.trace("Copy child op data {} to parent {} create:{}", mergeCommand.getDescription(),
getNodeId(parent), false);
T parentData = mergeCommand.transform(parent, data);
private void copyToChildren(final InstanceIdentifier<T> parentIdentifier, final T parentData) {
Set<InstanceIdentifier<Node>> children = getChildrenForHANode(parentIdentifier);
if (children != null) {
- ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(tx -> {
+ ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(datastoreType, tx -> {
for (InstanceIdentifier<Node> child : children) {
LOG.trace("Copy parent config data {} to child {}", mergeCommand.getDescription(),
getNodeId(child));
private void deleteFromChildren(final InstanceIdentifier<T> parentIdentifier, final T parentData) {
Set<InstanceIdentifier<Node>> children = getChildrenForHANode(parentIdentifier);
if (children != null) {
- ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(tx -> {
+ ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(datastoreType, tx -> {
for (InstanceIdentifier<Node> child : children) {
LOG.trace("Delete parent config data {} to child {}", mergeCommand.getDescription(),
getNodeId(child));
}
}
- private void writeToMdsal(final ReadWriteTransaction tx, final T data, final InstanceIdentifier<T> identifier)
- throws ReadFailedException {
- if (isDataUpdated(tx.read(datastoreType, identifier).checkedGet(), data)) {
- tx.put(datastoreType, identifier, data);
+ private void writeToMdsal(final TypedReadWriteTransaction<D> tx, final T data,
+ final InstanceIdentifier<T> identifier) throws ExecutionException, InterruptedException {
+ if (isDataUpdated(tx.read(identifier).get(), data)) {
+ tx.put(identifier, data);
}
}
- private void deleteFromMdsal(final ReadWriteTransaction tx,
- final InstanceIdentifier<T> identifier) throws ReadFailedException {
- if (tx.read(datastoreType, identifier).checkedGet().isPresent()) {
- tx.delete(datastoreType, identifier);
+ private void deleteFromMdsal(final TypedReadWriteTransaction<D> tx,
+ final InstanceIdentifier<T> identifier) throws ExecutionException, InterruptedException {
+ if (tx.read(identifier).get().isPresent()) {
+ tx.delete(identifier);
}
}
}
@Override
- protected HwvtepNodeDataListener<T> getDataTreeChangeListener() {
+ protected HwvtepNodeDataListener<D, T> getDataTreeChangeListener() {
return HwvtepNodeDataListener.this;
}
- protected Set<InstanceIdentifier<Node>> getChildrenForHANode(InstanceIdentifier identifier) {
+ protected Set<InstanceIdentifier<Node>> getChildrenForHANode(InstanceIdentifier<T> identifier) {
InstanceIdentifier<Node> parent = identifier.firstIdentifierOf(Node.class);
return hwvtepNodeHACache.getChildrenForHANode(parent);
}
- protected InstanceIdentifier<Node> getHAParent(InstanceIdentifier identifier) {
+ protected InstanceIdentifier<Node> getHAParent(InstanceIdentifier<T> identifier) {
InstanceIdentifier<Node> child = identifier.firstIdentifierOf(Node.class);
return hwvtepNodeHACache.getParent(child);
}
*/
package org.opendaylight.netvirt.elan.l2gw.ha.merge;
-import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.CONFIGURATION;
-import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.OPERATIONAL;
+import static org.opendaylight.controller.md.sal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+import static org.opendaylight.genius.infra.Datastore.OPERATIONAL;
import com.google.common.base.Optional;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
+import java.util.concurrent.ExecutionException;
import java.util.function.BiPredicate;
import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.genius.infra.Datastore;
+import org.opendaylight.genius.infra.Datastore.Configuration;
+import org.opendaylight.genius.infra.Datastore.Operational;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
import org.opendaylight.genius.utils.SuperTypeUtil;
import org.opendaylight.netvirt.elan.l2gw.ha.commands.LocalUcastCmd;
import org.opendaylight.netvirt.elan.l2gw.ha.commands.MergeCommand;
protected Map<Class<?>, MergeCommand> commands = new HashMap<>();
- private final BiPredicate<LogicalDatastoreType, Class> skipCopy =
- (dsType, cmdType) -> (dsType == CONFIGURATION ? commands.get(cmdType) instanceof LocalUcastCmd
+ private final BiPredicate<Class<? extends Datastore>, Class> skipCopy =
+ (dsType, cmdType) -> (Configuration.class.equals(dsType) ? commands.get(cmdType) instanceof LocalUcastCmd
: commands.get(cmdType) instanceof RemoteUcastCmd);
protected MergeCommandsAggregator() {
public void mergeConfigUpdate(InstanceIdentifier<Node> dstPath,
DataObjectModification mod,
- ReadWriteTransaction tx) {
+ TypedReadWriteTransaction<Configuration> tx) {
mergeUpdate(dstPath, mod, CONFIGURATION, tx);
}
public void mergeOpUpdate(InstanceIdentifier<Node> dstPath,
DataObjectModification mod,
- ReadWriteTransaction tx) {
+ TypedReadWriteTransaction<Operational> tx) {
mergeUpdate(dstPath, mod, OPERATIONAL, tx);
}
- public void mergeUpdate(InstanceIdentifier<Node> dstPath,
+ public <D extends Datastore> void mergeUpdate(InstanceIdentifier<Node> dstPath,
DataObjectModification mod,
- LogicalDatastoreType datastoreType,
- ReadWriteTransaction tx) {
+ Class<D> datastoreType,
+ TypedReadWriteTransaction<D> tx) {
if (mod == null) {
return;
}
Optional<DataObject> existingDataOptional = null;
try {
- existingDataOptional = tx.read(datastoreType, transformedId).checkedGet();
- } catch (ReadFailedException ex) {
+ existingDataOptional = tx.read(transformedId).get();
+ } catch (InterruptedException | ExecutionException ex) {
LOG.error("Failed to read data {} from {}", transformedId, datastoreType);
return;
}
- String destination = datastoreType == CONFIGURATION ? "child" : "parent";
+ String destination = Configuration.class.equals(datastoreType) ? "child" : "parent";
if (create) {
if (isDataUpdated(existingDataOptional, transformedItem)) {
LOG.debug("Copy to {} {} {}", destination, datastoreType, transformedId);
- tx.put(datastoreType, transformedId, transformedItem, true);
+ tx.put(transformedId, transformedItem, CREATE_MISSING_PARENTS);
} else {
LOG.debug("Data not updated skip copy to {}", transformedId);
}
} else {
if (existingDataOptional.isPresent()) {
LOG.debug("Delete from {} {} {}", destination, datastoreType, transformedId);
- tx.delete(datastoreType, transformedId);
+ tx.delete(transformedId);
} else {
LOG.debug("Delete skipped for {}", transformedId);
}
public List<ListenableFuture<Void>> call() {
LOG.info("running update mcast mac entry job for {} {}",
elanName, l2GatewayDevice.getHwvtepNodeId());
- return Collections.singletonList(
- elanL2GatewayMulticastUtils.updateRemoteMcastMacOnElanL2GwDevice(elanName, l2GatewayDevice));
+ elanL2GatewayMulticastUtils.updateRemoteMcastMacOnElanL2GwDevice(elanName, l2GatewayDevice);
+ return Collections.emptyList();
}
}
futures.add(elanL2GatewayUtils.updateVlanBindingsInL2GatewayDevice(
new NodeId(elanL2GwDevice.getHwvtepNodeId()), logicalSwitchName, physicalDevice, defaultVlanId));
LOG.info("creating mast mac entries for {} {}", logicalSwitchName, elanL2GwDevice.getHwvtepNodeId());
- futures.add(elanL2GatewayMulticastUtils.handleMcastForElanL2GwDeviceAdd(logicalSwitchName,
- elanL2GwDevice));
+ elanL2GatewayMulticastUtils.handleMcastForElanL2GwDeviceAdd(logicalSwitchName, elanL2GwDevice);
futures.add(elanL2GatewayUtils.installElanMacsInL2GatewayDevice(
logicalSwitchName, elanL2GwDevice));
return futures;
*/
package org.opendaylight.netvirt.elan.l2gw.listeners;
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+import static org.opendaylight.genius.infra.Datastore.OPERATIONAL;
+
import com.google.common.collect.Sets;
import java.util.Collections;
import java.util.HashMap;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
import org.opendaylight.genius.utils.batching.ResourceBatchingManager;
if (IS_PS_NODE_IID.test(nodeIid)) {
return;
}
- ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(tx -> {
- haOpClusteredListener.onGlobalNodeAdd(nodeIid, modification.getRootNode().getDataAfter(), tx);
- if (!isHAChild(nodeIid)) {
+ // TODO skitt we're only using read transactions here
+ ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL,
+ tx -> haOpClusteredListener.onGlobalNodeAdd(nodeIid, modification.getRootNode().getDataAfter(), tx)), LOG,
+ "Error processing added parent");
+ if (!isHAChild(nodeIid)) {
+ ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
LOG.trace("On parent add {}", nodeIid);
Node operNode = modification.getRootNode().getDataAfter();
- Set<LocalUcastMacs> configMacs =
- getMacs(tx.read(LogicalDatastoreType.CONFIGURATION, nodeIid).checkedGet().orNull());
+ Set<LocalUcastMacs> configMacs = getMacs(tx.read(nodeIid).get().orNull());
Set<LocalUcastMacs> operMacs = getMacs(operNode);
Set<LocalUcastMacs> staleMacs = Sets.difference(configMacs, operMacs);
staleMacs.forEach(staleMac -> removed(getMacIid(nodeIid, staleMac), staleMac));
- }
- }), LOG, "Error processing added parent");
+ }), LOG, "Error processing added parent");
+ }
}
InstanceIdentifier<LocalUcastMacs> getMacIid(InstanceIdentifier<Node> nodeIid, LocalUcastMacs mac) {
* Handle mcast for elan l2 gw device add.
* @param elanName the elan name
* @param device the device
- * @return the listenable future
*/
- public ListenableFuture<Void> handleMcastForElanL2GwDeviceAdd(String elanName, L2GatewayDevice device) {
+ public void handleMcastForElanL2GwDeviceAdd(String elanName, L2GatewayDevice device) {
InstanceIdentifier<ExternalTeps> tepPath = buildExternalTepPath(elanName, device.getTunnelIp());
- JdkFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
- tx.put(tepPath, buildExternalTeps(device));
- }), LOG, "Failed to write to config external tep {}", tepPath);
- return updateMcastMacsForAllElanDevices(elanName, device, true/* updateThisDevice */);
+ JdkFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
+ tx -> tx.put(tepPath, buildExternalTeps(device))), LOG, "Failed to write to config external tep {}",
+ tepPath);
+ updateMcastMacsForAllElanDevices(elanName, device, true/* updateThisDevice */);
}
public static InstanceIdentifier<ExternalTeps> buildExternalTepPath(String elan, IpAddress tepIp) {
*
* @param elanName
* the elan to be updated
- * @return the listenable future
*/
- @SuppressWarnings("checkstyle:IllegalCatch")
- public ListenableFuture<Void> updateRemoteMcastMacOnElanL2GwDevices(String elanName) {
- return txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
- for (L2GatewayDevice device : ElanL2GwCacheUtils.getInvolvedL2GwDevices(elanName).values()) {
- prepareRemoteMcastMacUpdateOnDevice(elanName, device);
- }
- });
+ public void updateRemoteMcastMacOnElanL2GwDevices(String elanName) {
+ for (L2GatewayDevice device : ElanL2GwCacheUtils.getInvolvedL2GwDevices(elanName).values()) {
+ prepareRemoteMcastMacUpdateOnDevice(elanName, device);
+ }
}
public void scheduleMcastMacUpdateJob(String elanName, L2GatewayDevice device) {
* the elan name
* @param device
* the device
- * @return the listenable future
*/
- public ListenableFuture<Void> updateRemoteMcastMacOnElanL2GwDevice(String elanName, L2GatewayDevice device) {
- return txRunner.callWithNewWriteOnlyTransactionAndSubmit(
- tx -> prepareRemoteMcastMacUpdateOnDevice(elanName, device));
+ public void updateRemoteMcastMacOnElanL2GwDevice(String elanName, L2GatewayDevice device) {
+ prepareRemoteMcastMacUpdateOnDevice(elanName, device);
}
public void prepareRemoteMcastMacUpdateOnDevice(String elanName,
List<DpnInterfaces> dpns = elanUtils.getElanDPNByName(elanName);
List<IpAddress> dpnsTepIps = getAllTepIpsOfDpns(device, dpns);
List<IpAddress> l2GwDevicesTepIps = getAllTepIpsOfL2GwDevices(elanL2gwDevices);
- preapareRemoteMcastMacEntry(elanName, device, dpnsTepIps, l2GwDevicesTepIps);
+ prepareRemoteMcastMacEntry(elanName, device, dpnsTepIps, l2GwDevicesTepIps);
}
/**
* the device
* @param updateThisDevice
* the update this device
- * @return the listenable future
*/
- private ListenableFuture<Void> updateMcastMacsForAllElanDevices(String elanName, L2GatewayDevice device,
+ private void updateMcastMacsForAllElanDevices(String elanName, L2GatewayDevice device,
boolean updateThisDevice) {
SettableFuture<Void> ft = SettableFuture.create();
// return ft;
// }
- return txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
- if (updateThisDevice) {
- preapareRemoteMcastMacEntry(elanName, device, dpnsTepIps, l2GwDevicesTepIps);
- }
+ if (updateThisDevice) {
+ prepareRemoteMcastMacEntry(elanName, device, dpnsTepIps, l2GwDevicesTepIps);
+ }
- // TODO: Need to revisit below logic as logical switches might not be
- // present to configure RemoteMcastMac entry
- for (L2GatewayDevice otherDevice : devices.values()) {
- if (!otherDevice.getDeviceName().equals(device.getDeviceName())) {
- preapareRemoteMcastMacEntry(elanName, otherDevice, dpnsTepIps, l2GwDevicesTepIps);
- }
+ // TODO: Need to revisit below logic as logical switches might not be
+ // present to configure RemoteMcastMac entry
+ for (L2GatewayDevice otherDevice : devices.values()) {
+ if (!otherDevice.getDeviceName().equals(device.getDeviceName())) {
+ prepareRemoteMcastMacEntry(elanName, otherDevice, dpnsTepIps, l2GwDevicesTepIps);
}
- });
-
+ }
}
public void updateRemoteBroadcastGroupForAllElanDpns(ElanInstance elanInfo) {
* the l2 gw devices tep ips
* @return the write transaction
*/
- private void preapareRemoteMcastMacEntry(String elanName,
+ private void prepareRemoteMcastMacEntry(String elanName,
L2GatewayDevice device, List<IpAddress> dpnsTepIps,
List<IpAddress> l2GwDevicesTepIps) {
NodeId nodeId = new NodeId(device.getHwvtepNodeId());
*/
public List<ListenableFuture<Void>> handleMcastForElanL2GwDeviceDelete(String elanName,
L2GatewayDevice l2GatewayDevice) {
- ListenableFuture<Void> deleteTepFuture = txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
- tx.delete(LogicalDatastoreType.CONFIGURATION,
- buildExternalTepPath(elanName, l2GatewayDevice.getTunnelIp()));
- });
- ListenableFuture<Void> updateMcastMacsFuture = updateMcastMacsForAllElanDevices(
- elanName, l2GatewayDevice, false/* updateThisDevice */);
+ ListenableFuture<Void> deleteTepFuture =
+ txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
+ tx -> tx.delete(buildExternalTepPath(elanName, l2GatewayDevice.getTunnelIp())));
+ updateMcastMacsForAllElanDevices(elanName, l2GatewayDevice, false/* updateThisDevice */);
ListenableFuture<Void> deleteRemoteMcastMacFuture = deleteRemoteMcastMac(
new NodeId(l2GatewayDevice.getHwvtepNodeId()), elanName);
- return Arrays.asList(updateMcastMacsFuture, deleteRemoteMcastMacFuture, deleteTepFuture);
+ return Arrays.asList(deleteRemoteMcastMacFuture, deleteTepFuture);
}
/**
return Futures.immediateFailedFuture(new RuntimeException(errMsg));
}
- return txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
+ return txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
for (org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712
.l2gateway.attributes.devices.Interfaces deviceInterface : hwVtepDevice.getInterfaces()) {
//Removed the check for checking terminationPoint present in OP or not
*/
public ListenableFuture<Void> updateVlanBindingsInL2GatewayDevice(NodeId nodeId, String psName,
String interfaceName, List<VlanBindings> vlanBindings) {
- return txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
+ return txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
HwvtepUtils.mergeVlanBindings(tx, nodeId, psName, interfaceName, vlanBindings);
LOG.info("Updated Hwvtep VlanBindings in config DS. NodeID: {}", nodeId.getValue());
});
}
NodeId physicalSwitchNodeId = HwvtepSouthboundUtils.createManagedNodeId(nodeId, hwVtepDevice.getDeviceName());
- return txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
+ return txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
for (org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712
.l2gateway.attributes.devices.Interfaces deviceInterface : hwVtepDevice.getInterfaces()) {
String phyPortName = deviceInterface.getInterfaceName();
*/
package org.opendaylight.netvirt.elan.l2gw.utils;
-import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.CONFIGURATION;
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
import java.util.ArrayList;
import java.util.Collections;
() -> {
L2GatewayDevice l2GwDevice = l2GatewayCache.get(deviceName);
NodeId globalNodeId = globalNodeIid.firstKeyOf(Node.class).getNodeId();
- Node configNode = MDSALUtil.read(broker, CONFIGURATION, globalNodeIid)
+ Node configNode = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, globalNodeIid)
.or(defaultNode(globalNodeId));
- Node configPsNode = MDSALUtil.read(broker, CONFIGURATION, psNodeIid).or(defaultNode(psNodeId));
+ Node configPsNode =
+ MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, psNodeIid).or(defaultNode(psNodeId));
cleanupStaleLogicalSwitches(l2GwDevice, configNode, configPsNode);
cleanupTasks.remove(psNodeIid.firstKeyOf(Node.class).getNodeId());
}, getCleanupDelay(), TimeUnit.SECONDS);
LOG.trace("CleanupStaleBindings for logical switch {}", staleLogicalSwitch);
ListenableFutures.addErrorLogging(
- txRunner.callWithNewReadWriteTransactionAndSubmit(tx -> {
+ txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
if (vlans.containsKey(staleLogicalSwitch)) {
- vlans.get(staleLogicalSwitch)
- .forEach((vlanIid) -> tx.delete(LogicalDatastoreType.CONFIGURATION, vlanIid));
+ vlans.get(staleLogicalSwitch).forEach((vlanIid) -> tx.delete(vlanIid));
}
}),
LOG, "Failed to delete stale vlan bindings from node {}", globalNodeId);
*/
package org.opendaylight.netvirt.elan.utils;
+import static org.opendaylight.controller.md.sal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+import static org.opendaylight.genius.infra.Datastore.OPERATIONAL;
import com.google.common.base.Optional;
import com.google.common.util.concurrent.ListenableFuture;
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.ExecutionException;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.genius.infra.Datastore.Operational;
import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo;
import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
private static final Logger LOG = LoggerFactory.getLogger(ElanForwardingEntriesHandler.class);
- private final DataBroker broker;
private final ManagedNewTransactionRunner txRunner;
private final ElanUtils elanUtils;
@Inject
public ElanForwardingEntriesHandler(DataBroker dataBroker, ElanUtils elanUtils) {
- this.broker = dataBroker;
this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
this.elanUtils = elanUtils;
}
public void updateElanInterfaceForwardingTablesList(String elanInstanceName, String interfaceName,
- String existingInterfaceName, MacEntry mac, WriteTransaction tx) {
+ String existingInterfaceName, MacEntry mac, TypedReadWriteTransaction<Operational> tx)
+ throws ExecutionException, InterruptedException {
if (existingInterfaceName.equals(interfaceName)) {
LOG.error("Static MAC address {} has already been added for the same ElanInstance "
+ "{} on the same Logical Interface Port {}."
}
public void addElanInterfaceForwardingTableList(String elanInstanceName, String interfaceName,
- StaticMacEntries staticMacEntries, WriteTransaction tx) {
+ StaticMacEntries staticMacEntries, TypedReadWriteTransaction<Operational> tx)
+ throws ExecutionException, InterruptedException {
MacEntry macEntry = new MacEntryBuilder().setIsStaticAddress(true)
.setMacAddress(staticMacEntries.getMacAddress())
.setIpPrefix(staticMacEntries.getIpPrefix())
}
public void deleteElanInterfaceForwardingTablesList(String interfaceName, MacEntry mac,
- WriteTransaction interfaceTx) {
+ TypedReadWriteTransaction<Operational> interfaceTx)
+ throws ExecutionException, InterruptedException {
InstanceIdentifier<MacEntry> existingMacEntryId = ElanUtils
.getInterfaceMacEntriesIdentifierOperationalDataPath(interfaceName, mac.getMacAddress());
MacEntry existingInterfaceMacEntry = elanUtils
- .getInterfaceMacEntriesOperationalDataPathFromId(existingMacEntryId);
+ .getInterfaceMacEntriesOperationalDataPathFromId(interfaceTx, existingMacEntryId);
if (existingInterfaceMacEntry != null) {
- interfaceTx.delete(LogicalDatastoreType.OPERATIONAL, existingMacEntryId);
+ interfaceTx.delete(existingMacEntryId);
}
}
- public void createElanInterfaceForwardingTablesList(String interfaceName, MacEntry mac, WriteTransaction tx) {
+ public void createElanInterfaceForwardingTablesList(String interfaceName, MacEntry mac,
+ TypedReadWriteTransaction<Operational> tx) throws ExecutionException, InterruptedException {
InstanceIdentifier<MacEntry> existingMacEntryId = ElanUtils
.getInterfaceMacEntriesIdentifierOperationalDataPath(interfaceName, mac.getMacAddress());
MacEntry existingInterfaceMacEntry = elanUtils
- .getInterfaceMacEntriesOperationalDataPathFromId(existingMacEntryId);
+ .getInterfaceMacEntriesOperationalDataPathFromId(tx, existingMacEntryId);
if (existingInterfaceMacEntry == null) {
MacEntry macEntry = new MacEntryBuilder().setMacAddress(mac.getMacAddress()).setIpPrefix(mac.getIpPrefix())
.setInterface(interfaceName)
.setIsStaticAddress(true).withKey(new MacEntryKey(mac.getMacAddress())).build();
- tx.put(LogicalDatastoreType.OPERATIONAL, existingMacEntryId, macEntry,
- WriteTransaction.CREATE_MISSING_PARENTS);
+ tx.put(existingMacEntryId, macEntry, CREATE_MISSING_PARENTS);
}
}
public void updateElanForwardingTablesList(String elanName, String interfaceName, MacEntry mac,
- WriteTransaction tx) {
+ TypedReadWriteTransaction<Operational> tx) throws ExecutionException, InterruptedException {
InstanceIdentifier<MacEntry> macEntryId = ElanUtils.getMacEntryOperationalDataPath(elanName,
mac.getMacAddress());
- MacEntry existingMacEntry = elanUtils.getMacEntryFromElanMacId(macEntryId);
+ MacEntry existingMacEntry = elanUtils.getMacEntryFromElanMacId(tx, macEntryId);
if (existingMacEntry != null && elanUtils.getElanMacTable(elanName) != null) {
MacEntry newMacEntry = new MacEntryBuilder().setInterface(interfaceName).setIsStaticAddress(true)
.setMacAddress(mac.getMacAddress()).setIpPrefix(mac.getIpPrefix())
.withKey(new MacEntryKey(mac.getMacAddress())).build();
- tx.put(LogicalDatastoreType.OPERATIONAL, macEntryId, newMacEntry);
+ tx.put(macEntryId, newMacEntry);
}
}
- private void createElanForwardingTablesList(String elanName, MacEntry macEntry, WriteTransaction tx) {
+ private void createElanForwardingTablesList(String elanName, MacEntry macEntry,
+ TypedReadWriteTransaction<Operational> tx) throws ExecutionException, InterruptedException {
InstanceIdentifier<MacEntry> macEntryId = ElanUtils.getMacEntryOperationalDataPath(elanName,
macEntry.getMacAddress());
- Optional<MacEntry> existingMacEntry = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, macEntryId);
+ Optional<MacEntry> existingMacEntry = tx.read(macEntryId).get();
if (!existingMacEntry.isPresent() && elanUtils.getElanMacTable(elanName) != null) {
- tx.put(LogicalDatastoreType.OPERATIONAL, macEntryId, macEntry, WriteTransaction.CREATE_MISSING_PARENTS);
+ tx.put(macEntryId, macEntry, CREATE_MISSING_PARENTS);
}
}
public void deleteElanInterfaceForwardingEntries(ElanInstance elanInfo, InterfaceInfo interfaceInfo,
MacEntry macEntry) {
List<ListenableFuture<Void>> futures = new ArrayList<>();
- futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(interfaceTx -> {
+ futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, interfaceTx -> {
InstanceIdentifier<MacEntry> macEntryId = ElanUtils
.getMacEntryOperationalDataPath(elanInfo.getElanInstanceName(), macEntry.getMacAddress());
- interfaceTx.delete(LogicalDatastoreType.OPERATIONAL, macEntryId);
+ interfaceTx.delete(macEntryId);
deleteElanInterfaceForwardingTablesList(interfaceInfo.getInterfaceName(), macEntry, interfaceTx);
- futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, flowTx -> {
- elanUtils.deleteMacFlows(elanInfo, interfaceInfo, macEntry, flowTx);
- }));
+ futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION,
+ flowTx -> elanUtils.deleteMacFlows(elanInfo, interfaceInfo, macEntry, flowTx)));
}));
for (ListenableFuture<Void> future : futures) {
ListenableFutures.addErrorLogging(future, LOG, "Error deleting ELAN interface forwarding entries");
*/
package org.opendaylight.netvirt.elan.utils;
+import static org.opendaylight.controller.md.sal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
import com.google.common.base.Optional;
import org.apache.commons.lang3.StringUtils;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.genius.infra.Datastore.Configuration;
+import org.opendaylight.genius.infra.Datastore.Operational;
import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.genius.infra.TypedReadTransaction;
import org.opendaylight.genius.infra.TypedReadWriteTransaction;
+import org.opendaylight.genius.infra.TypedWriteTransaction;
import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo;
import org.opendaylight.genius.interfacemanager.globals.InterfaceServiceUtil;
import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
}
@Nullable
- public static Elan getElanByName(ReadTransaction tx, String elanInstanceName) throws ReadFailedException {
- return tx.read(LogicalDatastoreType.OPERATIONAL,
- getElanInstanceOperationalDataPath(elanInstanceName)).checkedGet().orNull();
+ public static Elan getElanByName(TypedReadTransaction<Operational> tx, String elanInstanceName)
+ throws ExecutionException, InterruptedException {
+ return tx.read(getElanInstanceOperationalDataPath(elanInstanceName)).get().orNull();
}
public static InstanceIdentifier<Elan> getElanInstanceOperationalDataPath(String elanInstanceName) {
return existingInterfaceMacEntry.orNull();
}
+ public MacEntry getInterfaceMacEntriesOperationalDataPathFromId(TypedReadTransaction<Operational> tx,
+ InstanceIdentifier<MacEntry> identifier) throws ExecutionException, InterruptedException {
+ return tx.read(identifier).get().orNull();
+ }
+
public static InstanceIdentifier<MacEntry> getInterfaceMacEntriesIdentifierOperationalDataPath(String interfaceName,
PhysAddress physAddress) {
return InstanceIdentifier.builder(ElanInterfaceForwardingEntries.class)
return read(broker, LogicalDatastoreType.OPERATIONAL, macId);
}
- public Optional<MacEntry> getMacEntryForElanInstance(ReadTransaction tx, String elanName, PhysAddress physAddress)
- throws ReadFailedException {
+ public Optional<MacEntry> getMacEntryForElanInstance(TypedReadTransaction<Operational> tx, String elanName,
+ PhysAddress physAddress) throws ExecutionException, InterruptedException {
InstanceIdentifier<MacEntry> macId = getMacEntryOperationalDataPath(elanName, physAddress);
- return tx.read(LogicalDatastoreType.OPERATIONAL, macId).checkedGet();
+ return tx.read(macId).get();
}
public MacEntry getMacEntryFromElanMacId(InstanceIdentifier identifier) {
return existingInterfaceMacEntry.orNull();
}
+ public MacEntry getMacEntryFromElanMacId(TypedReadTransaction<Operational> tx,
+ InstanceIdentifier<MacEntry> identifier) throws ExecutionException, InterruptedException {
+ return tx.read(identifier).get().orNull();
+ }
+
public static InstanceIdentifier<MacEntry> getMacEntryOperationalDataPath(String elanName,
PhysAddress physAddress) {
return InstanceIdentifier.builder(ElanForwardingTables.class).child(MacTable.class, new MacTableKey(elanName))
*/
public void setupMacFlows(ElanInstance elanInfo, InterfaceInfo interfaceInfo,
long macTimeout, String macAddress, boolean configureRemoteFlows,
- WriteTransaction writeFlowGroupTx) {
+ TypedWriteTransaction<Configuration> writeFlowGroupTx) {
synchronized (getElanMacDPNKey(elanInfo.getElanTag(), macAddress, interfaceInfo.getDpId())) {
setupKnownSmacFlow(elanInfo, interfaceInfo, macTimeout, macAddress, mdsalManager,
writeFlowGroupTx);
}
public void setupDMacFlowOnRemoteDpn(ElanInstance elanInfo, InterfaceInfo interfaceInfo, BigInteger dstDpId,
- String macAddress, WriteTransaction writeFlowTx) {
+ String macAddress, TypedWriteTransaction<Configuration> writeFlowTx) {
String elanInstanceName = elanInfo.getElanInstanceName();
setupRemoteDmacFlow(dstDpId, interfaceInfo.getDpId(), interfaceInfo.getInterfaceTag(), elanInfo.getElanTag(),
macAddress, elanInstanceName, writeFlowTx, interfaceInfo.getInterfaceName(), elanInfo);
* learnt.
*/
private void setupKnownSmacFlow(ElanInstance elanInfo, InterfaceInfo interfaceInfo, long macTimeout,
- String macAddress, IMdsalApiManager mdsalApiManager, WriteTransaction writeFlowGroupTx) {
+ String macAddress, IMdsalApiManager mdsalApiManager,
+ TypedWriteTransaction<Configuration> writeFlowGroupTx) {
FlowEntity flowEntity = buildKnownSmacFlow(elanInfo, interfaceInfo, macTimeout, macAddress);
- mdsalApiManager.addFlowToTx(flowEntity, writeFlowGroupTx);
+ mdsalApiManager.addFlow(writeFlowGroupTx, flowEntity);
LOG.debug("Known Smac flow entry created for elan Name:{}, logical Interface port:{} and mac address:{}",
elanInfo.getElanInstanceName(), elanInfo.getDescription(), macAddress);
}
* the writeFLowGroup tx
*/
public void setupTermDmacFlows(InterfaceInfo interfaceInfo, IMdsalApiManager mdsalApiManager,
- WriteTransaction writeFlowGroupTx) {
+ TypedWriteTransaction<Configuration> writeFlowGroupTx) {
BigInteger dpId = interfaceInfo.getDpId();
int lportTag = interfaceInfo.getInterfaceTag();
Flow flow = MDSALUtil.buildFlowNew(NwConstants.INTERNAL_TUNNEL_TABLE,
ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(lportTag)),
getTunnelIdMatchForFilterEqualsLPortTag(lportTag),
getInstructionsInPortForOutGroup(interfaceInfo.getInterfaceName()));
- mdsalApiManager.addFlowToTx(dpId, flow, writeFlowGroupTx);
+ mdsalApiManager.addFlow(writeFlowGroupTx, dpId, flow);
LOG.debug("Terminating service table flow entry created on dpn:{} for logical Interface port:{}", dpId,
interfaceInfo.getPortName());
}
private void setupOrigDmacFlows(ElanInstance elanInfo, InterfaceInfo interfaceInfo, String macAddress,
boolean configureRemoteFlows, IMdsalApiManager mdsalApiManager,
- WriteTransaction writeFlowGroupTx) {
+ TypedWriteTransaction<Configuration> writeFlowGroupTx) {
BigInteger dpId = interfaceInfo.getDpId();
String ifName = interfaceInfo.getInterfaceName();
long ifTag = interfaceInfo.getInterfaceTag();
}
private void setupLocalDmacFlow(long elanTag, BigInteger dpId, String ifName, String macAddress,
- ElanInstance elanInfo, IMdsalApiManager mdsalApiManager, long ifTag, WriteTransaction writeFlowGroupTx) {
+ ElanInstance elanInfo, IMdsalApiManager mdsalApiManager, long ifTag,
+ TypedWriteTransaction<Configuration> writeFlowGroupTx) {
Flow flowEntity = buildLocalDmacFlowEntry(elanTag, dpId, ifName, macAddress, elanInfo, ifTag);
- mdsalApiManager.addFlowToTx(dpId, flowEntity, writeFlowGroupTx);
- installEtreeLocalDmacFlow(elanTag, dpId, ifName, macAddress, elanInfo,
- ifTag, writeFlowGroupTx);
+ mdsalApiManager.addFlow(writeFlowGroupTx, dpId, flowEntity);
+ installEtreeLocalDmacFlow(elanTag, dpId, ifName, macAddress, elanInfo, ifTag, writeFlowGroupTx);
}
private void installEtreeLocalDmacFlow(long elanTag, BigInteger dpId, String ifName, String macAddress,
- ElanInstance elanInfo, long ifTag, WriteTransaction writeFlowGroupTx) {
+ ElanInstance elanInfo, long ifTag, TypedWriteTransaction<Configuration> writeFlowGroupTx) {
EtreeInterface etreeInterface = elanInterfaceCache.getEtreeInterface(ifName).orNull();
if (etreeInterface != null && etreeInterface.getEtreeInterfaceType() == EtreeInterfaceType.Root) {
EtreeLeafTagName etreeTagName = elanEtreeUtils.getEtreeLeafTagByElanTag(elanTag);
} else {
Flow flowEntity = buildLocalDmacFlowEntry(etreeTagName.getEtreeLeafTag().getValue(), dpId, ifName,
macAddress, elanInfo, ifTag);
- mdsalManager.addFlowToTx(dpId, flowEntity, writeFlowGroupTx);
+ mdsalManager.addFlow(writeFlowGroupTx, dpId, flowEntity);
}
}
}
return flow;
}
- public void setupRemoteDmacFlow(BigInteger srcDpId, BigInteger destDpId, int lportTag, long elanTag, String
- macAddress, String displayName, WriteTransaction writeFlowGroupTx, String interfaceName, ElanInstance
- elanInstance) {
+ public void setupRemoteDmacFlow(BigInteger srcDpId, BigInteger destDpId, int lportTag, long elanTag,
+ String macAddress, String displayName, TypedWriteTransaction<Configuration> writeFlowGroupTx,
+ String interfaceName, ElanInstance elanInstance) {
if (interfaceManager.isExternalInterface(interfaceName)) {
LOG.debug("Ignoring install remote DMAC {} flow on provider interface {} elan {}",
macAddress, interfaceName, elanInstance.getElanInstanceName());
? getVxlanSegmentationId(elanInstance) : 0;
flowEntity = buildRemoteDmacFlowEntry(srcDpId, destDpId, lportTagOrVni, elanTag, macAddress, displayName,
elanInstance);
- mdsalManager.addFlowToTx(srcDpId, flowEntity, writeFlowGroupTx);
+ mdsalManager.addFlow(writeFlowGroupTx, srcDpId, flowEntity);
setupEtreeRemoteDmacFlow(srcDpId, destDpId, lportTagOrVni, elanTag, macAddress, displayName, interfaceName,
writeFlowGroupTx, elanInstance);
}
private void setupEtreeRemoteDmacFlow(BigInteger srcDpId, BigInteger destDpId, long lportTagOrVni, long elanTag,
String macAddress, String displayName, String interfaceName,
- WriteTransaction writeFlowGroupTx, ElanInstance elanInstance) {
+ TypedWriteTransaction<Configuration> writeFlowGroupTx,
+ ElanInstance elanInstance) {
Flow flowEntity;
EtreeInterface etreeInterface = elanInterfaceCache.getEtreeInterface(interfaceName).orNull();
if (etreeInterface != null && etreeInterface.getEtreeInterfaceType() == EtreeInterfaceType.Root) {
} else {
flowEntity = buildRemoteDmacFlowEntry(srcDpId, destDpId, lportTagOrVni,
etreeTagName.getEtreeLeafTag().getValue(), macAddress, displayName, elanInstance);
- mdsalManager.addFlowToTx(srcDpId, flowEntity, writeFlowGroupTx);
+ mdsalManager.addFlow(writeFlowGroupTx, srcDpId, flowEntity);
}
}
}
* the elan instance added
* @param elanInterfaces
* the elan interfaces
- * @param tx
+ * @param operTx
* transaction
*
* @return the updated ELAN instance.
*/
public static ElanInstance updateOperationalDataStore(IdManagerService idManager,
- ElanInstance elanInstanceAdded, List<String> elanInterfaces, WriteTransaction tx) {
+ ElanInstance elanInstanceAdded, List<String> elanInterfaces, TypedWriteTransaction<Configuration> confTx,
+ TypedWriteTransaction<Operational> operTx) {
String elanInstanceName = elanInstanceAdded.getElanInstanceName();
Long elanTag = elanInstanceAdded.getElanTag();
if (elanTag == null || elanTag == 0L) {
.withKey(new ElanKey(elanInstanceName)).build();
// Add the ElanState in the elan-state operational data-store
- tx.put(LogicalDatastoreType.OPERATIONAL, getElanInstanceOperationalDataPath(elanInstanceName),
- elanInfo, WriteTransaction.CREATE_MISSING_PARENTS);
+ operTx.put(getElanInstanceOperationalDataPath(elanInstanceName), elanInfo, CREATE_MISSING_PARENTS);
// Add the ElanMacTable in the elan-mac-table operational data-store
MacTable elanMacTable = new MacTableBuilder().withKey(new MacTableKey(elanInstanceName)).build();
- tx.put(LogicalDatastoreType.OPERATIONAL, getElanMacTableOperationalDataPath(elanInstanceName),
- elanMacTable, WriteTransaction.CREATE_MISSING_PARENTS);
+ operTx.put(getElanMacTableOperationalDataPath(elanInstanceName), elanMacTable, CREATE_MISSING_PARENTS);
ElanTagNameBuilder elanTagNameBuilder = new ElanTagNameBuilder().setElanTag(elanTag)
.withKey(new ElanTagNameKey(elanTag)).setName(elanInstanceName);
EtreeLeafTagName etreeLeafTagName = new EtreeLeafTagNameBuilder()
.setEtreeLeafTag(new EtreeLeafTag(etreeLeafTag)).build();
elanTagNameBuilder.addAugmentation(EtreeLeafTagName.class, etreeLeafTagName);
- addTheLeafTagAsElanTag(elanInstanceName, etreeLeafTag, tx);
+ addTheLeafTagAsElanTag(elanInstanceName, etreeLeafTag, operTx);
}
ElanTagName elanTagName = elanTagNameBuilder.build();
// Add the ElanTag to ElanName in the elan-tag-name Operational
// data-store
- tx.put(LogicalDatastoreType.OPERATIONAL,
- getElanInfoEntriesOperationalDataPath(elanTag), elanTagName);
+ operTx.put(getElanInfoEntriesOperationalDataPath(elanTag), elanTagName);
// Updates the ElanInstance Config DS by setting the just acquired
// elanTag
elanInstanceBuilder.addAugmentation(EtreeInstance.class, etreeInstance);
}
ElanInstance elanInstanceWithTag = elanInstanceBuilder.build();
- tx.merge(LogicalDatastoreType.CONFIGURATION, ElanHelper.getElanInstanceConfigurationDataPath(elanInstanceName),
- elanInstanceWithTag, WriteTransaction.CREATE_MISSING_PARENTS);
+ confTx.merge(ElanHelper.getElanInstanceConfigurationDataPath(elanInstanceName), elanInstanceWithTag,
+ CREATE_MISSING_PARENTS);
return elanInstanceWithTag;
}
- private static void addTheLeafTagAsElanTag(String elanInstanceName, long etreeLeafTag, WriteTransaction tx) {
+ private static void addTheLeafTagAsElanTag(String elanInstanceName, long etreeLeafTag,
+ TypedWriteTransaction<Operational> tx) {
ElanTagName etreeTagAsElanTag = new ElanTagNameBuilder().setElanTag(etreeLeafTag)
.withKey(new ElanTagNameKey(etreeLeafTag)).setName(elanInstanceName).build();
- tx.put(LogicalDatastoreType.OPERATIONAL,
- getElanInfoEntriesOperationalDataPath(etreeLeafTag), etreeTagAsElanTag);
+ tx.put(getElanInfoEntriesOperationalDataPath(etreeLeafTag), etreeTagAsElanTag);
}
private static boolean isEtreeInstance(ElanInstance elanInstanceAdded) {
return futures;
}
+ @CheckReturnValue
+ public static ListenableFuture<Void> waitForTransactionToComplete(ListenableFuture<Void> future) {
+ try {
+ future.get();
+ } catch (InterruptedException | ExecutionException e) {
+ // NETVIRT-1215: Do not log.error() here, only debug(); but callers *MUST* @CheckReturnValue
+ LOG.debug("Error writing to datastore", e);
+ }
+ return future;
+ }
+
public static boolean isVxlan(@Nullable ElanInstance elanInstance) {
return elanInstance != null && elanInstance.getSegmentType() != null
&& elanInstance.getSegmentType().isAssignableFrom(SegmentTypeVxlan.class)
IfTunnel ifTunnel = configIface.augmentation(IfTunnel.class);
if (ifTunnel != null && ifTunnel.getTunnelInterfaceType().isAssignableFrom(TunnelTypeVxlan.class)) {
ParentRefs refs = configIface.augmentation(ParentRefs.class);
- if (refs != null && !Strings.isNullOrEmpty(refs.getParentInterface())) {
- return true; //multiple VxLAN tunnels enabled, i.e. only logical tunnel should be treated
- }
+ return refs != null && !Strings.isNullOrEmpty(refs.getParentInterface());
}
return false;
}
*/
package org.opendaylight.netvirt.elan.utils;
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+
import com.google.common.base.Optional;
import com.google.common.collect.MapDifference;
import com.google.common.collect.MapDifference.ValueDifference;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
+import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
-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.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
+import org.opendaylight.genius.infra.Datastore.Configuration;
import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.genius.infra.TypedReadTransaction;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
+import org.opendaylight.genius.infra.TypedWriteTransaction;
import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
import org.opendaylight.netvirt.elan.cache.ElanInstanceCache;
import org.opendaylight.netvirt.elan.internal.ElanBridgeManager;
private static final String ALL_SUBNETS_GW = "0.0.0.0";
private static final String ALL_SUBNETS = "0.0.0.0/0";
private final ManagedNewTransactionRunner txRunner;
+ private final SingleTransactionDataBroker singleTxBroker;
private final SouthboundUtils southBoundUtils;
private final IElanService elanService;
private final ElanConfig elanConfig;
final IElanService elanService, final ElanConfig elanConfig, final ElanBridgeManager elanBridgeManager,
final ElanInstanceCache elanInstanceCache) {
this.txRunner = new ManagedNewTransactionRunnerImpl(dbx);
+ this.singleTxBroker = new SingleTransactionDataBroker(dbx);
this.elanService = elanService;
this.elanConfig = elanConfig;
this.elanBridgeManager = elanBridgeManager;
return tzb.build();
}
- private void updateTransportZone(TransportZone zone, BigInteger dpnId, @Nonnull WriteTransaction tx) {
+ private void updateTransportZone(TransportZone zone, BigInteger dpnId,
+ @Nonnull TypedWriteTransaction<Configuration> tx) {
InstanceIdentifier<TransportZone> path = InstanceIdentifier.builder(TransportZones.class)
.child(TransportZone.class, new TransportZoneKey(zone.getZoneName())).build();
- tx.merge(LogicalDatastoreType.CONFIGURATION, path, zone);
+ tx.merge(path, zone);
LOG.info("Transport zone {} updated due to dpn {} handling.", zone.getZoneName(), dpnId);
}
public void updateTransportZone(String zoneNamePrefix, BigInteger dpnId) {
- ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(tx -> {
- Map<String, String> localIps = getDpnLocalIps(dpnId, tx);
+ ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
+ Map<String, String> localIps = getDpnLocalIps(dpnId);
if (!localIps.isEmpty()) {
LOG.debug("Will use local_ips for transport zone update for dpn {} and zone name prefix {}", dpnId,
zoneNamePrefix);
updateTransportZone(zoneName, dpnId, localIp, tx);
}
} else {
- updateTransportZone(zoneNamePrefix, dpnId, getDpnLocalIp(dpnId, tx), tx);
+ updateTransportZone(zoneNamePrefix, dpnId, getDpnLocalIp(dpnId), tx);
}
}), LOG, "Error updating transport zone");
}
@SuppressWarnings("checkstyle:IllegalCatch")
private void updateTransportZone(String zoneName, BigInteger dpnId, @Nullable String localIp,
- @Nonnull ReadWriteTransaction tx) throws ReadFailedException {
+ @Nonnull TypedReadWriteTransaction<Configuration> tx)
+ throws ExecutionException, InterruptedException {
InstanceIdentifier<TransportZone> inst = InstanceIdentifier.create(TransportZones.class)
.child(TransportZone.class, new TransportZoneKey(zoneName));
// FIXME: Read this through a cache
- TransportZone zone = tx.read(LogicalDatastoreType.CONFIGURATION, inst).checkedGet().orNull();
+ TransportZone zone = tx.read(inst).get().orNull();
if (zone == null) {
zone = createZone(ALL_SUBNETS, zoneName);
}
}
- private void deleteTransportZone(TransportZone zone, BigInteger dpnId, @Nonnull WriteTransaction tx) {
+ private void deleteTransportZone(TransportZone zone, BigInteger dpnId,
+ @Nonnull TypedWriteTransaction<Configuration> tx) {
InstanceIdentifier<TransportZone> path = InstanceIdentifier.builder(TransportZones.class)
.child(TransportZone.class, new TransportZoneKey(zone.getZoneName())).build();
- tx.delete(LogicalDatastoreType.CONFIGURATION, path);
+ tx.delete(path);
LOG.info("Transport zone {} deleted due to dpn {} handling.", zone.getZoneName(), dpnId);
}
public void deleteTransportZone(String zoneNamePrefix, BigInteger dpnId) {
- ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(tx -> {
- Map<String, String> localIps = getDpnLocalIps(dpnId, tx);
+ ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
+ Map<String, String> localIps = getDpnLocalIps(dpnId);
if (!localIps.isEmpty()) {
LOG.debug("Will use local_ips for transport zone delete for dpn {} and zone name prefix {}", dpnId,
zoneNamePrefix);
}
@SuppressWarnings("checkstyle:IllegalCatch")
- private void deleteTransportZone(String zoneName, BigInteger dpnId, @Nonnull ReadWriteTransaction tx)
- throws ReadFailedException {
+ private void deleteTransportZone(String zoneName, BigInteger dpnId,
+ @Nonnull TypedReadWriteTransaction<Configuration> tx) throws ExecutionException, InterruptedException {
InstanceIdentifier<TransportZone> inst = InstanceIdentifier.create(TransportZones.class)
.child(TransportZone.class, new TransportZoneKey(zoneName));
// FIXME: Read this through a cache
- TransportZone zone = tx.read(LogicalDatastoreType.CONFIGURATION, inst).checkedGet().orNull();
+ TransportZone zone = tx.read(inst).get().orNull();
if (zone != null) {
try {
deleteTransportZone(zone, dpnId, tx);
return;
}
- ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(tx -> {
+ ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
BigInteger dpId = dpIdOpt.get();
Optional<DPNTEPsInfo> dpnTepsInfoOpt = getDpnTepsInfo(dpId, tx);
if (!dpnTepsInfoOpt.isPresent()) {
}
private void handleAddedLocalIps(Map<String, String> addedEntries, BigInteger dpId, Set<String> zonePrefixes,
- ReadWriteTransaction tx) throws ReadFailedException {
+ TypedReadWriteTransaction<Configuration> tx) throws ExecutionException, InterruptedException {
if (addedEntries == null || addedEntries.isEmpty()) {
LOG.trace("No added local_ips found for DPN {}", dpId);
return;
}
private void handleChangedLocalIps(Map<String, ValueDifference<String>> changedEntries, BigInteger dpId,
- Set<String> zonePrefixes, Map<String, List<String>> tepTzMap, @Nonnull ReadWriteTransaction tx)
- throws ReadFailedException {
+ Set<String> zonePrefixes, Map<String, List<String>> tepTzMap,
+ @Nonnull TypedReadWriteTransaction<Configuration> tx) throws ExecutionException, InterruptedException {
if (changedEntries == null || changedEntries.isEmpty()) {
LOG.trace("No changed local_ips found for DPN {}", dpId);
return;
}
private void handleRemovedLocalIps(Map<String, String> removedEntries, BigInteger dpId, Set<String> zonePrefixes,
- Map<String, List<String>> tepTzMap, @Nonnull WriteTransaction tx) {
+ Map<String, List<String>> tepTzMap, @Nonnull TypedWriteTransaction<Configuration> tx) {
if (removedEntries == null || removedEntries.isEmpty()) {
LOG.trace("No removed local_ips found on DPN {}", dpId);
return;
.collect(Collectors.toList());
}
- private Optional<DPNTEPsInfo> getDpnTepsInfo(BigInteger dpId, ReadTransaction tx) {
+ private Optional<DPNTEPsInfo> getDpnTepsInfo(BigInteger dpId, TypedReadTransaction<Configuration> tx) {
InstanceIdentifier<DPNTEPsInfo> identifier = InstanceIdentifier.builder(DpnEndpoints.class)
.child(DPNTEPsInfo.class, new DPNTEPsInfoKey(dpId)).build();
try {
- return tx.read(LogicalDatastoreType.CONFIGURATION, identifier).checkedGet();
- } catch (ReadFailedException e) {
+ return tx.read(identifier).get();
+ } catch (InterruptedException | ExecutionException e) {
LOG.warn("Failed to read DPNTEPsInfo for DPN id {}", dpId);
return Optional.absent();
}
return false;
}
- private void removeVtep(String zoneName, BigInteger dpId, @Nonnull WriteTransaction tx) {
+ private void removeVtep(String zoneName, BigInteger dpId, @Nonnull TypedWriteTransaction<Configuration> tx) {
InstanceIdentifier<Vteps> path = InstanceIdentifier.builder(TransportZones.class)
.child(TransportZone.class, new TransportZoneKey(zoneName))
.child(Subnets.class, new SubnetsKey(IpPrefixBuilder.getDefaultInstance(ALL_SUBNETS)))
.child(Vteps.class, new VtepsKey(dpId, TUNNEL_PORT)).build();
- tx.delete(LogicalDatastoreType.CONFIGURATION, path);
+ tx.delete(path);
}
// search for relevant subnets for the given subnetIP, add one if it is
return subnetsBuilder.build();
}
- private String getDpnLocalIp(BigInteger dpId, ReadTransaction tx) throws ReadFailedException {
- Optional<Node> node = getPortsNode(dpId, tx);
+ private String getDpnLocalIp(BigInteger dpId) throws ReadFailedException {
+ Optional<Node> node = getPortsNode(dpId);
if (node.isPresent()) {
String localIp = southBoundUtils.getOpenvswitchOtherConfig(node.get(), LOCAL_IP);
}
@Nonnull
- private Map<String, String> getDpnLocalIps(BigInteger dpId, ReadTransaction tx) throws ReadFailedException {
+ private Map<String, String> getDpnLocalIps(BigInteger dpId) throws ReadFailedException {
// Example of local IPs from other_config:
// local_ips="10.0.43.159:MPLS,11.11.11.11:DSL,ip:underlay-network"
- return getPortsNode(dpId, tx).toJavaUtil().map(
+ return getPortsNode(dpId).toJavaUtil().map(
node -> elanBridgeManager.getOpenvswitchOtherConfigMap(node, LOCAL_IPS)).orElse(Collections.emptyMap());
}
@SuppressWarnings("unchecked")
- private Optional<Node> getPortsNode(BigInteger dpnId, ReadTransaction tx) throws ReadFailedException {
+ private Optional<Node> getPortsNode(BigInteger dpnId) throws ReadFailedException {
InstanceIdentifier<BridgeRefEntry> bridgeRefInfoPath = InstanceIdentifier.create(BridgeRefInfo.class)
.child(BridgeRefEntry.class, new BridgeRefEntryKey(dpnId));
// FIXME: Read this through a cache
Optional<BridgeRefEntry> optionalBridgeRefEntry =
- tx.read(LogicalDatastoreType.OPERATIONAL, bridgeRefInfoPath).checkedGet();
+ singleTxBroker.syncReadOptional(LogicalDatastoreType.OPERATIONAL, bridgeRefInfoPath);
if (!optionalBridgeRefEntry.isPresent()) {
LOG.error("no bridge ref entry found for dpnId {}", dpnId);
return Optional.absent();
optionalBridgeRefEntry.get().getBridgeReference().getValue().firstIdentifierOf(Node.class);
// FIXME: Read this through a cache
- Optional<Node> optionalNode = tx.read(LogicalDatastoreType.OPERATIONAL, nodeId).checkedGet();
+ Optional<Node> optionalNode = singleTxBroker.syncReadOptional(LogicalDatastoreType.OPERATIONAL, nodeId);
if (!optionalNode.isPresent()) {
LOG.error("missing node for dpnId {}", dpnId);
}
*/
package org.opendaylight.netvirt.elan.l2gw.nodehandlertest;
-import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.CONFIGURATION;
-import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.OPERATIONAL;
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+import static org.opendaylight.genius.infra.Datastore.OPERATIONAL;
import com.google.common.base.Optional;
import java.util.UUID;
import org.junit.Test;
import org.mockito.Mockito;
import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
import org.opendaylight.controller.md.sal.binding.test.AbstractConcurrentDataBrokerTest;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
import org.opendaylight.genius.utils.hwvtep.HwvtepNodeHACache;
import org.opendaylight.netvirt.elan.l2gw.ha.handlers.NodeConnectedHandler;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
@Test
public void testD1Connect() throws Exception {
- ReadWriteTransaction tx = getDataBroker().newReadWriteTransaction();
- handlerUtils.addPsNode(d1PsNodePath, d1NodePath, DataProvider.getPortNameListD1(), tx).checkedGet();
+ ManagedNewTransactionRunner txRunner = new ManagedNewTransactionRunnerImpl(getDataBroker());
+ txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL,
+ tx -> handlerUtils.addPsNode(d1PsNodePath, d1NodePath, DataProvider.getPortNameListD1(), tx)).get();
- tx = getDataBroker().newReadWriteTransaction();
- handlerUtils.addNode(d1NodePath, d1PsNodePath, DataProvider.getLogicalSwitchDataD1(),
+ txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL,
+ tx -> handlerUtils.addNode(d1NodePath, d1PsNodePath, DataProvider.getLogicalSwitchDataD1(),
DataProvider.getLocalUcasMacDataD1(), DataProvider.getLocalMcastDataD1(),
DataProvider.getRemoteMcastDataD1(), DataProvider.getRemoteUcasteMacDataD1(),
- DataProvider.getGlobalTerminationPointIpD1(), tx).checkedGet();
+ DataProvider.getGlobalTerminationPointIpD1(), tx)).get();
readNodes();
- tx = getDataBroker().newReadWriteTransaction();
- nodeConnectedHandler.handleNodeConnected(d1GlobalOpNode.get(), d1NodePath, haNodePath, haGlobalConfigNode,
- haPsConfigNode, tx);
- tx.submit().checkedGet();
+ txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION,
+ confTx -> txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL,
+ operTx -> nodeConnectedHandler.handleNodeConnected(d1GlobalOpNode.get(), d1NodePath, haNodePath,
+ haGlobalConfigNode, haPsConfigNode, confTx, operTx)).get()).get();
readNodes();
//verify global ha manager config should have ha_children
- Assert.assertTrue(haGlobalConfigNode.isPresent() && d1GlobalOpNode.isPresent());
+ Assert.assertTrue(haGlobalConfigNode.isPresent());
+ Assert.assertTrue(d1GlobalOpNode.isPresent());
TestUtil.verifyHAconfigNode(haGlobalConfigNode.get(), d1GlobalOpNode.get());
- Assert.assertTrue(d1GlobalOpNode.isPresent() && haGlobalOpNode.isPresent() && d1PsOpNode.isPresent()
- && haPsOpNode.isPresent());
+ Assert.assertTrue(d1GlobalOpNode.isPresent());
+ Assert.assertTrue(haGlobalOpNode.isPresent());
+ Assert.assertTrue(d1PsOpNode.isPresent());
+ Assert.assertTrue(haPsOpNode.isPresent());
TestUtil.verifyHAOpNode(d1GlobalOpNode.get(), haGlobalOpNode.get(),
- d1PsOpNode.get(), haPsOpNode.get(), haNodePath, d1PsNodePath, haPsNodePath, haNodeId, getDataBroker());
+ d1PsOpNode.get(), haPsOpNode.get(), haNodePath, d1PsNodePath, haPsNodePath, getDataBroker());
}
public static InstanceIdentifier<Node> createInstanceIdentifier(String nodeIdString) {
public void readNodes() throws Exception {
ReadOnlyTransaction tx = getDataBroker().newReadOnlyTransaction();
- d1GlobalOpNode = TestUtil.readNode(OPERATIONAL, d1NodePath, tx);
- d2GlobalOpNode = TestUtil.readNode(OPERATIONAL, d2NodePath, tx);
- haGlobalOpNode = TestUtil.readNode(OPERATIONAL, haNodePath, tx);
+ d1GlobalOpNode = TestUtil.readNode(LogicalDatastoreType.OPERATIONAL, d1NodePath, tx);
+ d2GlobalOpNode = TestUtil.readNode(LogicalDatastoreType.OPERATIONAL, d2NodePath, tx);
+ haGlobalOpNode = TestUtil.readNode(LogicalDatastoreType.OPERATIONAL, haNodePath, tx);
- d1PsOpNode = TestUtil.readNode(OPERATIONAL, d1PsNodePath, tx);
- d2PsOpNode = TestUtil.readNode(OPERATIONAL, d2PsNodePath, tx);
- haPsOpNode = TestUtil.readNode(OPERATIONAL, haPsNodePath, tx);
+ d1PsOpNode = TestUtil.readNode(LogicalDatastoreType.OPERATIONAL, d1PsNodePath, tx);
+ d2PsOpNode = TestUtil.readNode(LogicalDatastoreType.OPERATIONAL, d2PsNodePath, tx);
+ haPsOpNode = TestUtil.readNode(LogicalDatastoreType.OPERATIONAL, haPsNodePath, tx);
- haGlobalConfigNode = TestUtil.readNode(CONFIGURATION, haNodePath, tx);
- d1GlobalConfigNode = TestUtil.readNode(CONFIGURATION, d1NodePath, tx);
- d2GlobalConfigNode = TestUtil.readNode(CONFIGURATION, d2NodePath, tx);
+ haGlobalConfigNode = TestUtil.readNode(LogicalDatastoreType.CONFIGURATION, haNodePath, tx);
+ d1GlobalConfigNode = TestUtil.readNode(LogicalDatastoreType.CONFIGURATION, d1NodePath, tx);
+ d2GlobalConfigNode = TestUtil.readNode(LogicalDatastoreType.CONFIGURATION, d2NodePath, tx);
- haPsConfigNode = TestUtil.readNode(CONFIGURATION, haPsNodePath, tx);
- d1PsConfigNode = TestUtil.readNode(CONFIGURATION, d1PsNodePath, tx);
- d2PsConfigNode = TestUtil.readNode(CONFIGURATION, d2PsNodePath, tx);
+ haPsConfigNode = TestUtil.readNode(LogicalDatastoreType.CONFIGURATION, haPsNodePath, tx);
+ d1PsConfigNode = TestUtil.readNode(LogicalDatastoreType.CONFIGURATION, d1PsNodePath, tx);
+ d2PsConfigNode = TestUtil.readNode(LogicalDatastoreType.CONFIGURATION, d2PsNodePath, tx);
tx.close();
}
*/
package org.opendaylight.netvirt.elan.l2gw.nodehandlertest;
-import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.OPERATIONAL;
+import static org.opendaylight.controller.md.sal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
-import com.google.common.util.concurrent.CheckedFuture;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.genius.infra.Datastore.Operational;
+import org.opendaylight.genius.infra.TypedWriteTransaction;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
*/
public class NodeConnectedHandlerUtils {
- CheckedFuture<Void, TransactionCommitFailedException> addNode(InstanceIdentifier<Node> path,
+ void addNode(InstanceIdentifier<Node> path,
InstanceIdentifier<Node> psPath, String logicalSwitchData, String localUcasMacData, String localMcastData,
String remoteMcastData, String remoteUcasteMacData, String globalTerminationPointIp,
- WriteTransaction transaction) throws Exception {
- NodeBuilder nodeBuilder = null;
- HwvtepGlobalAugmentationBuilder augmentationBuilder = null;
- nodeBuilder = prepareOperationalNode(path);
- augmentationBuilder = prepareAugmentationBuilder();
+ TypedWriteTransaction<Operational> tx) {
+ NodeBuilder nodeBuilder = prepareOperationalNode(path);
+ HwvtepGlobalAugmentationBuilder augmentationBuilder = prepareAugmentationBuilder();
GlobalAugmentationHelper.addLogicalSwitches(augmentationBuilder, getData(logicalSwitchData));
nodeBuilder.addAugmentation(HwvtepGlobalAugmentation.class, augmentationBuilder.build());
- return TestUtil.submitNode(OPERATIONAL, path, nodeBuilder.build(), transaction);
+ tx.put(path, nodeBuilder.build());
}
- CheckedFuture<Void, TransactionCommitFailedException> addPsNode(InstanceIdentifier<Node> path,
- InstanceIdentifier<Node> parentPath, List<String> portNameList, WriteTransaction transaction)
- throws Exception {
- NodeBuilder nodeBuilder = null;
-
- nodeBuilder = prepareOperationalNode(path);
+ void addPsNode(InstanceIdentifier<Node> path, InstanceIdentifier<Node> parentPath, List<String> portNameList,
+ TypedWriteTransaction<Operational> tx) {
PhysicalSwitchAugmentationBuilder physicalSwitchAugmentationBuilder = new PhysicalSwitchAugmentationBuilder();
physicalSwitchAugmentationBuilder.setManagedBy(new HwvtepGlobalRef(parentPath));
physicalSwitchAugmentationBuilder.setPhysicalSwitchUuid(getUUid("d1s3"));
tunnelIps.add(new TunnelIpsBuilder().withKey(new TunnelIpsKey(ip)).setTunnelIpsKey(ip).build());
physicalSwitchAugmentationBuilder.setTunnelIps(tunnelIps);
+ NodeBuilder nodeBuilder = prepareOperationalNode(path);
nodeBuilder.addAugmentation(PhysicalSwitchAugmentation.class, physicalSwitchAugmentationBuilder.build());
PhysicalSwitchHelper.dId = parentPath;
nodeBuilder.setTerminationPoint(PhysicalSwitchHelper
- .addPhysicalSwitchTerminationPoints(path, transaction, portNameList));
+ .addPhysicalSwitchTerminationPoints(path, portNameList));
- return TestUtil.submitNode(OPERATIONAL, path, nodeBuilder.build(), transaction);
+ tx.put(path, nodeBuilder.build(), CREATE_MISSING_PARENTS);
}
- NodeBuilder prepareOperationalNode(InstanceIdentifier<Node> iid) {
+ private NodeBuilder prepareOperationalNode(InstanceIdentifier<Node> iid) {
NodeBuilder nodeBuilder = new NodeBuilder();
nodeBuilder.setNodeId(iid.firstKeyOf(Node.class).getNodeId());
return nodeBuilder;
}
- HwvtepGlobalAugmentationBuilder prepareAugmentationBuilder() {
+ private HwvtepGlobalAugmentationBuilder prepareAugmentationBuilder() {
HwvtepGlobalAugmentationBuilder builder = new HwvtepGlobalAugmentationBuilder();
builder.setManagers(TestBuilders.buildManagers());
return builder;
}
- public List<String> getData(String data) {
+ private List<String> getData(String data) {
return Arrays.asList(data.split(","));
}
import java.util.List;
import java.util.Map;
import java.util.UUID;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.genius.utils.hwvtep.HwvtepSouthboundConstants;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
* Created by eaksahu on 8/8/2016.
*/
public final class PhysicalSwitchHelper {
- static Logger LOG = LoggerFactory.getLogger(PhysicalSwitchHelper.class);
-
static InstanceIdentifier<Node> dId;
private PhysicalSwitchHelper() { }
.build();
}
- public static List<TerminationPoint> addPhysicalSwitchTerminationPoints(InstanceIdentifier<Node> switchIid,
- WriteTransaction transaction,
- List<String> portNames) {
+ static List<TerminationPoint> addPhysicalSwitchTerminationPoints(InstanceIdentifier<Node> switchIid,
+ List<String> portNames) {
List<TerminationPoint> tps = new ArrayList<>();
for (String portName : portNames) {
- tps.add(buildTerminationPointForPhysicalSwitch(switchIid, portName, transaction, getVlanBindingData(1)));
+ tps.add(buildTerminationPointForPhysicalSwitch(switchIid, portName, getVlanBindingData(1)));
}
return tps;
}
- public static TerminationPoint buildTerminationPointForPhysicalSwitch(InstanceIdentifier<Node> switchIid,
- String portName, WriteTransaction transaction,
- Map<Long, String> vlanBindingData) {
+ private static TerminationPoint buildTerminationPointForPhysicalSwitch(InstanceIdentifier<Node> switchIid,
+ String portName, Map<Long, String> vlanBindingData) {
TerminationPointKey tpKey = new TerminationPointKey(new TpId(portName));
TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
tpBuilder.withKey(tpKey);
tpBuilder.setTpId(tpKey.getTpId());
switchIid.firstKeyOf(Node.class);
- InstanceIdentifier<TerminationPoint> tpPath = switchIid.child(TerminationPoint.class,
- new TerminationPointKey(new TpId(portName)));
HwvtepPhysicalPortAugmentationBuilder tpAugmentationBuilder =
new HwvtepPhysicalPortAugmentationBuilder();
buildTerminationPoint(tpAugmentationBuilder, portName, vlanBindingData);
return tpBuilder.build();
}
- public static void buildTerminationPoint(HwvtepPhysicalPortAugmentationBuilder tpAugmentationBuilder,
- String portName, Map<Long, String> vlanBindingData) {
+ private static void buildTerminationPoint(HwvtepPhysicalPortAugmentationBuilder tpAugmentationBuilder,
+ String portName, Map<Long, String> vlanBindingData) {
updatePhysicalPortId(portName, tpAugmentationBuilder);
- updatePort(portName, tpAugmentationBuilder, vlanBindingData);
+ updatePort(tpAugmentationBuilder, vlanBindingData);
}
- public static void updatePhysicalPortId(String portName,
- HwvtepPhysicalPortAugmentationBuilder tpAugmentationBuilder) {
+ private static void updatePhysicalPortId(String portName,
+ HwvtepPhysicalPortAugmentationBuilder tpAugmentationBuilder) {
tpAugmentationBuilder.setHwvtepNodeName(new HwvtepNodeName(portName));
tpAugmentationBuilder.setHwvtepNodeDescription("");
}
- public static void updatePort(String portName, HwvtepPhysicalPortAugmentationBuilder tpAugmentationBuilder,
- Map<Long, String> vlanBindings) {
+ private static void updatePort(HwvtepPhysicalPortAugmentationBuilder tpAugmentationBuilder,
+ Map<Long, String> vlanBindings) {
updateVlanBindings(vlanBindings, tpAugmentationBuilder);
tpAugmentationBuilder.setPhysicalPortUuid(new Uuid(UUID.randomUUID().toString()));
}
- public static void updateVlanBindings(Map<Long, String> vlanBindings,
- HwvtepPhysicalPortAugmentationBuilder tpAugmentationBuilder) {
+ private static void updateVlanBindings(Map<Long, String> vlanBindings,
+ HwvtepPhysicalPortAugmentationBuilder tpAugmentationBuilder) {
List<VlanBindings> vlanBindingsList = new ArrayList<>();
for (Map.Entry<Long, String> vlanBindingEntry : vlanBindings.entrySet()) {
Long vlanBindingKey = vlanBindingEntry.getKey();
tpAugmentationBuilder.setVlanBindings(vlanBindingsList);
}
- public static VlanBindings createVlanBinding(Long key, String logicalSwitch) {
+ private static VlanBindings createVlanBinding(Long key, String logicalSwitch) {
VlanBindingsBuilder vbBuilder = new VlanBindingsBuilder();
VlanBindingsKey vbKey = new VlanBindingsKey(new VlanId(key.intValue()));
vbBuilder.withKey(vbKey);
return vbBuilder.build();
}
- public static InstanceIdentifier<LogicalSwitches> createInstanceIdentifier(String logicalSwitch) {
+ private static InstanceIdentifier<LogicalSwitches> createInstanceIdentifier(String logicalSwitch) {
NodeId id = dId.firstKeyOf(Node.class).getNodeId();
NodeKey nodeKey = new NodeKey(id);
- InstanceIdentifier<LogicalSwitches> iid = null;
- iid = InstanceIdentifier.builder(NetworkTopology.class)
+ return InstanceIdentifier.builder(NetworkTopology.class)
.child(Topology.class, new TopologyKey(HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID))
.child(Node.class, nodeKey).augmentation(HwvtepGlobalAugmentation.class)
.child(LogicalSwitches.class, new LogicalSwitchesKey(new HwvtepNodeName(logicalSwitch)))
.build();
- return iid;
}
- public static Map<Long, String> getVlanBindingData(int mapSize) {
+ private static Map<Long, String> getVlanBindingData(int mapSize) {
Map<Long, String> vlanBindings = new HashMap<>();
- for (Integer i = 0; i < mapSize; i++) {
+ for (long i = 0; i < mapSize; i++) {
i = i * 100;
- vlanBindings.put(Long.valueOf(i), "9227c228-6bba-4bbe-bdb8-6942768ff0f1");
+ vlanBindings.put(i, "9227c228-6bba-4bbe-bdb8-6942768ff0f1");
}
return vlanBindings;
}
package org.opendaylight.netvirt.elan.l2gw.nodehandlertest;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.OPERATIONAL;
import com.google.common.base.Optional;
-import com.google.common.util.concurrent.CheckedFuture;
-import java.util.Arrays;
-import java.util.List;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
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.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
* Created by eaksahu on 8/12/2016.
*/
-public final class TestUtil {
- static Logger LOG = LoggerFactory.getLogger(TestUtil.class);
+final class TestUtil {
private TestUtil() { }
- public static void deleteNode(ReadWriteTransaction tx, InstanceIdentifier<Node> id) throws Exception {
- tx.delete(OPERATIONAL, id);
- tx.submit().checkedGet();
- }
-
- public static void verifyHAOpNode(Node d1GlobalOpNode, Node haGlobalOpNode, Node d1PsOpNode, Node haPsOpNode,
- InstanceIdentifier<Node> haId, InstanceIdentifier<Node> d1PsId,
- InstanceIdentifier<Node> haPsId, NodeId haNodeId, DataBroker dataBroker)
- throws ReadFailedException {
+ static void verifyHAOpNode(Node d1GlobalOpNode, Node haGlobalOpNode, Node d1PsOpNode, Node haPsOpNode,
+ InstanceIdentifier<Node> haId, InstanceIdentifier<Node> d1PsId, InstanceIdentifier<Node> haPsId,
+ DataBroker dataBroker) throws ReadFailedException {
ReadWriteTransaction transaction = dataBroker.newReadWriteTransaction();
TestComparators.compareLogicalSwitches(d1GlobalOpNode, haGlobalOpNode, haId);
TestComparators.compareRemoteUcastMacs(d1GlobalOpNode, haGlobalOpNode, haId);
d1GlobalOpNode, haGlobalOpNode);
}
- public static void verifyHAOpNode(Node d1GlobalOpNode, Node d2GlobalOpNode, Node haGlobalOpNode,
- Node d1PsOpNode, Node d2PsOpNode, Node haPsOpNode,
- InstanceIdentifier<Node> haId, InstanceIdentifier<Node> d1PsId,
- InstanceIdentifier<Node> d2PsId, InstanceIdentifier<Node> haPsId,
- NodeId haNodeId, DataBroker dataBroker) throws ReadFailedException {
- ReadWriteTransaction transaction = dataBroker.newReadWriteTransaction();
- TestComparators.compareLogicalSwitches(d1GlobalOpNode, d2GlobalOpNode, haGlobalOpNode, haId);
- TestComparators.compareRemoteUcastMacs(d1GlobalOpNode, d2GlobalOpNode, haGlobalOpNode, haId);
- TestComparators.compareRemoteMcastMacs(d1GlobalOpNode, d2GlobalOpNode, haGlobalOpNode, haId);
- TestComparators.compareLocalUcastMacs(d1GlobalOpNode, d2GlobalOpNode, haGlobalOpNode, haId);
- TestComparators.compareLocalMcastMacs(d1GlobalOpNode, d2GlobalOpNode, haGlobalOpNode, haId);
- TestComparators.verifySwitches(haGlobalOpNode, haPsOpNode);
- TestComparators.verifySwitches(d1GlobalOpNode, d1PsOpNode);
- TestComparators.verifySwitches(d2GlobalOpNode, d2PsOpNode);
- TestComparators.comparePhysicalSwitches(d1PsOpNode, d2PsOpNode, haPsOpNode, d1PsId, d2PsId, haPsId,
- transaction, "s3", d1GlobalOpNode, d2GlobalOpNode, haGlobalOpNode);
- }
-
- public static Node readNode(LogicalDatastoreType datastoreType, InstanceIdentifier<Node> id, DataBroker dataBroker)
- throws Exception {
- if (dataBroker.newReadWriteTransaction().read(datastoreType, id).checkedGet().isPresent()) {
- return dataBroker.newReadWriteTransaction().read(datastoreType, id).checkedGet().get();
- }
- return null;
- }
-
- public static Optional<Node> readNode(LogicalDatastoreType datastoreType, InstanceIdentifier<Node> id,
- ReadOnlyTransaction tx) throws Exception {
+ static Optional<Node> readNode(LogicalDatastoreType datastoreType, InstanceIdentifier<Node> id,
+ ReadOnlyTransaction tx) throws Exception {
return tx.read(datastoreType, id).checkedGet();
}
- static void updateNode(LogicalDatastoreType datastoreType, InstanceIdentifier<Node> id, Node node,
- DataBroker dataBroker) throws Exception {
- WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
- transaction.merge(datastoreType, id, node, WriteTransaction.CREATE_MISSING_PARENTS);
- transaction.submit();
- }
-
-
- static CheckedFuture<Void, TransactionCommitFailedException> submitNode(LogicalDatastoreType datastoreType,
- InstanceIdentifier<Node> id, Node node, WriteTransaction transaction) throws Exception {
- transaction.put(datastoreType, id, node, WriteTransaction.CREATE_MISSING_PARENTS);
- return transaction.submit();
- }
- static Optional<Node> readNodeOptional(LogicalDatastoreType datastoreType, InstanceIdentifier<Node> id,
- DataBroker dataBroker) throws Exception {
- return dataBroker.newReadWriteTransaction().read(datastoreType, id).checkedGet();
- }
-
- public static void verifyHaAfterDelete(InstanceIdentifier<Node> nodeId, LogicalDatastoreType datastoreType,
- String message, DataBroker dataBroker) throws Exception {
- Optional<Node> nodeOptional = TestUtil.readNodeOptional(datastoreType, nodeId, dataBroker);
- if (!message.contains("D2")) {
- assertTrue(message, nodeOptional.isPresent());
- } else {
- assertFalse(message, nodeOptional.isPresent());
- }
- if (nodeOptional.isPresent()) {
- LOG.info("Node data{}", nodeOptional.get());
- }
- }
-
- public static void verifyHAconfigNode(InstanceIdentifier<Node> nodeId, DataBroker dataBroker, String message)
- throws Exception {
- Optional<Node> nodeOptional = TestUtil.readNodeOptional(LogicalDatastoreType.CONFIGURATION, nodeId, dataBroker);
- assertTrue(message, nodeOptional.isPresent());
- if (nodeOptional.isPresent()) {
- nodeOptional.get().augmentation(HwvtepGlobalAugmentation.class).getManagers();
- }
- }
-
- public static void verifyHAconfigNode(Node haConfig, Node d1Node) throws Exception {
+ static void verifyHAconfigNode(Node haConfig, Node d1Node) {
String haid = haConfig.augmentation(HwvtepGlobalAugmentation.class).getManagers()
.get(0).getManagerOtherConfigs().get(0).getOtherConfigValue();
String d1id = d1Node.getNodeId().getValue();
assertEquals("Other config should contain D1 as child manager", haid, d1id);
}
-
- public static void verifyHAconfigNode(Node haConfig, Node d1Node, Node d2Node) throws Exception {
- String haid = haConfig.augmentation(HwvtepGlobalAugmentation.class).getManagers()
- .get(0).getManagerOtherConfigs().get(0).getOtherConfigValue();
- String[] haids = haid.split(",");
- List<String> haidSlist = Arrays.asList(haids);
- assertEquals("Ha Other config size should be 2 after creationg of D2 Node", 2, haids.length);
- String d1id = d1Node.getNodeId().getValue();
- String d2id = d2Node.getNodeId().getValue();
- assertTrue("ha should contain d1/d2 id as other config", haidSlist.contains(d1id));
- assertTrue("ha should contain d1/d2 id as other config", haidSlist.contains(d2id));
- }
-
}
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.Ordered;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
/*ELAN1+":"+DPN1MAC1 ->
(vlanInterfaceInfo(String interfaceName, BigInteger dpId, int portNo, int lportTag, String mac), vmPrefix)*/
ELAN_INTERFACES.put(ELAN1 + ":" + DPN1MAC1 ,
- new ImmutablePair(InterfaceHelper
+ ImmutablePair.of(InterfaceHelper
.buildVlanInterfaceInfo("23701c04-1118-4c65-9425-78a80d49a211",
DPN1_ID, 1, 10, DPN1MAC1), DPN1IP1));
ELAN_INTERFACES.put(ELAN1 + ":" + DPN1MAC2 ,
- new ImmutablePair(InterfaceHelper
+ ImmutablePair.of(InterfaceHelper
.buildVlanInterfaceInfo("23701c04-1218-4c65-9425-78a80d49a211",
DPN1_ID, 2, 11, DPN1MAC2), DPN1IP2));
ELAN_INTERFACES.put(ELAN1 + ":" + DPN2MAC1 ,
- new ImmutablePair(InterfaceHelper
+ ImmutablePair.of(InterfaceHelper
.buildVlanInterfaceInfo("23701c04-2118-4c65-9425-78a80d49a211",
DPN2_ID, 3, 12, DPN2MAC1), DPN2IP1));
ELAN_INTERFACES.put(ELAN1 + ":" + DPN2MAC2 ,
- new ImmutablePair(InterfaceHelper
+ ImmutablePair.of(InterfaceHelper
.buildVlanInterfaceInfo("23701c04-2218-4c65-9425-78a80d49a211",
DPN2_ID, 4, 13, DPN2MAC2), DPN2IP2));
ELAN_INTERFACES.put(ELAN1 + ":" + DPN3MAC1 ,
- new ImmutablePair(InterfaceHelper
+ ImmutablePair.of(InterfaceHelper
.buildVlanInterfaceInfo("23701c04-3118-4c65-9425-78a80d49a211",
DPN3_ID, 5, 14, DPN3MAC1), DPN3IP1));
ELAN_INTERFACES.put(ELAN1 + ":" + DPN3MAC2 ,
- new ImmutablePair(InterfaceHelper
+ ImmutablePair.of(InterfaceHelper
.buildVlanInterfaceInfo("23701c04-3218-4c65-9425-78a80d49a211",
DPN3_ID, 6, 15, DPN3MAC2), DPN3IP2));
sortActions(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction input) {
if (input instanceof ApplyActionsCase) {
List<Action> action = new ArrayList<>(((ApplyActionsCase)input).getApplyActions().getAction());
- Collections.sort(action, (o1, o2) -> o1.getOrder().compareTo(o2.getOrder()));
+ action.sort(Comparator.comparing(Ordered::getOrder));
ApplyActions actions = new ApplyActionsBuilder().setAction(action).build();
return new ApplyActionsCaseBuilder().setApplyActions(actions).build();