<artifactId>library</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.karaf.shell</groupId>
+ <artifactId>org.apache.karaf.shell.console</artifactId>
+ <scope>provided</scope>
+ </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>schema.hardwarevtep</artifactId>
import org.opendaylight.ovsdb.lib.schema.GenericTableSchema;
import org.opendaylight.ovsdb.lib.schema.TableSchema;
import org.opendaylight.ovsdb.lib.schema.typed.TypedBaseTable;
+import org.opendaylight.ovsdb.utils.mdsal.utils.TransactionHistory;
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.ConnectionInfo;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
private final ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
private final SettableFuture<Boolean> reconciliationFt = SettableFuture.create();
private final AtomicBoolean firstUpdateTriggered = new AtomicBoolean(false);
+ private TransactionHistory controllerTxHistory;
+ private TransactionHistory deviceUpdateHistory;
HwvtepConnectionInstance (HwvtepConnectionManager hwvtepConnectionManager, ConnectionInfo key, OvsdbClient client,
InstanceIdentifier<Node> iid, TransactionInvoker txInvoker, DataBroker dataBroker) {
TableUpdates tableUpdates = hwvtepTableReader.readAllTables();
callback.update(tableUpdates, getDatabaseSchema(HwvtepSchemaConstants.HARDWARE_VTEP));
}
+
+ public MonitorCallBack getCallback() {
+ return callback;
+ }
+
+ public void setCallback(MonitorCallBack callback) {
+ this.callback = callback;
+ }
+
+ public TransactionHistory getControllerTxHistory() {
+ return controllerTxHistory;
+ }
+
+ public void setControllerTxHistory(TransactionHistory controllerTxLog) {
+ deviceInfo.setControllerTxHistory(controllerTxLog);
+ this.controllerTxHistory = controllerTxLog;
+ }
+
+ public TransactionHistory getDeviceUpdateHistory() {
+ return deviceUpdateHistory;
+ }
+
+ public void setDeviceUpdateHistory(TransactionHistory deviceUpdateLog) {
+ deviceInfo.setDeviceUpdateHistory(deviceUpdateLog);
+ this.deviceUpdateHistory = deviceUpdateLog;
+ }
}
import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipState;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.ovsdb.hwvtepsouthbound.events.ClientConnected;
import org.opendaylight.ovsdb.hwvtepsouthbound.reconciliation.ReconciliationManager;
import org.opendaylight.ovsdb.hwvtepsouthbound.reconciliation.ReconciliationTask;
import org.opendaylight.ovsdb.hwvtepsouthbound.reconciliation.configuration.HwvtepReconciliationTask;
import org.opendaylight.ovsdb.lib.schema.GenericTableSchema;
import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
import org.opendaylight.ovsdb.schema.hardwarevtep.Global;
+import org.opendaylight.ovsdb.utils.mdsal.utils.TransactionHistory;
+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.HwvtepPhysicalSwitchAttributes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentation;
private static final Logger LOG = LoggerFactory.getLogger(HwvtepConnectionManager.class);
private static final String ENTITY_TYPE = "hwvtep";
private static final int DB_FETCH_TIMEOUT = 1000;
+ private static final int TRANSACTION_HISTORY_CAPACITY = 10000;
+ private static final int TRANSACTION_HISTORY_WATERMARK = 7500;
private DataBroker db;
private TransactionInvoker txInvoker;
private final Map<InstanceIdentifier<Node>, HwvtepConnectionInstance> nodeIidVsConnectionInstance =
new ConcurrentHashMap<>();
private HwvtepOperGlobalListener hwvtepOperGlobalListener;
+ private final Map<InstanceIdentifier<Node>, TransactionHistory> controllerTxHistory = new ConcurrentHashMap<>();
+ private final Map<InstanceIdentifier<Node>, TransactionHistory> deviceUpdateHistory = new ConcurrentHashMap<>();
public HwvtepConnectionManager(DataBroker db, TransactionInvoker txInvoker,
EntityOwnershipService entityOwnershipService) {
ConnectionInfo key = HwvtepSouthboundMapper.createConnectionInfo(client);
HwvtepConnectionInstance hwvtepConnectionInstance = getConnectionInstance(key);
if (hwvtepConnectionInstance != null) {
+ deviceUpdateHistory.get(hwvtepConnectionInstance.getInstanceIdentifier()).addToHistory(
+ TransactionType.DELETE, new ClientConnected(client.getConnectionInfo().getRemotePort()));
+
// Unregister Entity ownership as soon as possible ,so this instance should
// not be used as a candidate in Entity election (given that this instance is
// about to disconnect as well), if current owner get disconnected from
hwvtepConnectionInstance.setInstanceIdentifier(iid);
LOG.info("InstanceIdentifier {} generated for device "
+ "connection {}",iid, hwvtepConnectionInstance.getConnectionInfo());
-
+ controllerTxHistory.putIfAbsent(iid,
+ new TransactionHistory(TRANSACTION_HISTORY_CAPACITY, TRANSACTION_HISTORY_WATERMARK));
+ deviceUpdateHistory.putIfAbsent(iid,
+ new TransactionHistory(TRANSACTION_HISTORY_CAPACITY, TRANSACTION_HISTORY_WATERMARK));
+ TransactionHistory controllerLog = controllerTxHistory.get(iid);
+ TransactionHistory deviceLog = deviceUpdateHistory.get(iid);
+ int port = hwvtepConnectionInstance.getOvsdbClient().getConnectionInfo().getRemotePort();
+ deviceLog.addToHistory(TransactionType.ADD, new ClientConnected(port));
+ hwvtepConnectionInstance.setControllerTxHistory(controllerLog);
+ hwvtepConnectionInstance.setDeviceUpdateHistory(deviceLog);
}
YangInstanceIdentifier entityId =
HwvtepSouthboundUtil.getInstanceIdentifierCodec().getYangInstanceIdentifier(iid);
}
}
+ public Map<InstanceIdentifier<Node>, TransactionHistory> getControllerTxHistory() {
+ return controllerTxHistory;
+ }
+
+ public Map<InstanceIdentifier<Node>, TransactionHistory> getDeviceUpdateHistory() {
+ return deviceUpdateHistory;
+ }
+
private class HwvtepDeviceEntityOwnershipListener implements EntityOwnershipListener {
private HwvtepConnectionManager hcm;
private EntityOwnershipListenerRegistration listenerRegistration;
import org.opendaylight.ovsdb.schema.hardwarevtep.LogicalSwitch;
import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalLocator;
import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalSwitch;
+import org.opendaylight.ovsdb.utils.mdsal.utils.TransactionHistory;
+import org.opendaylight.ovsdb.utils.mdsal.utils.TransactionType;
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.RemoteMcastMacs;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteUcastMacs;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
-import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.Identifiable;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
private Map<Class<? extends Identifiable>, Map<InstanceIdentifier, DeviceData>> opKeyVsData = new ConcurrentHashMap<>();
private Map<Class<? extends Identifiable>, Map<UUID, Object>> uuidVsData = new ConcurrentHashMap<>();
private DependencyQueue dependencyQueue;
+ private TransactionHistory controllerTxHistory;
+ private TransactionHistory deviceUpdateHistory;
+
public HwvtepDeviceInfo(HwvtepConnectionInstance hwvtepConnectionInstance) {
this.connectionInstance = hwvtepConnectionInstance;
public HwvtepConnectionInstance getConnectionInstance() {
return connectionInstance;
}
+
+ public void setConfigKeyVsData(Map<Class<? extends Identifiable>, Map<InstanceIdentifier, DeviceData>> configKeyVsData) {
+ this.configKeyVsData = configKeyVsData;
+ }
+
+ public void setControllerTxHistory(TransactionHistory controllerTxHistory) {
+ this.controllerTxHistory = controllerTxHistory;
+ }
+
+ public void setDeviceUpdateHistory(TransactionHistory deviceUpdateHistory) {
+ this.deviceUpdateHistory = deviceUpdateHistory;
+ }
+
+ public void addToControllerTx(TransactionType transactionType, Object object) {
+ controllerTxHistory.addToHistory(transactionType, object);
+ }
+
+ public void addToDeviceUpdate(TransactionType transactionType, Object object) {
+ deviceUpdateHistory.addToHistory(transactionType, object);
+ }
}
}
}
+ public HwvtepConnectionManager getHwvtepConnectionManager() {
+ return cm;
+ }
}
--- /dev/null
+/*
+ * Copyright (c) 2017 Ericsson India Global Services Pvt Ltd. 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;
+
+import org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md.HwvtepOperationalCommandAggregator;
+import org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md.TransactionInvoker;
+import org.opendaylight.ovsdb.lib.MonitorCallBack;
+import org.opendaylight.ovsdb.lib.message.TableUpdates;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.ovsdb.utils.mdsal.utils.TransactionElement;
+import org.opendaylight.ovsdb.utils.mdsal.utils.TransactionType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class HwvtepTransactionLogElement extends TransactionElement {
+
+ private final boolean isDeviceLog;
+
+ public HwvtepTransactionLogElement(TransactionType transactionType,
+ Object data,
+ boolean isDeviceLog) {
+ super(transactionType, data);
+ this.isDeviceLog = isDeviceLog;
+ }
+
+ public HwvtepTransactionLogElement(TransactionElement element,
+ boolean isDeviceLog) {
+ super(element.getTransactionType(), element.getData());
+ this.isDeviceLog = isDeviceLog;
+ }
+
+ @Override
+ public String toString() {
+ return "{" +
+ "isDeviceLog=" + isDeviceLog +
+ super.toString() +
+ '}';
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Ericsson India Global Services Pvt Ltd. 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;
+
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.ovsdb.utils.mdsal.utils.TransactionElement;
+import org.opendaylight.ovsdb.utils.mdsal.utils.TransactionHistory;
+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 java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@Command(scope = "hwvtep", name = "txlog", description = "prints hwvtep tx log")
+public class TransactionHistoryCmd extends OsgiCommandSupport {
+
+ @Option(name = "-nodeid", description = "Node Id",
+ required = false, multiValued = false)
+ String nodeid;
+
+ private HwvtepSouthboundProvider hwvtepProvider;
+ private DataBroker dataBroker;
+
+ public void setDataBroker(DataBroker dataBroker) {
+ this.dataBroker = dataBroker;
+ }
+
+ public void setHwvtepProvider(HwvtepSouthboundProvider hwvtepProvider) {
+ this.hwvtepProvider = hwvtepProvider;
+ }
+
+ @Override
+ protected Object doExecute() throws Exception {
+ Map<InstanceIdentifier<Node>, TransactionHistory> controllerTxLogs
+ = hwvtepProvider.getHwvtepConnectionManager().getControllerTxHistory();
+ Map<InstanceIdentifier<Node>, TransactionHistory> deviceUpdateLogs
+ = hwvtepProvider.getHwvtepConnectionManager().getDeviceUpdateHistory();
+ if (nodeid != null) {
+ InstanceIdentifier<Node> iid = HwvtepSouthboundMapper.createInstanceIdentifier(new NodeId(nodeid));
+ printLogs(controllerTxLogs, deviceUpdateLogs, iid);
+ } else {
+ Map<InstanceIdentifier<Node>, TransactionHistory> txlogs
+ = controllerTxLogs.isEmpty() ? deviceUpdateLogs : controllerTxLogs;
+ txlogs.keySet().forEach( (iid) -> {
+ printLogs(controllerTxLogs, deviceUpdateLogs, iid);
+ });
+ session.getConsole().println("Device tx logs size "+deviceUpdateLogs.keySet().size());
+ }
+ return null;
+ }
+
+ private void printLogs(Map<InstanceIdentifier<Node>, TransactionHistory> controllerTxLogs,
+ Map<InstanceIdentifier<Node>, TransactionHistory> deviceUpdateLogs,
+ InstanceIdentifier<Node> iid) {
+ session.getConsole().println("Printing for iid "+ iid);
+ List<HwvtepTransactionLogElement> controllerTxLog = controllerTxLogs.get(iid).getElements()
+ .stream().map(ele -> new HwvtepTransactionLogElement(ele, false)).collect(Collectors.toList());
+ List<HwvtepTransactionLogElement> deviceUpdateLog = deviceUpdateLogs.get(iid).getElements()
+ .stream().map(ele -> new HwvtepTransactionLogElement(ele, false)).collect(Collectors.toList());
+ //deviceUpdateLog.forEach( (log) -> log.setDeviceLog(true));
+ List<HwvtepTransactionLogElement> allLogs = mergeLogsByDate(controllerTxLog, deviceUpdateLog);
+ session.getConsole().println("======================================");
+ session.getConsole().println("======================================");
+ session.getConsole().print("printing logs for node ");
+ session.getConsole().println(iid);
+ printLogs(allLogs);
+ }
+
+ private void sortLogsByDate(ArrayList<TransactionElement> logs) {
+ Collections.sort(logs, new Comparator<TransactionElement>() {
+ @Override
+ public int compare(TransactionElement o1, TransactionElement o2) {
+ return (int) (o1.getDate() - o2.getDate());
+ }
+ });
+ }
+
+ private List<HwvtepTransactionLogElement> mergeLogsByDate(
+ List<HwvtepTransactionLogElement> logs1,
+ List<HwvtepTransactionLogElement> logs2) {
+
+ ArrayList<HwvtepTransactionLogElement> result = new ArrayList();
+ int firstIdx = 0;
+ int secondIdx = 0;
+ int firstSize = logs1.size();
+ int secondSize = logs2.size();
+ while ( firstIdx < firstSize && secondIdx < secondSize) {
+ if (logs1.get(firstIdx).getDate() < logs2.get(secondIdx).getDate()) {
+ result.add(logs1.get(firstIdx));
+ firstIdx++;
+ } else {
+ result.add(logs2.get(secondIdx));
+ secondIdx++;
+ }
+ }
+ while (firstIdx < firstSize) {
+ result.add(logs1.get(firstIdx));
+ firstIdx++;
+ }
+ while (secondIdx < secondSize) {
+ result.add(logs2.get(secondIdx));
+ secondIdx++;
+ }
+ return result;
+ }
+
+ private void printLogs(List<HwvtepTransactionLogElement> logs) {
+ logs.forEach( (log) -> {
+ session.getConsole().print(new Date(log.getDate()));
+ session.getConsole().print(" ");
+ session.getConsole().print(log.getTransactionType());
+ session.getConsole().print(" ");
+ session.getConsole().println(log.getData());
+ });
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Ericsson India Global Services Pvt Ltd. 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.events;
+
+public class ClientConnected {
+
+ private final int port;
+
+ public ClientConnected(int port) {
+ this.port = port;
+ }
+
+ @Override
+ public String toString() {
+ return "ClientConnected{" +
+ "port=" + port +
+ '}';
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Ericsson India Global Services Pvt Ltd. 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.events;
+
+public class ClientDisConnected {
+
+ private final int port;
+
+ public ClientDisConnected(int port) {
+ this.port = port;
+ }
+
+ @Override
+ public String toString() {
+ return "ClientConnected{" +
+ "port=" + port +
+ '}';
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Ericsson India Global Services Pvt Ltd. 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.events;
+
+import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalPort;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+
+public class PortEvent {
+
+ private final PhysicalPort port;
+ private final NodeId nodeId;
+
+ public PortEvent(PhysicalPort port, NodeId nodeId) {
+ this.port = port;
+ this.nodeId = nodeId;
+ }
+
+ @Override
+ public String toString() {
+ return "PortEvent{" +
+ "port=" + port +
+ "nodeId=" + nodeId +
+ '}';
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Ericsson India Global Services Pvt Ltd. 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.events;
+
+import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalPort;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+
+public class ReconcilePortEvent {
+
+ private final PhysicalPort port;
+ private final NodeId nodeId;
+
+ public ReconcilePortEvent(PhysicalPort port, NodeId nodeId) {
+ this.port = port;
+ this.nodeId = nodeId;
+ }
+
+ @Override
+ public String toString() {
+ return "ReconcilePortEvent{" +
+ "port=" + port +
+ "nodeId=" + nodeId +
+ '}';
+ }
+}
import org.opendaylight.ovsdb.lib.notation.UUID;
import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
+import org.opendaylight.ovsdb.utils.mdsal.utils.TransactionType;
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.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
protected void onCommandFailed() {
}
+
+ void updateControllerTxHistory(TransactionType transactionType, Object element) {
+ getOperationalState().getDeviceInfo().addToControllerTx(transactionType, element);
+ }
}
import org.opendaylight.ovsdb.schema.hardwarevtep.McastMacsRemote;
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.RemoteMcastMacs;
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.Identifiable;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.Optional;
-
public class LogicalSwitchRemoveCommand extends AbstractTransactCommand<LogicalSwitches, HwvtepGlobalAugmentation> {
private static final Logger LOG = LoggerFactory.getLogger(LogicalSwitchRemoveCommand.class);
transaction.add(op.delete(mcastMacsLocal.getSchema())
.where(mcastMacsLocal.getLogicalSwitchColumn().getSchema().opEqual(logicalSwitchUuid)).build());
updateCurrentTxDeleteData(LogicalSwitches.class, lsKey, lswitch);
+ updateControllerTxHistory(TransactionType.DELETE, lswitch);
} else {
LOG.warn("Unable to delete logical switch {} because it was not found in the operational store",
lswitch.getHwvtepNodeName().getValue());
import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
import org.opendaylight.ovsdb.lib.error.SchemaVersionMismatchException;
import org.opendaylight.ovsdb.schema.hardwarevtep.LogicalSwitch;
+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.RemoteMcastMacs;
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;
-import com.google.common.base.Optional;
-
public class LogicalSwitchUpdateCommand extends AbstractTransactCommand<LogicalSwitches, HwvtepGlobalAugmentation> {
private static final Logger LOG = LoggerFactory.getLogger(LogicalSwitchUpdateCommand.class);
transaction.add(op.comment("Logical Switch: Creating " + lswitch.getHwvtepNodeName().getValue()));
UUID lsUuid = new UUID(TransactUtils.getLogicalSwitchId(lswitch));
updateCurrentTxData(LogicalSwitches.class, lsKey, lsUuid, lswitch);
+ updateControllerTxHistory(TransactionType.ADD, lswitch);
} else {
String existingLogicalSwitchName = lswitch.getHwvtepNodeName().getValue();
// Name is immutable, and so we *can't* update it. So we use extraBridge for the schema stuff
.where(extraLogicalSwitch.getNameColumn().getSchema().opEqual(existingLogicalSwitchName))
.build());
transaction.add(op.comment("Logical Switch: Updating " + existingLogicalSwitchName));
+ updateControllerTxHistory(TransactionType.UPDATE, lswitch);
}
}
import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalPort;
+import org.opendaylight.ovsdb.utils.mdsal.utils.TransactionType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalPortAugmentation;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
transaction.add(op.update(physicalPort)
.where(extraPhyscialPort.getNameColumn().getSchema().opEqual(existingPhysicalPortName))
.build());
+ updateControllerTxHistory(TransactionType.UPDATE, physicalPort);
} else {
LOG.warn("Unable to update physical port {} because it was not found in the operational store, "
+ "and thus we cannot retrieve its UUID", port.getHwvtepNodeName().getValue());
import com.google.common.collect.Lists;
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.ovsdb.hwvtepsouthbound.HwvtepDeviceInfo;
-import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundMapper;
import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundUtil;
-import org.opendaylight.ovsdb.lib.notation.Mutator;
import org.opendaylight.ovsdb.lib.notation.UUID;
import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalPort;
-import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalSwitch;
-import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
+import org.opendaylight.ovsdb.utils.mdsal.utils.TransactionType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalPortAugmentation;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentation;
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.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
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.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
.where(extraPhyscialPort.getNameColumn().getSchema().opEqual(existingPhysicalPortName))
.build());
transaction.add(op.comment("Physical Port: Updating " + existingPhysicalPortName));
+ updateControllerTxHistory(TransactionType.UPDATE, physicalPort);
}
}
}
import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepDeviceInfo;
import org.opendaylight.ovsdb.lib.message.TableUpdates;
import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.ovsdb.utils.mdsal.utils.TransactionType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.ConnectionInfo;
import org.opendaylight.yangtools.yang.binding.DataObject;
public HwvtepDeviceInfo getDeviceInfo() {
return key.getDeviceInfo();
}
+
+ void addToDeviceUpdate(TransactionType transactionType, Object element) {
+ key.getDeviceInfo().addToDeviceUpdate(transactionType, element);
+ }
}
import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
import org.opendaylight.ovsdb.schema.hardwarevtep.LogicalSwitch;
+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.HwvtepNodeName;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
// TODO Delete any references
transaction.delete(LogicalDatastoreType.OPERATIONAL, switchIid);
getOvsdbConnectionInstance().getDeviceInfo().clearDeviceOperData(LogicalSwitches.class, switchIid);
+ addToDeviceUpdate(TransactionType.DELETE, lSwitch);
}
}
import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
import org.opendaylight.ovsdb.schema.hardwarevtep.LogicalSwitch;
+import org.opendaylight.ovsdb.utils.mdsal.utils.TransactionType;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
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.HwvtepGlobalAugmentationBuilder;
.child(LogicalSwitches.class, new LogicalSwitchesKey(new HwvtepNodeName(lSwitch.getName())));
getOvsdbConnectionInstance().getDeviceInfo().updateDeviceOperData(LogicalSwitches.class, switchIid,
lSwitch.getUuid(), lSwitch);
+ addToDeviceUpdate(TransactionType.ADD, lSwitch);
// TODO: Delete entries that are no longer needed
}
}
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepConnectionInstance;
import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundMapper;
+import org.opendaylight.ovsdb.hwvtepsouthbound.events.PortEvent;
import org.opendaylight.ovsdb.lib.message.TableUpdates;
import org.opendaylight.ovsdb.lib.notation.UUID;
import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalPort;
import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalSwitch;
+import org.opendaylight.ovsdb.utils.mdsal.utils.TransactionType;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
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;
updatedPSwitchData).child(TerminationPoint.class,
new TerminationPointKey(new TpId(portName)));
transaction.delete(LogicalDatastoreType.OPERATIONAL, nodePath);
+ addToDeviceUpdate(TransactionType.DELETE,
+ new PortEvent(pPort, nodePath.firstKeyOf(Node.class).getNodeId()));
getDeviceInfo().clearDeviceOperData(TerminationPoint.class, nodePath);
}
}
import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepConnectionInstance;
import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundMapper;
import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundUtil;
+import org.opendaylight.ovsdb.hwvtepsouthbound.events.PortEvent;
+import org.opendaylight.ovsdb.hwvtepsouthbound.events.ReconcilePortEvent;
import org.opendaylight.ovsdb.hwvtepsouthbound.transact.HwvtepOperationalState;
import org.opendaylight.ovsdb.hwvtepsouthbound.transact.PhysicalPortUpdateCommand;
import org.opendaylight.ovsdb.lib.message.TableUpdates;
import org.opendaylight.ovsdb.schema.hardwarevtep.LogicalSwitch;
import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalPort;
import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalSwitch;
+import org.opendaylight.ovsdb.utils.mdsal.utils.TransactionType;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
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.physical.port.attributes.VlanBindings;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.port.attributes.VlanBindingsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.port.attributes.VlanBindingsKey;
+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.TpId;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
} else {
transaction.put(LogicalDatastoreType.OPERATIONAL, tpPath, tpBuilder.build());
}
+ NodeId psNodeId = tpPath.firstKeyOf(Node.class).getNodeId();
+ if (getDeviceInfo().getDeviceOperData(TerminationPoint.class, tpPath) == null) {
+ addToDeviceUpdate(TransactionType.ADD, new PortEvent(pPortUpdate, psNodeId));
+ } else {
+ addToDeviceUpdate(TransactionType.UPDATE, new PortEvent(pPortUpdate, psNodeId));
+ }
reconcileToPort(transaction, pPortUpdate, tpPath);
getDeviceInfo().updateDeviceOperData(TerminationPoint.class, tpPath,
pPortUpdate.getUuid(), pPortUpdate);
//TODO port came with some vlan bindings clean them up use PortRemovedCommand
return;
}
+ addToDeviceUpdate(TransactionType.ADD,
+ new ReconcilePortEvent(pPortUpdate, tpPath.firstKeyOf(Node.class).getNodeId()));
getDeviceInfo().updateDeviceOperData(TerminationPoint.class, tpPath,
pPortUpdate.getUuid(), pPortUpdate);
TerminationPoint configTp = optionalConfigTp.get();
<argument ref="bindingNormalizedNodeSerializer" />
</bean>
+ <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
+ <command>
+ <action class="org.opendaylight.ovsdb.hwvtepsouthbound.TransactionHistoryCmd">
+ <property name="dataBroker" ref="dataBroker" />
+ <property name="hwvtepProvider" ref="hwvtepProvider" />
+ </action>
+ </command>
+ </command-bundle>
</blueprint>
import org.opendaylight.ovsdb.lib.operations.Where;
import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
import org.opendaylight.ovsdb.lib.schema.typed.TypedBaseTable;
+import org.opendaylight.ovsdb.utils.mdsal.utils.TransactionHistory;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
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.HwvtepGlobalAugmentationBuilder;
doReturn(nodeIid).when(connectionInstance).getInstanceIdentifier();
field(HwvtepConnectionInstance.class, "deviceInfo").set(connectionInstance,
new HwvtepDeviceInfo(connectionInstance));
+ connectionInstance.setControllerTxHistory(new TransactionHistory(10000, 7500));
+ connectionInstance.setDeviceUpdateHistory(new TransactionHistory(10000, 7500));
connectionInstance.createTransactInvokers();
}
--- /dev/null
+/*
+ * Copyright (c) 2017 Ericsson India Global Services Pvt Ltd. 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.utils.mdsal.utils;
+
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class MdsalObject {
+ private final InstanceIdentifier iid;
+ private final DataObject dataObject;
+
+ public MdsalObject(InstanceIdentifier iid, DataObject dataObject) {
+ this.dataObject = dataObject;
+ this.iid = iid;
+ }
+
+ @Override
+ public String toString() {
+ return "MdsalObject{" +
+ "dataObject=" + dataObject +
+ ", iid=" + iid +
+ '}';
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Ericsson India Global Services Pvt Ltd. 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.utils.mdsal.utils;
+
+public class TransactionElement {
+ private long date;
+ private TransactionType transactionType;
+ private Object data;
+
+ public TransactionElement(TransactionType transactionType, Object data) {
+ this.data = data;
+ this.transactionType = transactionType;
+ this.date = System.currentTimeMillis();
+ }
+
+ public Object getData() {
+ return data;
+ }
+
+ public long getDate() {
+ return date;
+ }
+
+ public TransactionType getTransactionType() {
+ return transactionType;
+ }
+
+ @Override
+ public String toString() {
+ return "TransactionElement{" +
+ "date=" + date +
+ ", transactionType=" + transactionType +
+ ", data=" + data +
+ '}';
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. 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.utils.mdsal.utils;
+
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+
+public class TransactionHistory extends ArrayList<TransactionElement> {
+
+ private final int capacity;
+ private final int watermark;
+
+ public TransactionHistory(int initialCapacity, int watermark) {
+ super(initialCapacity);
+ this.capacity = initialCapacity;
+ this.watermark = watermark;
+ }
+
+ public void addToHistory(TransactionType updateType, Object object) {
+ add(new TransactionElement(updateType, object));
+ }
+
+ public void addToHistory(TransactionType updateType, InstanceIdentifier iid, DataObject dataObject) {
+ add(new TransactionElement(updateType, new MdsalObject(iid, dataObject)));
+ }
+
+ @Override
+ public boolean add(TransactionElement element) {
+ if (size() >= watermark) {
+ removeRange(0, capacity - watermark);
+ }
+ return super.add(element);
+ }
+
+ public ArrayList<TransactionElement> getElements() {
+ return new ArrayList<>(this);
+ }
+
+ @Override
+ protected void removeRange(int fromIndex, int toIndex) {
+ super.removeRange(fromIndex, toIndex);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Ericsson India Global Services Pvt Ltd. 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.utils.mdsal.utils;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+
+public enum TransactionType {
+ ADD,
+ UPDATE,
+ DELETE;
+}