org.opendaylight.ovsdb.hwvtepsouthbound.transact.LogicalSwitchUcastsRemoveCommand Maven / Gradle / Ivy
/*
* Copyright (c) 2015 China Telecom Beijing Research Institute and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
package org.opendaylight.ovsdb.hwvtepsouthbound.transact;
import static org.opendaylight.ovsdb.lib.operations.Operations.op;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import org.opendaylight.mdsal.binding.api.DataTreeModification;
import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepDeviceInfo;
import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundConstants;
import org.opendaylight.ovsdb.lib.notation.UUID;
import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
import org.opendaylight.ovsdb.lib.schema.typed.TypedBaseTable;
import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
import org.opendaylight.ovsdb.schema.hardwarevtep.LogicalSwitch;
import org.opendaylight.ovsdb.schema.hardwarevtep.McastMacsLocal;
import org.opendaylight.ovsdb.schema.hardwarevtep.McastMacsRemote;
import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalPort;
import org.opendaylight.ovsdb.schema.hardwarevtep.UcastMacsLocal;
import org.opendaylight.ovsdb.schema.hardwarevtep.UcastMacsRemote;
import org.opendaylight.ovsdb.utils.mdsal.utils.TransactionType;
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.hwvtep.global.attributes.LogicalSwitches;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitchesKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.port.attributes.VlanBindings;
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;
public class LogicalSwitchUcastsRemoveCommand
extends AbstractTransactCommand {
private static final Logger LOG = LoggerFactory.getLogger(LogicalSwitchUcastsRemoveCommand.class);
private final AtomicInteger retryCount = new AtomicInteger(5);
private final LogicalSwitches logicalSwitches;
private final InstanceIdentifier nodeIid;
private final List deletedLs;
volatile Map> updatedPortBindings = new HashMap<>();
private boolean firstAttempt = true;
public LogicalSwitchUcastsRemoveCommand(final HwvtepOperationalState state,
final Collection> changes,
final List deletedLs,
final LogicalSwitches logicalSwitches) {
super(state, changes);
this.deletedLs = deletedLs;
this.logicalSwitches = logicalSwitches;
this.nodeIid = getOperationalState().getConnectionInstance().getInstanceIdentifier();
}
@Override
public void execute(final TransactionBuilder transaction) {
InstanceIdentifier lsKey = nodeIid.augmentation(HwvtepGlobalAugmentation.class)
.child(LogicalSwitches.class, logicalSwitches.key());
HwvtepDeviceInfo.DeviceData deviceData = super.fetchDeviceData(LogicalSwitches.class, lsKey);
if (deviceData != null && deviceData.getUuid() != null) {
UUID logicalSwitchUuid = deviceData.getUuid();
UcastMacsRemote ucastMacsRemote = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(),
UcastMacsRemote.class, null);
transaction.add(op.delete(ucastMacsRemote.getSchema())
.where(ucastMacsRemote.getLogicalSwitchColumn().getSchema().opEqual(logicalSwitchUuid)).build());
UcastMacsLocal ucastMacsLocal = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(),
UcastMacsLocal.class, null);
transaction.add(op.delete(ucastMacsLocal.getSchema())
.where(ucastMacsLocal.getLogicalSwitchColumn().getSchema().opEqual(logicalSwitchUuid)).build());
McastMacsRemote mcastMacsRemote = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(),
McastMacsRemote.class, null);
transaction.add(op.delete(mcastMacsRemote.getSchema())
.where(mcastMacsRemote.getLogicalSwitchColumn().getSchema().opEqual(logicalSwitchUuid)).build());
McastMacsLocal mcastMacsLocal = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(),
McastMacsLocal.class, null);
transaction.add(op.delete(mcastMacsLocal.getSchema())
.where(mcastMacsLocal.getLogicalSwitchColumn().getSchema().opEqual(logicalSwitchUuid)).build());
if (firstAttempt) {
LogicalSwitch logicalSwitch = TyperUtils.getTypedRowWrapper(
transaction.getDatabaseSchema(), LogicalSwitch.class, null);
transaction.add(op.delete(logicalSwitch.getSchema()).where(logicalSwitch.getNameColumn().getSchema()
.opEqual(logicalSwitches.getHwvtepNodeName().getValue())).build());
updateControllerTxHistory(TransactionType.DELETE, new StringBuilder(logicalSwitch.toString())
.append(": ").append(logicalSwitches.getHwvtepNodeName()).append(" ")
.append(logicalSwitches.getLogicalSwitchUuid()).append(" ")
.append(logicalSwitches.getTunnelKey()));
LOG.info("CONTROLLER - {} {} {} {} {}", TransactionType.DELETE, logicalSwitch,
logicalSwitches.getHwvtepNodeName(), logicalSwitches.getLogicalSwitchUuid(),
logicalSwitches.getTunnelKey());
} else {
for (Entry> entry : updatedPortBindings.entrySet()) {
PhysicalPort physicalPort = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(),
PhysicalPort.class);
physicalPort.setName(entry.getKey());
physicalPort.setVlanBindings(entry.getValue());
transaction.add(op.update(physicalPort)
.where(physicalPort.getNameColumn().getSchema().opEqual(physicalPort.getName())).build());
updateControllerTxHistory(TransactionType.UPDATE, physicalPort);
LOG.info("CONTROLLER - {} {}", TransactionType.UPDATE, physicalPort);
}
}
} else {
firstAttempt = false;
onSuccess(transaction);
}
}
@Override
protected Map getData(final HwvtepGlobalAugmentation augmentation) {
return augmentation.getLogicalSwitches();
}
@Override
protected boolean areEqual(final LogicalSwitches logicalSwitches1 , final LogicalSwitches logicalSwitches2) {
return logicalSwitches1.key().equals(logicalSwitches2.key())
&& Objects.equals(logicalSwitches1.getTunnelKey(), logicalSwitches2.getTunnelKey());
}
@Override
public void onSuccess(final TransactionBuilder tx) {
if (firstAttempt) {
//LOG.error("check succeeded in deletion of logical swtich at first attempt ");
//succeed in removing the logical switch upon first attempt
return;
}
//LOG.error("check succeeded in deletion of logical swtich after first attempt ");
PlainLogicalSwitchRemoveCmd cmd = new PlainLogicalSwitchRemoveCmd(
newOperState(), getChanges(), logicalSwitches, HwvtepSouthboundConstants.LS_REMOVE_RETRIES);
hwvtepOperationalState.getConnectionInstance().transact(cmd);
}
@Override
public void onFailure(final TransactionBuilder tx) {
//Failed to remove logical swith upon first attempt,
//will attempt to remove the local ucasts and vlan bindings alone in the next attemtps
firstAttempt = false;
getFreshPortBindingsExcludingDeleted();
super.onFailure(tx);
}
private void getFreshPortBindingsExcludingDeleted() {
Set deletedLsUuids = new HashSet<>();
for (LogicalSwitches ls : deletedLs) {
InstanceIdentifier lsKey = nodeIid
.augmentation(HwvtepGlobalAugmentation.class)
.child(LogicalSwitches.class, ls.key());
HwvtepDeviceInfo.DeviceData deviceData =
super.fetchDeviceData(LogicalSwitches.class, lsKey);
if (deviceData.getUuid() != null) {
deletedLsUuids.add(deviceData.getUuid());
}
}
updatedPortBindings = new HashMap<>();
List portsFromDevice = getOperationalState().getConnectionInstance()
.getHwvtepTableReader().getHwvtepTableEntries(VlanBindings.class);
if (portsFromDevice == null || portsFromDevice.isEmpty()) {
LOG.debug("Check did not get any bindings from tor while doing failure of logical switch delete");
return;
}
portsFromDevice.stream()
.map(row -> (PhysicalPort) row)
.filter(port -> port.getVlanBindingsColumn() != null && port.getVlanBindingsColumn().getData() != null)
.forEach(port -> {
int originalBindingsSize = port.getVlanBindingsColumn().getData().size();
Map bindingsAfterExclusion = excludeVlanBindings(deletedLsUuids, port);
if (bindingsAfterExclusion.size() < originalBindingsSize) {
updatedPortBindings.put(port.getName(), bindingsAfterExclusion);
}
});
}
private Map excludeVlanBindings(final Set deletedLsUuids, final PhysicalPort port) {
return port.getVlanBindingsColumn().getData()
.entrySet().stream()
.peek(entry -> {
if (deletedLsUuids.contains(entry.getValue())) {
LOG.trace("check Excluding the vlan binding {}", entry.getValue());
}
})
.filter(entry -> !deletedLsUuids.contains(entry.getValue()))
.collect(Collectors.toMap(entry -> entry.getKey(), entry -> entry.getValue()));
}
@Override
public boolean retry() {
boolean ret = retryCount.decrementAndGet() > 0;
return ret;
}
@Override
protected boolean isDeleteCmd() {
return true;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy