revision-date "2013-07-15";
}
+ import ietf-yang-types {
+ prefix yang;
+ revision-date "2013-07-15";
+ }
+
revision "2016-04-11" {
description "YANG model describes methods for monitoring endpoints.";
}
leaf ip-address { type inet:ip-address; }
}
case interface {
+ leaf mac-address { type yang:phys-address; }
leaf interface-ip { type inet:ip-address; }
leaf interface-name { type string; }
}
import static org.opendaylight.genius.alivenessmonitor.internal.AlivenessMonitorConstants.SEPERATOR;
import static org.opendaylight.genius.alivenessmonitor.internal.AlivenessMonitorUtil.toStringIpAddress;
+import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.util.concurrent.FutureCallback;
import org.opendaylight.genius.mdsalutil.NwConstants;
import org.opendaylight.genius.mdsalutil.packet.ARP;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder;
+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.genius.alivenessmonitor.rev160411.EtherTypes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.endpoint.EndpointType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.endpoint.endpoint.type.Interface;
}
EndpointType source = monitorInfo.getSource().getEndpointType();
final String sourceInterface = Preconditions.checkNotNull(getInterfaceName(source),
- "Source interface is required to send ARP Packet for monitoring");
+ "Source interface is required to send ARP Packet for monitoring");
final String srcIp = Preconditions.checkNotNull(getIpAddress(source),
- "Source Ip address is required to send ARP Packet for monitoring");
-
- EndpointType target = monitorInfo.getDestination().getEndpointType();
- final String targetIp = Preconditions.checkNotNull(getIpAddress(target),
- "Target Ip address is required to send ARP Packet for monitoring");
-
- if (LOG.isTraceEnabled()) {
- LOG.trace("sendArpRequest interface {}, senderIPAddress {}, targetAddress {}", sourceInterface, srcIp, targetIp);
- }
-
- List<InterfaceAddress> addresses = Collections.singletonList(
- new InterfaceAddressBuilder().setInterface(sourceInterface)
- .setIpAddress(IpAddressBuilder.getDefaultInstance(srcIp)).build());
- SendArpRequestInput input = new SendArpRequestInputBuilder().setInterfaceAddress(addresses)
- .setIpaddress(IpAddressBuilder.getDefaultInstance(targetIp)).build();
- Future<RpcResult<Void>> future = arpService.sendArpRequest(input);
-
- final String msgFormat = String.format("Send ARP Request on interface %s to destination %s", sourceInterface, targetIp);
- Futures.addCallback(JdkFutureAdapters.listenInPoolThread(future), new FutureCallback<RpcResult<Void>>() {
- @Override
- public void onFailure(Throwable error) {
- LOG.error("Error - {}", msgFormat, error);
+ "Source Ip address is required to send ARP Packet for monitoring");
+ final Optional<PhysAddress> srcMacAddressOptional = getMacAddress(source);
+ if(srcMacAddressOptional.isPresent())
+ {
+ PhysAddress srcMacAddress = srcMacAddressOptional.get();
+ EndpointType target = monitorInfo.getDestination().getEndpointType();
+ final String targetIp = Preconditions.checkNotNull(getIpAddress(target),
+ "Target Ip address is required to send ARP Packet for monitoring");
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("sendArpRequest interface {}, senderIPAddress {}, targetAddress {}", sourceInterface, srcIp, targetIp);
+ }
+ InterfaceAddressBuilder interfaceAddressBuilder = new InterfaceAddressBuilder().setInterface(sourceInterface)
+ .setIpAddress(IpAddressBuilder.getDefaultInstance(srcIp));
+ if (srcMacAddress != null) {
+ interfaceAddressBuilder.setMacaddress(srcMacAddress);
}
+ List<InterfaceAddress> addresses = Collections.singletonList(interfaceAddressBuilder.build());
+ SendArpRequestInput input = new SendArpRequestInputBuilder().setInterfaceAddress(addresses)
+ .setIpaddress(IpAddressBuilder.getDefaultInstance(targetIp)).build();
+ Future<RpcResult<Void>> future = arpService.sendArpRequest(input);
+ final String msgFormat = String.format("Send ARP Request on interface %s to destination %s", sourceInterface, targetIp);
+ Futures.addCallback(JdkFutureAdapters.listenInPoolThread(future), new FutureCallback<RpcResult<Void>>() {
+ @Override
+ public void onFailure(Throwable error) {
+ LOG.error("Error - {}", msgFormat, error);
+ }
- @Override
- public void onSuccess(RpcResult<Void> result) {
- if(!result.isSuccessful()) {
- LOG.warn("Rpc call to {} failed {}", msgFormat, getErrorText(result.getErrors()));
- } else {
- LOG.debug("Successful RPC Result - {}", msgFormat);
+ @Override
+ public void onSuccess(RpcResult<Void> result) {
+ if(!result.isSuccessful()) {
+ LOG.warn("Rpc call to {} failed {}", msgFormat, getErrorText(result.getErrors()));
+ } else {
+ LOG.debug("Successful RPC Result - {}", msgFormat);
+ }
}
- }
- });
+ });
+ }
}
private String getErrorText(Collection<RpcError> errors) {
return ipAddress;
}
+ private Optional <PhysAddress> getMacAddress(EndpointType source) {
+ Optional <PhysAddress> result = Optional.absent();
+ if (source instanceof Interface) {
+ result = Optional.of(((Interface)source).getMacAddress());
+ }
+ return result;
+ }
+
private String getInterfaceName(EndpointType endpoint) {
String interfaceName = null;
if(endpoint instanceof Interface) {
String macAddr = interfaceAddress.getMacaddress().getValue();
srcMac = HexEncode.bytesFromHexString(macAddr);
}
-
checkNotNull(srcMac, FAILED_TO_GET_SRC_MAC_FOR_INTERFACE,
interfaceName, ref.getValue());
checkNotNull(srcIpBytes, FAILED_TO_GET_SRC_IP_FOR_INTERFACE,
<model.bgp.version>2013.07.15.10-SNAPSHOT</model.bgp.version>
<openflowplugin.version>0.4.0-SNAPSHOT</openflowplugin.version>
<genius.ovsdb.version>1.4.0-SNAPSHOT</genius.ovsdb.version>
+ <genius.infrautils.version>1.1.0-SNAPSHOT</genius.infrautils.version>
<liblldp.version>0.12.0-SNAPSHOT</liblldp.version>
<karaf.shell.console.version>3.0.3</karaf.shell.console.version>
</properties>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
- <artifactId>resourcemanager-impl</artifactId>
+ <artifactId>fcapsapplication-impl</artifactId>
+ <version>${project.version}</version>
+ <type>xml</type>
+ <classifier>config</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>resourcemanager-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>resourcemanager-impl</artifactId>
<version>${project.version}</version>
- <type>xml</type>
- <classifier>config</classifier>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
- <artifactId>resourcemanager-api</artifactId>
+ <artifactId>resourcemanager-impl</artifactId>
<version>${project.version}</version>
+ <type>xml</type>
+ <classifier>config</classifier>
</dependency>
</dependencies>
</project>
package org.opendaylight.genius.interfacemanager;
import com.google.common.base.Optional;
-import com.google.common.collect.ImmutableBiMap;
+import com.google.common.collect.ImmutableMap;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeGre;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeMplsOverGre;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlanGpe;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceBindings;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeBase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.ServicesInfo;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.concurrent.Callable;
import static org.opendaylight.genius.interfacemanager.globals.InterfaceInfo.InterfaceType.VLAN_INTERFACE;
private static final Logger LOG = LoggerFactory.getLogger(IfmUtil.class);
private static final int INVALID_ID = 0;
- public static final ImmutableBiMap<Class<? extends TunnelTypeBase>, InterfaceInfo.InterfaceType> TUNNEL_TYPE_MAP =
- new ImmutableBiMap.Builder<Class<? extends TunnelTypeBase>, InterfaceInfo.InterfaceType>()
+ private static final ImmutableMap<Class<? extends TunnelTypeBase>, InterfaceInfo.InterfaceType> TUNNEL_TYPE_MAP =
+ new ImmutableMap.Builder<Class<? extends TunnelTypeBase>, InterfaceInfo.InterfaceType>()
.put(TunnelTypeGre.class, InterfaceInfo.InterfaceType.GRE_TRUNK_INTERFACE)
.put(TunnelTypeMplsOverGre.class, InterfaceInfo.InterfaceType.MPLS_OVER_GRE)
.put(TunnelTypeVxlan.class, InterfaceInfo.InterfaceType.VXLAN_TRUNK_INTERFACE)
+ .put(TunnelTypeVxlanGpe.class, InterfaceInfo.InterfaceType.VXLAN_TRUNK_INTERFACE)
.build();
-
public static String getDpnFromNodeConnectorId(NodeConnectorId portId) {
/*
* NodeConnectorId is of form 'openflow:dpnid:portnum'
int actionKeyStart,
boolean isDefaultEgress,
int ifIndex) {
- List<ActionInfo> result = new ArrayList<ActionInfo>();
+ List<ActionInfo> result = new ArrayList<>();
switch (ifaceType) {
case VLAN_INTERFACE:
if(isDefaultEgress) {
}
public static InterfaceInfo.InterfaceType getInterfaceType(Interface iface) {
- InterfaceInfo.InterfaceType interfaceType =
- org.opendaylight.genius.interfacemanager.globals.InterfaceInfo.InterfaceType.UNKNOWN_INTERFACE;
- Class<? extends org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType> ifType = iface.getType();
+ InterfaceInfo.InterfaceType interfaceType = org.opendaylight.genius.interfacemanager.globals.InterfaceInfo.InterfaceType.UNKNOWN_INTERFACE;
+ Class<? extends org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType> ifType = iface
+ .getType();
if (ifType.isAssignableFrom(L2vlan.class)) {
- interfaceType = VLAN_INTERFACE;
+ interfaceType = VLAN_INTERFACE;
} else if (ifType.isAssignableFrom(Tunnel.class)) {
IfTunnel ifTunnel = iface.getAugmentation(IfTunnel.class);
- Class<? extends org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase> tunnelType = ifTunnel.getTunnelInterfaceType();
+ Class<? extends org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase> tunnelType = ifTunnel
+ .getTunnelInterfaceType();
interfaceType = TUNNEL_TYPE_MAP.get(tunnelType);
}
return interfaceType;
LOG.info("Unbinding Service from : {}", interfaceName);
DataStoreJobCoordinator dataStoreJobCoordinator = DataStoreJobCoordinator.getInstance();
dataStoreJobCoordinator.enqueueJob(interfaceName,
- new Callable<List<ListenableFuture<Void>>>() {
- @Override
- public List<ListenableFuture<Void>> call() throws Exception {
- WriteTransaction t = dataBroker.newWriteOnlyTransaction();
- t.delete(LogicalDatastoreType.CONFIGURATION, boundServicesInstanceIdentifier);
- List<ListenableFuture<Void>> futures = new ArrayList<>();
- futures.add(t.submit());
- return futures;
- }
+ () -> {
+ WriteTransaction t = dataBroker.newWriteOnlyTransaction();
+ t.delete(LogicalDatastoreType.CONFIGURATION, boundServicesInstanceIdentifier);
+ List<ListenableFuture<Void>> futures = new ArrayList<>();
+ futures.add(t.submit());
+ return futures;
}
);
}
import org.opendaylight.genius.interfacemanager.listeners.TerminationPointStateListener;
import org.opendaylight.genius.interfacemanager.listeners.VlanMemberConfigListener;
import org.opendaylight.genius.interfacemanager.pmcounters.NodeConnectorStatsImpl;
-import org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.BatchHandler;
+import org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.InterfaceBatchHandler;
import org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.BatchingUtils;
import org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.IfmClusterUtils;
import org.opendaylight.genius.interfacemanager.rpcservice.InterfaceManagerRpcService;
createIdPool();
IfmClusterUtils.registerEntityForOwnership(this, entityOwnershipService);
- BatchingUtils.registerWithBatchManager(new BatchHandler(), this.dataBroker);
+ BatchingUtils.registerWithBatchManager(new InterfaceBatchHandler(), this.dataBroker);
alivenessManager = rpcProviderRegistry.getRpcService(AlivenessMonitorService.class);
interfaceManagerRpcService = new InterfaceManagerRpcService(dataBroker, mdsalManager);
rpcRegistration = getRpcProviderRegistry().addRpcImplementation(
private static final Logger LOG = LoggerFactory.getLogger(InterfaceManagerCommonUtils.class);
private static ConcurrentHashMap<String, Interface> interfaceConfigMap = new ConcurrentHashMap<>();
private static ConcurrentHashMap<String, org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> interfaceStateMap = new ConcurrentHashMap<>();
+ private static ConcurrentHashMap<String, org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus> bfdStateMap =
+ new ConcurrentHashMap<String, org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus>();
+
private static final String NOVA_OR_TUNNEL_PORT_REGEX = "(tap|vhu)[0-9a-f]{8}-[0-9a-f]{2}|tun[0-9a-f]{11}";
private static final Pattern pattern = Pattern.compile(NOVA_OR_TUNNEL_PORT_REGEX);
}
}
+ public static boolean checkIfBfdStateIsDown(String interfaceName){
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus operStatus =
+ InterfaceManagerCommonUtils.getBfdStateFromCache(interfaceName);
+ return (operStatus == org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Down);
+ }
+
public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface addStateEntry(
Interface interfaceInfo, String interfaceName, WriteTransaction transaction, IdManagerService idManager,
PhysAddress physAddress,
InterfaceBuilder ifaceBuilder = new InterfaceBuilder();
Integer ifIndex = null;
if (interfaceInfo != null) {
- if (!interfaceInfo.isEnabled()) {
+ if(!interfaceInfo.isEnabled() || (InterfaceManagerCommonUtils.isTunnelInterface(interfaceInfo) &&
+ checkIfBfdStateIsDown(interfaceInfo.getName()))){
operStatus = org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Down;
}
interfaceStateMap.remove(iface.getName());
}
+ public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus getBfdStateFromCache(String interfaceName) {
+ return bfdStateMap.get(interfaceName);
+ }
+
+ public static void addBfdStateToCache(String interfaceName,
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus operStatus) {
+ bfdStateMap.put(interfaceName, operStatus);
+ }
+
+ public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus removeBfdStateFromCache(String interfaceName){
+ return bfdStateMap.remove(interfaceName);
+ }
+
public static boolean isNovaOrTunnelPort(String portName) {
Matcher matcher = pattern.matcher(portName);
String portName = flowCapableNodeConnectorOld.getName();
NodeConnectorId nodeConnectorId = InstanceIdentifier.keyOf(key.firstIdentifierOf(NodeConnector.class)).getId();
- //VM Migration: Skip OFPPR_DELETE event received after OFPPR_ADD for same interface from Older DPN
- NodeConnectorId nodeConnectorIdOld = IfmUtil.getNodeConnectorIdFromInterface(portName, dataBroker);
- if (InterfaceManagerCommonUtils.isNovaOrTunnelPort(portName)) {
- if (nodeConnectorIdOld != null && !nodeConnectorId.equals(nodeConnectorIdOld)) {
- LOG.debug("Dropping the NodeConnector Remove Event for the interface: {}, {}, {}", portName, nodeConnectorId, nodeConnectorIdOld);
- return;
- }
- } else {
+ if (!InterfaceManagerCommonUtils.isNovaOrTunnelPort(portName)) {
portName = getDpnPrefixedPortName(nodeConnectorId, portName);
}
- boolean isNodePresent = InterfaceManagerCommonUtils.isNodePresent(dataBroker, nodeConnectorId);
- remove(nodeConnectorId, nodeConnectorIdOld, flowCapableNodeConnectorOld, portName, isNodePresent);
+ remove(nodeConnectorId, null, flowCapableNodeConnectorOld, portName, true);
}
});
}
NodeConnectorId nodeConnectorIdOld = IfmUtil.getNodeConnectorIdFromInterface(portName, dataBroker);
if (nodeConnectorIdOld != null && !nodeConnectorId.equals(nodeConnectorIdOld)) {
LOG.debug("Triggering NodeConnector Remove Event for the interface: {}, {}, {}", portName, nodeConnectorId, nodeConnectorIdOld);
- boolean isNodePresent = InterfaceManagerCommonUtils.isNodePresent(dataBroker, nodeConnectorIdOld);
- remove(nodeConnectorId, nodeConnectorIdOld, fcNodeConnectorNew, portName, isNodePresent);
+ remove(nodeConnectorId, nodeConnectorIdOld, fcNodeConnectorNew, portName, false);
//Adding a delay of 10sec for VM migration, so applications can process remove and add events
try {
Thread.sleep(IfmConstants.DELAY_TIME_IN_MILLISECOND);
}
private void remove(NodeConnectorId nodeConnectorIdNew, NodeConnectorId nodeConnectorIdOld,
- FlowCapableNodeConnector fcNodeConnectorNew, String portName, boolean isNodePresent) {
+ FlowCapableNodeConnector fcNodeConnectorNew, String portName, boolean isNetworkEvent) {
+ boolean isNodePresent = InterfaceManagerCommonUtils.isNodePresent(dataBroker, nodeConnectorIdNew);
DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
- InterfaceStateRemoveWorker portStateRemoveWorker = new InterfaceStateRemoveWorker(idManager,
- nodeConnectorIdNew, nodeConnectorIdOld, fcNodeConnectorNew, portName, isNodePresent);
+ InterfaceStateRemoveWorker portStateRemoveWorker = new InterfaceStateRemoveWorker(idManager, nodeConnectorIdNew,
+ nodeConnectorIdOld, fcNodeConnectorNew, portName, isNodePresent, isNetworkEvent, true);
coordinator.enqueueJob(portName, portStateRemoveWorker, IfmConstants.JOB_MAX_RETRIES);
}
private class InterfaceStateRemoveWorker implements Callable {
private final NodeConnectorId nodeConnectorIdNew;
- private final NodeConnectorId nodeConnectorIdOld;
+ private NodeConnectorId nodeConnectorIdOld;
FlowCapableNodeConnector fcNodeConnectorOld;
private final String interfaceName;
private final IdManagerService idManager;
private final boolean isNodePresent;
+ private final boolean isNetworkEvent;
+ private final boolean isParentInterface;
public InterfaceStateRemoveWorker(IdManagerService idManager, NodeConnectorId nodeConnectorIdNew,
NodeConnectorId nodeConnectorIdOld,
FlowCapableNodeConnector fcNodeConnectorOld,
String portName,
- boolean isNodePresent) {
+ boolean isNodePresent,
+ boolean isNetworkEvent,
+ boolean isParentInterface) {
this.nodeConnectorIdNew = nodeConnectorIdNew;
this.nodeConnectorIdOld = nodeConnectorIdOld;
this.fcNodeConnectorOld = fcNodeConnectorOld;
this.interfaceName = portName;
this.idManager = idManager;
this.isNodePresent = isNodePresent;
+ this.isNetworkEvent = isNetworkEvent;
+ this.isParentInterface = isParentInterface;
}
@Override
public Object call() throws Exception {
// If another renderer(for eg : CSS) needs to be supported, check can be performed here
// to call the respective helpers.
- List<ListenableFuture<Void>> futures = OvsInterfaceStateRemoveHelper.removeInterfaceStateConfiguration(idManager, mdsalApiManager, alivenessMonitorService,
+
+ List<ListenableFuture<Void>> futures = null;
+ //VM Migration: Skip OFPPR_DELETE event received after OFPPR_ADD for same interface from Older DPN
+ if (isParentInterface && isNetworkEvent) {
+ nodeConnectorIdOld = IfmUtil.getNodeConnectorIdFromInterface(interfaceName, dataBroker);
+ if(nodeConnectorIdOld != null && !nodeConnectorIdNew.equals(nodeConnectorIdOld)) {
+ LOG.debug("Dropping the NodeConnector Remove Event for the interface: {}, {}, {}", interfaceName, nodeConnectorIdNew, nodeConnectorIdOld);
+ return futures;
+ }
+ }
+
+ futures = OvsInterfaceStateRemoveHelper.removeInterfaceStateConfiguration(idManager, mdsalApiManager, alivenessMonitorService,
nodeConnectorIdNew, nodeConnectorIdOld, dataBroker, interfaceName, fcNodeConnectorOld, isNodePresent);
List<InterfaceChildEntry> interfaceChildEntries = getInterfaceChildEntries(dataBroker, interfaceName);
for (InterfaceChildEntry interfaceChildEntry : interfaceChildEntries) {
// Fetch all interfaces on this port and trigger remove worker for each of them
- InterfaceStateRemoveWorker interfaceStateRemoveWorker = new InterfaceStateRemoveWorker(idManager,
- nodeConnectorIdNew, nodeConnectorIdOld, fcNodeConnectorOld, interfaceChildEntry.getChildInterface(), isNodePresent);
+ InterfaceStateRemoveWorker interfaceStateRemoveWorker = new InterfaceStateRemoveWorker(idManager, nodeConnectorIdNew,
+ nodeConnectorIdOld, fcNodeConnectorOld, interfaceChildEntry.getChildInterface(), isNodePresent, isNetworkEvent, false);
DataStoreJobCoordinator.getInstance().enqueueJob(interfaceName, interfaceStateRemoveWorker);
}
return futures;
import com.google.common.util.concurrent.ListenableFuture;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
import org.opendaylight.genius.datastoreutils.AsyncDataChangeListenerBase;
+import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
import org.opendaylight.genius.interfacemanager.IfmConstants;
import org.opendaylight.genius.interfacemanager.renderer.ovs.statehelpers.OvsInterfaceTopologyStateAddHelper;
import org.opendaylight.genius.interfacemanager.renderer.ovs.statehelpers.OvsInterfaceTopologyStateRemoveHelper;
import org.opendaylight.genius.interfacemanager.renderer.ovs.statehelpers.OvsInterfaceTopologyStateUpdateHelper;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
import java.util.List;
import java.util.concurrent.Callable;
-public class InterfaceTopologyStateListener extends AsyncDataChangeListenerBase<OvsdbBridgeAugmentation, InterfaceTopologyStateListener> {
+public class InterfaceTopologyStateListener extends AsyncDataTreeChangeListenerBase<OvsdbBridgeAugmentation, InterfaceTopologyStateListener> {
private static final Logger LOG = LoggerFactory.getLogger(InterfaceTopologyStateListener.class);
private DataBroker dataBroker;
}
@Override
- protected DataChangeListener getDataChangeListener() {
+ protected InterfaceTopologyStateListener getDataTreeChangeListener() {
return InterfaceTopologyStateListener.this;
}
- @Override
- protected AsyncDataBroker.DataChangeScope getDataChangeScope() {
- return AsyncDataBroker.DataChangeScope.ONE;
- }
-
@Override
protected void remove(InstanceIdentifier<OvsdbBridgeAugmentation> identifier, OvsdbBridgeAugmentation bridgeOld) {
LOG.debug("Received Remove DataChange Notification for identifier: {}, ovsdbBridgeAugmentation: {}",
OvsdbBridgeAugmentation bridgeNew) {
LOG.debug("Received Update DataChange Notification for identifier: {}, ovsdbBridgeAugmentation old: {}, new: {}.",
identifier, bridgeOld, bridgeNew);
- if(bridgeOld.getDatapathId()== null && bridgeNew.getDatapathId()!= null){
+ DatapathId oldDpid = bridgeOld.getDatapathId();
+ DatapathId newDpid = bridgeNew.getDatapathId();
+ if(oldDpid == null && newDpid != null){
DataStoreJobCoordinator jobCoordinator = DataStoreJobCoordinator.getInstance();
RendererStateAddWorker rendererStateAddWorker = new RendererStateAddWorker(identifier, bridgeNew);
jobCoordinator.enqueueJob(bridgeNew.getBridgeName().getValue(), rendererStateAddWorker, IfmConstants.JOB_MAX_RETRIES);
- } else if(!bridgeOld.getDatapathId().equals(bridgeNew.getDatapathId())){
+ } else if(oldDpid != null && !oldDpid.equals(newDpid)){
DataStoreJobCoordinator jobCoordinator = DataStoreJobCoordinator.getInstance();
RendererStateUpdateWorker rendererStateAddWorker = new RendererStateUpdateWorker(identifier, bridgeNew, bridgeOld);
jobCoordinator.enqueueJob(bridgeNew.getBridgeName().getValue(), rendererStateAddWorker, IfmConstants.JOB_MAX_RETRIES);
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
+import org.opendaylight.genius.datastoreutils.AsyncClusteredDataTreeChangeListenerBase;
import org.opendaylight.genius.datastoreutils.AsyncDataChangeListenerBase;
import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
import org.opendaylight.genius.interfacemanager.IfmConstants;
+import org.opendaylight.genius.interfacemanager.commons.InterfaceManagerCommonUtils;
import org.opendaylight.genius.interfacemanager.renderer.ovs.statehelpers.OvsInterfaceTopologyStateUpdateHelper;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
import java.util.List;
import java.util.concurrent.Callable;
-public class TerminationPointStateListener extends AsyncDataChangeListenerBase<OvsdbTerminationPointAugmentation, TerminationPointStateListener> {
+public class TerminationPointStateListener extends AsyncClusteredDataTreeChangeListenerBase<OvsdbTerminationPointAugmentation, TerminationPointStateListener> {
private static final Logger LOG = LoggerFactory.getLogger(TerminationPointStateListener.class);
private DataBroker dataBroker;
}
@Override
- protected DataChangeListener getDataChangeListener() {
+ protected TerminationPointStateListener getDataTreeChangeListener() {
return TerminationPointStateListener.this;
}
- @Override
- protected AsyncDataBroker.DataChangeScope getDataChangeScope() {
- return AsyncDataBroker.DataChangeScope.SUBTREE;
- }
-
@Override
protected void remove(InstanceIdentifier<OvsdbTerminationPointAugmentation> identifier,
OvsdbTerminationPointAugmentation tpOld) {
+ LOG.debug("Received remove DataChange Notification for ovsdb termination point {}", tpOld.getName());
+ if (tpOld.getInterfaceBfdStatus() != null) {
+ LOG.debug("Received termination point removed notification with bfd status values {}", tpOld.getName());
+ DataStoreJobCoordinator jobCoordinator = DataStoreJobCoordinator.getInstance();
+ RendererStateRemoveWorker rendererStateRemoveWorker = new RendererStateRemoveWorker(tpOld);
+ jobCoordinator.enqueueJob(tpOld.getName(), rendererStateRemoveWorker);
+ }
}
@Override
terminationPointNew);
}
}
+
+ private class RendererStateRemoveWorker implements Callable<List<ListenableFuture<Void>>> {
+ OvsdbTerminationPointAugmentation terminationPointOld;
+
+
+ public RendererStateRemoveWorker(OvsdbTerminationPointAugmentation tpNew) {
+ this.terminationPointOld = tpNew;
+ }
+
+ @Override
+ public List<ListenableFuture<Void>> call() throws Exception {
+ LOG.debug("Removing bfd state from cache, if any, for {}", terminationPointOld.getName());
+ InterfaceManagerCommonUtils.removeBfdStateFromCache(terminationPointOld.getName());
+ return null;
+ }
+ }
}
return futures;
}
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface =
+ InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceName, dataBroker);
+
+ // For tunnels, derive the final opstate based on the bfd tunnel monitoring status
+ if(modifyTunnel(iface, opstateModified) && InterfaceManagerCommonUtils.checkIfBfdStateIsDown(iface.getName())){
+ operStatusNew = Interface.OperStatus.Down;
+ opstateModified = operStatusNew.equals(operStatusOld);
+ }
+
+ if (!opstateModified && !hardwareAddressModified) {
+ LOG.debug("If State entry for port: {} Not Modified.", interfaceName);
+ return futures;
+ }
InterfaceBuilder ifaceBuilder = new InterfaceBuilder();
if (hardwareAddressModified) {
LOG.debug("Hw-Address Modified for Port: {}", interfaceName);
ifaceBuilder.setPhysAddress(physAddress);
}
// modify the attributes in interface operational DS
- org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface =
- handleInterfaceStateUpdates(interfaceName, transaction, dataBroker,
- ifaceBuilder, opstateModified, flowCapableNodeConnectorNew.getName(), operStatusNew);
+ handleInterfaceStateUpdates(iface, transaction, dataBroker,
+ ifaceBuilder, opstateModified, interfaceName, flowCapableNodeConnectorNew.getName(), operStatusNew);
// start/stop monitoring based on opState
if(modifyTunnel(iface, opstateModified)){
InterfaceBuilder ifaceBuilder = new InterfaceBuilder();
org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface =
- handleInterfaceStateUpdates(interfaceName,transaction, dataBroker,
- ifaceBuilder, true, flowCapableNodeConnector.getName(),
+ InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceName, dataBroker);
+ handleInterfaceStateUpdates(iface,transaction, dataBroker,
+ ifaceBuilder, true, interfaceName, flowCapableNodeConnector.getName(),
Interface.OperStatus.Unknown);
if (InterfaceManagerCommonUtils.isTunnelInterface(iface)){
handleTunnelMonitoringUpdates(alivenessMonitorService, dataBroker, iface.getAugmentation(IfTunnel.class),
return operStatus;
}
- public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface
- handleInterfaceStateUpdates(String interfaceName, WriteTransaction transaction,
- DataBroker dataBroker, InterfaceBuilder ifaceBuilder, boolean opStateModified,
- String portName,
- org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus opState){
- LOG.debug("updating interface state entry for {}", interfaceName);
- InstanceIdentifier<Interface> ifStateId = IfmUtil.buildStateInterfaceId(interfaceName);
- ifaceBuilder.setKey(new InterfaceKey(interfaceName));
- org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface =
- InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceName, dataBroker);
+ public static void handleInterfaceStateUpdates(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface,
+ WriteTransaction transaction, DataBroker dataBroker, InterfaceBuilder ifaceBuilder, boolean opStateModified,
+ String interfaceName, String portName, Interface.OperStatus opState){
// if interface config DS is null, do the update only for the lower-layer-interfaces
// which have no corresponding config entries
- if(iface == null && interfaceName != portName){
- return null;
+ if(iface == null && !interfaceName.equals(portName)) {
+ return;
}
+ LOG.debug("updating interface state entry for {}", interfaceName);
+ InstanceIdentifier<Interface> ifStateId = IfmUtil.buildStateInterfaceId(interfaceName);
+ ifaceBuilder.setKey(new InterfaceKey(interfaceName));
if (modifyOpState(iface, opStateModified)) {
LOG.debug("updating interface oper status as {} for {}", opState.name(), interfaceName);
ifaceBuilder.setOperStatus(opState);
}
transaction.merge(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build(), false);
-
- return iface;
}
public static void handleTunnelMonitoringUpdates(AlivenessMonitorService alivenessMonitorService, DataBroker dataBroker,
import com.google.common.util.concurrent.ListenableFuture;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
import org.opendaylight.genius.interfacemanager.IfmUtil;
import org.opendaylight.genius.interfacemanager.commons.InterfaceManagerCommonUtils;
import org.opendaylight.genius.interfacemanager.commons.InterfaceMetaUtils;
+import org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.IfmClusterUtils;
import org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.SouthboundUtils;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceBfdStatus;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.Callable;
public class OvsInterfaceTopologyStateUpdateHelper {
private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceTopologyStateUpdateHelper.class);
return futures;
}
- public static List<ListenableFuture<Void>> updateTunnelState(DataBroker dataBroker,
- OvsdbTerminationPointAugmentation terminationPointNew) {
- List<ListenableFuture<Void>> futures = new ArrayList<ListenableFuture<Void>>();
-
- if (InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(terminationPointNew.getName(), dataBroker) == null) {
- return futures;
+ public static List<ListenableFuture<Void>> updateTunnelState(final DataBroker dataBroker,
+ final OvsdbTerminationPointAugmentation terminationPointNew) {
+ final Interface interfaceState = InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(terminationPointNew.getName(), dataBroker);
+ final Interface.OperStatus interfaceOperStatus = getTunnelOpState(terminationPointNew.getInterfaceBfdStatus());
+ InterfaceManagerCommonUtils.addBfdStateToCache(terminationPointNew.getName(), interfaceOperStatus);
+ if(interfaceState != null && interfaceState.getOperStatus() != Interface.OperStatus.Unknown) {
+ IfmClusterUtils.runOnlyInLeaderNode(new Runnable() {
+ @Override
+ public void run() {
+ DataStoreJobCoordinator jobCoordinator = DataStoreJobCoordinator.getInstance();
+ jobCoordinator.enqueueJob(terminationPointNew.getName(), new Callable<List<ListenableFuture<Void>>>() {
+ @Override
+ public List<ListenableFuture<Void>> call() throws Exception {
+ // update opstate of interface if TEP has gone down/up as a result of BFD monitoring
+ final List<ListenableFuture<Void>> futures = new ArrayList<ListenableFuture<Void>>();
+ LOG.debug("updating tunnel state for interface {}", terminationPointNew.getName());
+ WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
+ InterfaceManagerCommonUtils.updateOpState(transaction, terminationPointNew.getName(), interfaceOperStatus);
+ futures.add(transaction.submit());
+ return futures;
+ }
+ });
+ }
+ });
}
- // update opstate of interface if TEP has gone down/up as a result of BFD monitoring
- LOG.debug("updating tunnel state for interface {}", terminationPointNew.getName());
- WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
- InterfaceManagerCommonUtils.updateOpState(transaction, terminationPointNew.getName(), getTunnelOpState(terminationPointNew.getInterfaceBfdStatus()));
- futures.add(transaction.submit());
- return futures;
+ return null;
}
private static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.genius.utils.batching.ResourceHandler;
-//import org.opendaylight.genius.utils.batching.SubTransaction;
-//import org.opendaylight.genius.utils.batching.SubTransactionImpl;
+import org.opendaylight.genius.utils.batching.SubTransaction;
+import org.opendaylight.genius.utils.batching.SubTransactionImpl;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import java.util.List;
-public class BatchHandler implements ResourceHandler {
- public void update(WriteTransaction tx, LogicalDatastoreType datastoreType, InstanceIdentifier identifier, Object original, Object update) {
+public class InterfaceBatchHandler implements ResourceHandler {
+ public void update(WriteTransaction tx, LogicalDatastoreType datastoreType, InstanceIdentifier identifier, Object original, Object update,List<SubTransaction> transactionObjects) {
if (update != null && !(update instanceof DataObject)) {
return;
}
}
tx.merge(datastoreType, identifier, (DataObject)update, true);
- // TODO enable retries
- //buildSubTransactions(transactionObjects, identifier, update, SubTransaction.UPDATE);
+ buildSubTransactions(transactionObjects, identifier, update, SubTransaction.UPDATE);
}
- public void create(WriteTransaction tx, LogicalDatastoreType datastoreType, InstanceIdentifier identifier, Object data) {
+ public void create(WriteTransaction tx, LogicalDatastoreType datastoreType, InstanceIdentifier identifier, Object data,List<SubTransaction> transactionObjects) {
if (data != null && !(data instanceof DataObject)) {
return;
}
return;
}
tx.put(datastoreType, identifier, (DataObject)data, true);
- // TODO enable retries
- //buildSubTransactions(transactionObjects, identifier, data, SubTransaction.CREATE);
+
+ buildSubTransactions(transactionObjects, identifier, data, SubTransaction.CREATE);
}
- public void delete(WriteTransaction tx, LogicalDatastoreType datastoreType, InstanceIdentifier identifier, Object data) {
+ public void delete(WriteTransaction tx, LogicalDatastoreType datastoreType, InstanceIdentifier identifier, Object data,List<SubTransaction> transactionObjects) {
if (data != null && !(data instanceof DataObject)) {
return;
}
}
tx.delete(datastoreType, identifier);
- // TODO enable retries
- //buildSubTransactions(transactionObjects, identifier, data, SubTransaction.DELETE);
+ buildSubTransactions(transactionObjects, identifier, data, SubTransaction.DELETE);
}
public DataBroker getResourceBroker() {
return LogicalDatastoreType.CONFIGURATION;
}
- //TODO
- /*private void buildSubTransactions(List<SubTransaction> transactionObjects, InstanceIdentifier identifier,
+ private void buildSubTransactions(List<SubTransaction> transactionObjects, InstanceIdentifier identifier,
Object data, short subTransactionType) {
// enable retries
SubTransaction subTransaction = new SubTransactionImpl();
subTransaction.setInstance(data);
subTransaction.setAction(subTransactionType);
transactionObjects.add(subTransaction);
- }*/
+ }
}
static final String BFD_PARAM_CPATH_DOWN = "cpath_down";
static final String BFD_PARAM_CHECK_TNL_KEY = "check_tnl_key";
- // bfd params
+ // BFD parameters
public static final String BFD_OP_STATE = "state";
public static final String BFD_STATE_UP = "up";
private static final String BFD_MIN_RX_VAL = "1000";
private static final String TUNNEL_OPTIONS_KEY = "key";
private static final String TUNNEL_OPTIONS_LOCAL_IP = "local_ip";
private static final String TUNNEL_OPTIONS_REMOTE_IP = "remote_ip";
+ private static final String TUNNEL_OPTIONS_DESTINATION_PORT = "dst_port";
- // Options for VxLAN-GPE + NSH tunnels
+ // Option values for VxLAN-GPE + NSH tunnels
private static final String TUNNEL_OPTIONS_EXTS = "exts";
private static final String TUNNEL_OPTIONS_NSI = "nsi";
private static final String TUNNEL_OPTIONS_NSP = "nsp";
private static final String TUNNEL_OPTIONS_NSHC3 = "nshc3";
private static final String TUNNEL_OPTIONS_NSHC4 = "nshc4";
- // Values for VxLAN-GPE + NSH tunnels
+ // Option values for VxLAN-GPE + NSH tunnels
private static final String TUNNEL_OPTIONS_VALUE_FLOW = "flow";
private static final String TUNNEL_OPTIONS_VALUE_GPE = "gpe";
+ // UDP port for VxLAN-GPE Tunnels
+ private static final String TUNNEL_OPTIONS_VALUE_GPE_DESTINATION_PORT = "4880";
+ //
public static final TopologyId OVSDB_TOPOLOGY_ID = new TopologyId(new Uri("ovsdb:1"));
// To keep the mapping between Tunnel Types and Tunnel Interfaces
}
/*
- * add all tunnels ports corresponding to the bridge to the topology config
+ * Add all tunnels ports corresponding to the bridge to the topology config
* DS
*/
public static void addAllPortsToBridge(BridgeEntry bridgeEntry, DataBroker dataBroker,
options.put(TUNNEL_OPTIONS_NSHC2, TUNNEL_OPTIONS_VALUE_FLOW);
options.put(TUNNEL_OPTIONS_NSHC3, TUNNEL_OPTIONS_VALUE_FLOW);
options.put(TUNNEL_OPTIONS_NSHC4, TUNNEL_OPTIONS_VALUE_FLOW);
+ // VxLAN-GPE interfaces will not use the default UDP port to avoid problems with other meshes
+ options.put(TUNNEL_OPTIONS_DESTINATION_PORT, TUNNEL_OPTIONS_VALUE_GPE_DESTINATION_PORT);
}
addTerminationPoint(bridgeIid, portName, vlanId, type, options, ifTunnel);
}
return true;
}
return false;
-
}
}
BigInteger dpId = null;
InterfaceKey interfaceKey = new InterfaceKey(interfaceName);
Interface interfaceInfo = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
+ if (interfaceInfo == null) {
+ rpcResultBuilder = getRpcErrorResultForGetDpnIdRpc(interfaceName, "missing Interface in Config DataStore");
+ return Futures.immediateFuture(rpcResultBuilder.build());
+ }
if (Tunnel.class.equals(interfaceInfo.getType())) {
ParentRefs parentRefs = interfaceInfo.getAugmentation(ParentRefs.class);
dpId = parentRefs.getDatapathNodeIdentifier();
} else {
org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState =
InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(interfaceName, dataBroker);
- String lowerLayerIf = ifState.getLowerLayerIf().get(0);
- NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
- dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId));
+ if (ifState != null) {
+ String lowerLayerIf = ifState.getLowerLayerIf().get(0);
+ NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
+ dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId));
+ } else {
+ rpcResultBuilder = getRpcErrorResultForGetDpnIdRpc(interfaceName, "missing Interface-state");
+ return Futures.immediateFuture(rpcResultBuilder.build());
+ }
}
GetDpidFromInterfaceOutputBuilder output = new GetDpidFromInterfaceOutputBuilder().setDpid(
(dpId));
rpcResultBuilder = RpcResultBuilder.success();
rpcResultBuilder.withResult(output.build());
} catch (Exception e) {
- LOG.error("Retrieval of datapath id for the key {} failed due to {}", interfaceName, e);
- rpcResultBuilder = RpcResultBuilder.failed();
+ rpcResultBuilder = getRpcErrorResultForGetDpnIdRpc(interfaceName, e.getMessage());
}
return Futures.immediateFuture(rpcResultBuilder.build());
}
+ private RpcResultBuilder<GetDpidFromInterfaceOutput> getRpcErrorResultForGetDpnIdRpc(String interfaceName, String errMsg) {
+ errMsg = String.format("Retrieval of datapath id for the key {%s} failed due to %s", interfaceName, errMsg);
+ LOG.error(errMsg);
+ RpcResultBuilder<GetDpidFromInterfaceOutput> rpcResultBuilder = RpcResultBuilder.<GetDpidFromInterfaceOutput>failed().withError(RpcError.ErrorType.APPLICATION, errMsg);
+ return rpcResultBuilder;
+ }
+
@Override
public Future<RpcResult<Void>> createTerminatingServiceActions(final CreateTerminatingServiceActionsInput input) {
final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
try {
InterfaceKey interfaceKey = new InterfaceKey(interfaceName);
Interface interfaceInfo = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
-
+ if (interfaceInfo == null) {
+ String errMsg = String.format("Retrieval of Interface Type for the key {%s} failed due to missing Interface in Config DataStore", interfaceName);
+ LOG.error(errMsg);
+ rpcResultBuilder = RpcResultBuilder.<GetInterfaceTypeOutput>failed().withError(RpcError.ErrorType.APPLICATION, errMsg);
+ return Futures.immediateFuture(rpcResultBuilder.build());
+ }
GetInterfaceTypeOutputBuilder output = new GetInterfaceTypeOutputBuilder().setInterfaceType(interfaceInfo.getType());
rpcResultBuilder = RpcResultBuilder.success();
rpcResultBuilder.withResult(output.build());
try {
InterfaceKey interfaceKey = new InterfaceKey(interfaceName);
Interface interfaceInfo = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
-
+ if (interfaceInfo == null) {
+ String errMsg = String.format("Retrieval of Tunnel Type for the key {%s} failed due to missing Interface in Config DataStore", interfaceName);
+ LOG.error(errMsg);
+ rpcResultBuilder = RpcResultBuilder.<GetTunnelTypeOutput>failed().withError(RpcError.ErrorType.APPLICATION, errMsg);
+ return Futures.immediateFuture(rpcResultBuilder.build());
+ }
if (Tunnel.class.equals(interfaceInfo.getType())) {
IfTunnel tnl = interfaceInfo.getAugmentation(IfTunnel.class);
Class <? extends TunnelTypeBase> tun_type = tnl.getTunnelInterfaceType();
long portNo = 0;
org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState =
InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(interfaceName, dataBroker);
- String lowerLayerIf = ifState.getLowerLayerIf().get(0);
- NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
- dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId));
- portNo = Long.valueOf(IfmUtil.getPortNoFromNodeConnectorId(nodeConnectorId));
- // FIXME Assuming portName and interfaceName are same
- GetPortFromInterfaceOutputBuilder output = new GetPortFromInterfaceOutputBuilder().setDpid(dpId).
- setPortname(interfaceName).setPortno(Long.valueOf(portNo));
- rpcResultBuilder = RpcResultBuilder.success();
- rpcResultBuilder.withResult(output.build());
+ if (ifState != null) {
+ String lowerLayerIf = ifState.getLowerLayerIf().get(0);
+ NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
+ dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId));
+ portNo = Long.valueOf(IfmUtil.getPortNoFromNodeConnectorId(nodeConnectorId));
+ // FIXME Assuming portName and interfaceName are same
+ GetPortFromInterfaceOutputBuilder output = new GetPortFromInterfaceOutputBuilder().setDpid(dpId).
+ setPortname(interfaceName).setPortno(Long.valueOf(portNo));
+ rpcResultBuilder = RpcResultBuilder.success();
+ rpcResultBuilder.withResult(output.build());
+ } else {
+ rpcResultBuilder = getRpcErrorResultForGetPortRpc(interfaceName, "missing Interface state");
+ }
}catch(Exception e){
- LOG.error("Retrieval of lport tag for the key {} failed due to {}" ,input.getIntfName(), e);
- rpcResultBuilder = RpcResultBuilder.failed();
+ rpcResultBuilder = getRpcErrorResultForGetPortRpc(interfaceName, e.getMessage());
}
return Futures.immediateFuture(rpcResultBuilder.build());
}
+ private RpcResultBuilder<GetPortFromInterfaceOutput> getRpcErrorResultForGetPortRpc(String interfaceName, String errMsg) {
+ errMsg = String.format("Retrieval of Port for the key {%s} failed due to %s", interfaceName, errMsg);
+ LOG.error(errMsg);
+ RpcResultBuilder<GetPortFromInterfaceOutput> rpcResultBuilder = RpcResultBuilder.<GetPortFromInterfaceOutput>failed().withError(RpcError.ErrorType.APPLICATION, errMsg);
+ return rpcResultBuilder;
+ }
+
@Override
public Future<RpcResult<GetNodeconnectorIdFromInterfaceOutput>> getNodeconnectorIdFromInterface(GetNodeconnectorIdFromInterfaceInput input) {
String interfaceName = input.getIntfName();
import java.util.ArrayList;
import java.util.List;
import org.junit.After;
+import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.genius.interfacemanager.IfmUtil;
+import org.opendaylight.genius.interfacemanager.commons.InterfaceManagerCommonUtils;
import org.opendaylight.genius.interfacemanager.commons.InterfaceMetaUtils;
import org.opendaylight.genius.interfacemanager.renderer.hwvtep.utilities.SouthboundUtils;
import org.opendaylight.genius.interfacemanager.renderer.ovs.statehelpers.OvsInterfaceTopologyStateAddHelper;
List<InterfaceBfdStatus> interfaceBfdStatus = new ArrayList<>();
interfaceBfdStatus.add(new InterfaceBfdStatusBuilder().setBfdStatusKey(SouthboundUtils.BFD_OP_STATE).setBfdStatusValue(SouthboundUtils.BFD_STATE_UP).build());
-
- org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState = new InterfaceBuilder().setKey(new InterfaceKey(InterfaceManagerTestUtil.interfaceName)).build();
- Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> expectedInterface = Optional.of(ifState);
+ Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> expectedInterface = Optional.absent();
doReturn(Futures.immediateCheckedFuture(expectedInterface)).when(mockReadTx).read(
LogicalDatastoreType.OPERATIONAL, interfaceStateIdentifier);
updateHelper.updateTunnelState(dataBroker, newTerminationPoint);
//verify
- InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId =
- IfmUtil.buildStateInterfaceId(InterfaceManagerTestUtil.tunnelInterfaceName);
- InterfaceBuilder ifaceBuilder = new InterfaceBuilder().setOperStatus(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Down);
- ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(InterfaceManagerTestUtil.tunnelInterfaceName));
- verify(mockWriteTx).merge(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build(), false);
+ Assert.assertNotNull(InterfaceManagerCommonUtils.getBfdStateFromCache(newTerminationPoint.getName()));
}
}
*/
public class TransportZoneListener extends AsyncDataTreeChangeListenerBase<TransportZone, TransportZoneListener> implements AutoCloseable{
private static final Logger LOG = LoggerFactory.getLogger(TransportZoneListener.class);
- private DataBroker dataBroker;
- private IdManagerService idManagerService;
+ private final DataBroker dataBroker;
+ private final IdManagerService idManagerService;
private IMdsalApiManager mdsalManager;
private ITMManager itmManager;
List<DPNTEPsInfo> opDpnList = createDPNTepInfo(tzOld);
List<HwVtep> hwVtepList = createhWVteps(tzOld);
LOG.trace("Delete: Invoking deleteTunnels in ItmManager with DpnList {}", opDpnList);
- if(opDpnList.size()>0 || hwVtepList.size()>0) {
+ if(!opDpnList.isEmpty() || !hwVtepList.isEmpty()) {
LOG.trace("Delete: Invoking ItmManager");
LOG.trace("Delete: Invoking ItmManager with hwVtep List {} " , hwVtepList);
// itmManager.deleteTunnels(opDpnList);
LOG.trace("newcopy"+newDpnTepsListcopy);
LOG.trace("oldcopy Size "+oldDpnTepsList.size());
LOG.trace("newcopy Size "+newDpnTepsList.size());
- if(newDpnTepsList.size() > 0) {
+ if(!newDpnTepsList.isEmpty()) {
LOG.trace( "Adding TEPs " );
ItmTepAddWorker addWorker = new ItmTepAddWorker(newDpnTepsList, Collections.<HwVtep>emptyList(), dataBroker, idManagerService, mdsalManager);
coordinator.enqueueJob(tzNew.getZoneName(), addWorker);
}
- if(oldDpnTepsList.size() > 0) {
+ if(!oldDpnTepsList.isEmpty()) {
LOG.trace( "Removing TEPs " );
ItmTepRemoveWorker removeWorker = new ItmTepRemoveWorker(oldDpnTepsList, Collections.<HwVtep>emptyList(),
tzOld, dataBroker, idManagerService, mdsalManager);
LOG.trace("newHwList" + newHwList);
LOG.trace("oldHwListcopy" + oldHwListcopy);
LOG.trace("newHwListcopy" + newHwListcopy);
- if(newHwList.size() > 0) {
+ if(!newHwList.isEmpty()) {
LOG.trace( "Adding HW TEPs " );
ItmTepAddWorker addWorker = new ItmTepAddWorker(Collections.<DPNTEPsInfo>emptyList(), newHwList, dataBroker, idManagerService, mdsalManager);
coordinator.enqueueJob(tzNew.getZoneName(), addWorker);
}
- if (oldHwList.size() > 0) {
+ if (!oldHwList.isEmpty()) {
LOG.trace("Removing HW TEPs ");
ItmTepRemoveWorker removeWorker = new ItmTepRemoveWorker(Collections.<DPNTEPsInfo>emptyList(), oldHwList,
tzOld, dataBroker, idManagerService, mdsalManager);
coordinator.enqueueJob(tzNew.getZoneName(), removeWorker);
}
-
}
@Override
List<DPNTEPsInfo> opDpnList = createDPNTepInfo(tzNew);
List<HwVtep> hwVtepList = createhWVteps(tzNew);
LOG.trace("Add: Operational dpnTepInfo - Before invoking ItmManager {}", opDpnList);
- if(opDpnList.size()>0 || hwVtepList.size()>0) {
+ if(!opDpnList.isEmpty() || !hwVtepList.isEmpty()) {
LOG.trace("Add: Invoking ItmManager with DPN List {} " , opDpnList);
LOG.trace("Add: Invoking ItmManager with hwVtep List {} " , hwVtepList);
//itmManager.build_all_tunnels(opDpnList);
}
}
- private List<DPNTEPsInfo> createDPNTepInfo(TransportZone transportZone){
-
+ private List<DPNTEPsInfo> createDPNTepInfo(TransportZone transportZone) {
Map<BigInteger, List<TunnelEndPoints>> mapDPNToTunnelEndpt = new ConcurrentHashMap<>();
List<DPNTEPsInfo> dpnTepInfo = new ArrayList<>();
// List<TransportZone> transportZoneList = transportZones.getTransportZone();
// for(TransportZone transportZone : transportZoneList) {
- String zone_name = transportZone.getZoneName();
- Class<? extends TunnelTypeBase> tunnel_type = transportZone.getTunnelType();
- LOG.trace("Transport Zone_name: {}", zone_name);
+ String zoneName = transportZone.getZoneName();
+ Class<? extends TunnelTypeBase> tunnelType = transportZone.getTunnelType();
+ LOG.trace("Transport Zone_name: {}", zoneName);
List<Subnets> subnetsList = transportZone.getSubnets();
if(subnetsList!=null){
for (Subnets subnet : subnetsList) {
LOG.trace("DpnID: {}, port: {}, ipAddress: {}", dpnID, port, ipAddress);
TunnelEndPoints tunnelEndPoints =
ItmUtils.createTunnelEndPoints(dpnID, ipAddress, port, vlanID, ipPrefix,
- gatewayIP, zone_name, tunnel_type);
+ gatewayIP, zoneName, tunnelType);
List<TunnelEndPoints> tunnelEndPointsList = mapDPNToTunnelEndpt.get(dpnID);
if (tunnelEndPointsList != null) {
LOG.trace("Existing DPN info list in the Map: {} ", dpnID);
}
}
//}
- if(mapDPNToTunnelEndpt.size()>0){
+ if(!mapDPNToTunnelEndpt.isEmpty()){
Set<BigInteger> keys = mapDPNToTunnelEndpt.keySet();
LOG.trace("List of dpns in the Map: {} ", keys);
for(BigInteger key: keys){
List<DeviceVteps> deviceVtepsList = subnet.getDeviceVteps();
if (deviceVtepsList != null) {
for (DeviceVteps vteps : deviceVtepsList) {
- String topo_id = vteps.getTopologyId();
- String node_id = vteps.getNodeId();
+ String topologyId = vteps.getTopologyId();
+ String nodeId = vteps.getNodeId();
IpAddress ipAddress = vteps.getIpAddress();
- LOG.trace("topo-id: {}, node-id: {}, ipAddress: {}", topo_id, node_id, ipAddress);
+ LOG.trace("topo-id: {}, node-id: {}, ipAddress: {}", topologyId, nodeId, ipAddress);
//TunnelEndPoints tunnelEndPoints = ItmUtils.createTunnelEndPoints(dpnID, ipAddress, port, vlanID, ipPrefix, gatewayIP, zone_name, tunnel_type);
- HwVtep hwVtep = ItmUtils.createHwVtepObject(topo_id, node_id, ipAddress, ipPrefix, gatewayIP, vlanID, tunnel_type, transportZone);
+ HwVtep hwVtep = ItmUtils.createHwVtepObject(topologyId, nodeId, ipAddress, ipPrefix, gatewayIP, vlanID, tunnel_type, transportZone);
if (hwVtepsList != null) {
LOG.trace("Existing hwVteps");
<artifactId>mdsalutil-api</artifactId>
<version>0.2.0-SNAPSHOT</version>
<packaging>bundle</packaging>
+
<dependencies>
<dependency>
<groupId>org.opendaylight.openflowplugin.model</groupId>
<artifactId>utils.config</artifactId>
<version>${genius.ovsdb.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.infrautils</groupId>
+ <artifactId>inject</artifactId>
+ <version>${genius.infrautils.version}</version>
+ </dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava-testlib</artifactId>
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
+import javax.annotation.PreDestroy;
import org.opendaylight.controller.md.sal.binding.api.ClusteredDataChangeListener;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
}
@Override
+ @PreDestroy
public void close() throws Exception {
if (listenerRegistration != null) {
try {
import org.slf4j.LoggerFactory;
import java.util.Collection;
-import java.util.concurrent.Callable;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
+import javax.annotation.PreDestroy;
public abstract class AsyncClusteredDataTreeChangeListenerBase<T extends DataObject, K extends ClusteredDataTreeChangeListener> implements ClusteredDataTreeChangeListener<T>, AutoCloseable {
private static final Logger LOG = LoggerFactory.getLogger(AsyncClusteredDataTreeChangeListenerBase.class);
final DataTreeIdentifier<T> treeId = new DataTreeIdentifier<>(dsType, getWildCardPath());
try {
TaskRetryLooper looper = new TaskRetryLooper(STARTUP_LOOP_TICK, STARTUP_LOOP_MAX_RETRIES);
- listenerRegistration = looper.loopUntilNoException(new Callable<ListenerRegistration<K>>() {
- @Override
- public ListenerRegistration<K> call() throws Exception {
- return db.registerDataTreeChangeListener(treeId, getDataTreeChangeListener());
- }
- });
+ listenerRegistration = looper.loopUntilNoException(() -> db.registerDataTreeChangeListener(treeId, getDataTreeChangeListener()));
} catch (final Exception e) {
LOG.warn("{}: Data Tree Change listener registration failed.", eventClazz.getName());
LOG.debug("{}: Data Tree Change listener registration failed: {}", eventClazz.getName(), e);
}
@Override
+ @PreDestroy
public void close() throws Exception {
if (listenerRegistration != null) {
try {
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
+import javax.annotation.PreDestroy;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
}
@Override
+ @PreDestroy
public void close() throws Exception {
if (listenerRegistration != null) {
try {
import com.google.common.base.Preconditions;
import java.util.Collection;
-import java.util.concurrent.Callable;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
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.DataTreeChangeListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public abstract class AsyncDataTreeChangeListenerBase<T extends DataObject, K extends DataTreeChangeListener> implements DataTreeChangeListener<T>, AutoCloseable {
+public abstract class AsyncDataTreeChangeListenerBase<T extends DataObject, K extends DataTreeChangeListener>
+ implements DataTreeChangeListener<T>, AutoCloseable {
+
private static final Logger LOG = LoggerFactory.getLogger(AsyncDataTreeChangeListenerBase.class);
private static final int DATATREE_CHANGE_HANDLER_THREAD_POOL_CORE_SIZE = 1;
final DataTreeIdentifier<T> treeId = new DataTreeIdentifier<>(dsType, getWildCardPath());
try {
TaskRetryLooper looper = new TaskRetryLooper(STARTUP_LOOP_TICK, STARTUP_LOOP_MAX_RETRIES);
- listenerRegistration = looper.loopUntilNoException(new Callable<ListenerRegistration<K>>() {
- @Override
- public ListenerRegistration<K> call() throws Exception {
- return db.registerDataTreeChangeListener(treeId, getDataTreeChangeListener());
- }
- });
+ listenerRegistration = looper.loopUntilNoException(() -> db.registerDataTreeChangeListener(treeId, getDataTreeChangeListener()));
} catch (final Exception e) {
LOG.warn("{}: Data Tree Change listener registration failed.", eventClazz.getName());
LOG.debug("{}: Data Tree Change listener registration failed: {}", eventClazz.getName(), e);
}
}
+ /**
+ * Subclasses override this and place initialization logic here, notably
+ * calls to registerListener(). Note that the overriding method MUST repeat
+ * the PostConstruct annotation, because JSR 250 specifies that lifecycle
+ * methods "are called unless a subclass of the declaring class overrides
+ * the method without repeating the annotation". (The blueprint-maven-plugin
+ * would gen. XML which calls PostConstruct annotated methods even if they are
+ * in a subclass without repeating the annotation, but this is wrong and not
+ * JSR 250 compliant, and while working in BP, then causes issues e.g. when
+ * wiring with Guice for tests, so do always repeat it.)
+ */
+ @PostConstruct
+ protected void init() {
+ }
+
@Override
+ @PreDestroy
public void close() throws Exception {
if (listenerRegistration != null) {
try {
this.changes = changes;
}
-
-
@Override
public void run() {
for (DataTreeModification<T> change : changes) {
if (jobQueue == null) {
jobQueue = new JobQueue();
}
+ LOG.trace("Adding jobkey {} to queue {} with size {}", key, hashKey, jobEntriesMap.size());
jobQueue.addEntry(jobEntry);
jobEntriesMap.put(key, jobQueue);
}
-
- jobQueueMap.put(hashKey, jobEntriesMap); // Is this really needed ?
reentrantLock.lock();
try {
waitCondition.signal();
* clearJob is used to cleanup the submitted job from the jobqueue.
**/
private void clearJob(JobEntry jobEntry) {
- Map<String, JobQueue> jobEntriesMap = jobQueueMap.get(getHashKey(jobEntry.getKey()));
+ Integer hashKey = getHashKey(jobEntry.getKey());
+ Map<String, JobQueue> jobEntriesMap = jobQueueMap.get(hashKey);
+ LOG.trace("About to clear jobkey {} from queue {}", jobEntry.getKey(), hashKey);
synchronized (jobEntriesMap) {
JobQueue jobQueue = jobEntriesMap.get(jobEntry.getKey());
jobQueue.setExecutingEntry(null);
if (jobQueue.getWaitingEntries().isEmpty()) {
+ LOG.trace("Clear jobkey {} from queue {}", jobEntry.getKey(), hashKey);
jobEntriesMap.remove(jobEntry.getKey());
}
}
*/
@Override
public void onSuccess(List<Void> voids) {
+ LOG.trace("Job {} completed successfully", jobEntry.getKey());
clearJob(jobEntry);
}
@Override
public void onFailure(Throwable throwable) {
- LOG.warn("Job: {} failed with exception: {}", jobEntry, throwable.getStackTrace());
+ LOG.warn("Job: {} failed with exception: {} {}", jobEntry, throwable.getClass().getSimpleName(),
+ throwable.getStackTrace());
if (jobEntry.getMainWorker() == null) {
LOG.error("Job: {} failed with Double-Fault. Bailing Out.", jobEntry);
clearJob(jobEntry);
@Override
public void run() {
List<ListenableFuture<Void>> futures = null;
+ long jobStartTimestamp = System.currentTimeMillis();
+ LOG.trace("Running job {}", jobEntry.getKey());
+
try {
futures = jobEntry.getMainWorker().call();
+ long jobExecutionTime = System.currentTimeMillis() - jobStartTimestamp;
+ LOG.trace("Job {} took {}ms to complete", jobEntry.getKey(), jobExecutionTime);
} catch (Exception e){
- LOG.error("Exception when executing jobEntry: {}, exception: {}", jobEntry, e.getStackTrace());
- e.printStackTrace();
+ LOG.error("Exception when executing jobEntry: {}", jobEntry, e);
}
+
if (futures == null || futures.isEmpty()) {
clearJob(jobEntry);
return;
private class JobQueueHandler implements Runnable {
@Override
public void run() {
- LOG.debug("Starting JobQueue Handler Thread.");
+ LOG.info("Starting JobQueue Handler Thread with pool size {}", THREADPOOL_SIZE);
while (true) {
try {
for (int i = 0; i < THREADPOOL_SIZE; i++) {
Map<String, JobQueue> jobEntriesMap = jobQueueMap.get(i);
if (jobEntriesMap.isEmpty()) {
- Thread.sleep(500);
continue;
}
+ LOG.trace("JobQueueHandler handling queue {} with size {}", i, jobEntriesMap.size());
synchronized (jobEntriesMap) {
- Iterator it = jobEntriesMap.entrySet().iterator();
+ Iterator<Map.Entry<String, JobQueue>> it = jobEntriesMap.entrySet().iterator();
while (it.hasNext()) {
- Map.Entry<String, JobQueue> entry = (Map.Entry)it.next();
+ Map.Entry<String, JobQueue> entry = it.next();
if (entry.getValue().getExecutingEntry() != null) {
continue;
}
if (jobEntry != null) {
entry.getValue().setExecutingEntry(jobEntry);
MainTask worker = new MainTask(jobEntry);
+ LOG.trace("Executing job {} from queue {}", jobEntry.getKey(), i);
fjPool.execute(worker);
} else {
it.remove();
}
}
- if (jobQueueMap.isEmpty()) {
- reentrantLock.lock();
- try {
+ reentrantLock.lock();
+ try {
+ if (isJobQueueEmpty()) {
waitCondition.await();
- } finally {
- reentrantLock.unlock();
}
+ } finally {
+ reentrantLock.unlock();
}
} catch (Exception e) {
LOG.error("Exception while executing the tasks {} ", e);
}
}
}
-}
\ No newline at end of file
+
+ private boolean isJobQueueEmpty() {
+ for (int i = 0; i < THREADPOOL_SIZE; i++) {
+ Map<String, JobQueue> jobEntriesMap = jobQueueMap.get(i);
+ if (!jobEntriesMap.isEmpty()) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
return rollbackWorker;
}
+ public int getRetryCount() {
+ return retryCount.get();
+ }
+
public int decrementRetryCountAndGet() {
return retryCount.decrementAndGet();
}
import java.util.List;
import org.opendaylight.genius.mdsalutil.NwConstants.LearnFlowModsType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
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.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DropActionCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.GroupActionCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopMplsActionCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushPbbActionCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.drop.action._case.DropAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.drop.action._case.DropActionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.group.action._case.GroupActionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.output.action._case.OutputActionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.mpls.action._case.PopMplsActionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.OutputPortValues;
import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetDestinationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetSourceBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Icmpv4MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.ProtocolMatchFieldsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.TunnelBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.protocol.match.fields.PbbBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanIdBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetSourceBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DropActionCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.drop.action._case.DropAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.drop.action._case.DropActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.protocol.match.fields.PbbBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanIdBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.add.group.input.buckets.bucket.action.action.NxActionResubmitRpcAddGroupCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxOfInPortCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxRegCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionConntrackNodesNodeTableFlowApplyActionsCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegLoadNodesNodeTableFlowApplyActionsCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.conntrack.grouping.NxConntrack;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.conntrack.grouping.NxConntrackBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoadBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.nx.reg.load.Dst;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.nx.reg.load.DstBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstOfEthDstCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstOfIpDstCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flow.mod.spec.flow.mod.spec.FlowModAddMatchFromFieldCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flow.mod.spec.flow.mod.spec.FlowModAddMatchFromValueCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flow.mod.spec.flow.mod.spec.FlowModCopyFieldIntoFieldCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flow.mod.spec.flow.mod.spec.flow.mod.output.to.port._case.FlowModOutputToPortBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionConntrackNodesNodeTableFlowApplyActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionLearnNodesNodeTableFlowApplyActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegLoadNodesNodeTableFlowApplyActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegMoveNodesNodeTableFlowApplyActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.conntrack.grouping.NxConntrackBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.learn.grouping.NxLearnBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.learn.grouping.nx.learn.FlowMods;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.learn.grouping.nx.learn.FlowModsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoad;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoadBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.nx.reg.load.Dst;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.nx.reg.load.DstBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.move.grouping.NxRegMove;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.move.grouping.NxRegMoveBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.move.grouping.nx.reg.move.SrcBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.resubmit.grouping.NxResubmitBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcOfEthSrcCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcOfIpSrcCaseBuilder;
+
public enum ActionType {
group {
}
+ },
+ move_src_dst_ip {
+ @Override
+ public Action buildAction(int newActionKey, ActionInfo actionInfo) {
+
+ ActionBuilder ab = new ActionBuilder();
+ NxRegMove regMove = new NxRegMoveBuilder()
+ .setSrc(new SrcBuilder().setSrcChoice(new SrcOfIpSrcCaseBuilder().setOfIpSrc(Boolean.TRUE).build())
+ .setStart(0).build())
+ .setDst(new org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.move.grouping.nx.reg.move.DstBuilder()
+ .setDstChoice(new DstOfIpDstCaseBuilder().setOfIpDst(Boolean.TRUE).build()).setStart(0)
+ .setEnd(31).build())
+ .build();
+ ab.setAction(new NxActionRegMoveNodesNodeTableFlowApplyActionsCaseBuilder().setNxRegMove(regMove).build());
+ ab.setKey(new ActionKey(newActionKey));
+ return ab.build();
+ }
+ },
+
+ move_src_dst_eth {
+ @Override
+ public Action buildAction(int newActionKey, ActionInfo actionInfo) {
+ ActionBuilder ab = new ActionBuilder();
+ NxRegMove regMove = new NxRegMoveBuilder().setSrc(new SrcBuilder()
+ .setSrcChoice(new SrcOfEthSrcCaseBuilder().setOfEthSrc(Boolean.TRUE).build()).setStart(0).build())
+ .setDst(new org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.move.grouping.nx.reg.move.DstBuilder()
+ .setDstChoice(new DstOfEthDstCaseBuilder().setOfEthDst(Boolean.TRUE).build()).setStart(0)
+ .setEnd(47).build())
+ .build();
+ ab.setAction(new NxActionRegMoveNodesNodeTableFlowApplyActionsCaseBuilder().setNxRegMove(regMove).build());
+ ab.setKey(new ActionKey(newActionKey));
+ return ab.build();
+ }
+ },
+
+ set_icmp_type {
+ @Override
+ public Action buildAction(int newActionKey, ActionInfo actionInfo) {
+ String[] actionValues = actionInfo.getActionValues();
+
+ ActionBuilder ab = new ActionBuilder();
+ Icmpv4MatchBuilder icmpb = new Icmpv4MatchBuilder().setIcmpv4Type(Short.parseShort(actionValues[0]));
+ ab.setAction(new SetFieldCaseBuilder()
+ .setSetField(new SetFieldBuilder().setIcmpv4Match(icmpb.build()).build()).build());
+ ab.setKey(new ActionKey(newActionKey));
+ return ab.build();
+ }
+
+ },
+ nx_load_in_port {
+ @Override
+ public Action buildAction(int newActionKey, ActionInfo actionInfo) {
+ BigInteger[] actionValues = actionInfo.getBigActionValues();
+ NxRegLoad rb = new NxRegLoadBuilder()
+ .setDst(new DstBuilder()
+ .setDstChoice(new DstNxOfInPortCaseBuilder().setOfInPort(Boolean.TRUE).build())
+ .setStart(Integer.valueOf(0)).setEnd(Integer.valueOf(15)).build())
+ .setValue(actionValues[0]).build();
+ ActionBuilder ab = new ActionBuilder();
+ ab.setKey(new ActionKey(newActionKey));
+ ab.setOrder(newActionKey);
+ ab.setAction(new NxActionRegLoadNodesNodeTableFlowApplyActionsCaseBuilder().setNxRegLoad(rb).build());
+ return ab.build();
+ }
};
private static final int RADIX_HEX = 16;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.Joiner;
import com.google.common.base.Optional;
-import com.google.common.primitives.Bytes;
-import com.google.common.primitives.Ints;
import com.google.common.util.concurrent.CheckedFuture;
public class MDSALUtil {
}
public static String longToIp(long ip, long mask) {
- StringBuilder sb = new StringBuilder(15);
- Joiner joiner = Joiner.on('.');
-
- joiner.appendTo(sb, Bytes.asList(Ints.toByteArray((int) ip)));
-
- sb.append("/" + mask);
-
- return sb.toString();
+ return ((ip & 0xFF000000) >> 3 * 8) + "." +
+ ((ip & 0x00FF0000) >> 2 * 8) + "." +
+ ((ip & 0x0000FF00) >> 8) + "." +
+ (ip & 0x000000FF) +
+ (mask == 0 ? "" : "/" + mask);
}
.child(Node.class, new NodeKey(new NodeId("openflow:" + dpnId))).toInstance()))
.setIngress(ncRef).setEgress(ncRef).build();
}
-
}
*/
package org.opendaylight.genius.mdsalutil;
+import java.math.BigInteger;
import java.net.InetAddress;
+import java.util.LinkedList;
+import java.util.List;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import com.google.common.base.Optional;
import com.google.common.primitives.UnsignedBytes;
public class NWUtil {
StringBuilder sb = new StringBuilder(18);
- for (int i = 0; i < ipAddress.length; i++) {
- sb.append(UnsignedBytes.toString(ipAddress[i], 10));
+ for (byte ipAddres : ipAddress) {
+ sb.append(UnsignedBytes.toString(ipAddres, 10));
sb.append(".");
}
StringBuilder sb = new StringBuilder(18);
- for (int i = 0; i < macAddress.length; i++) {
- String tmp = UnsignedBytes.toString(macAddress[i], 16).toUpperCase();
- if(tmp.length() == 1 || macAddress[i] == (byte)0) {
+ for (byte macAddres : macAddress) {
+ String tmp = UnsignedBytes.toString(macAddres, 16).toUpperCase();
+ if(tmp.length() == 1 || macAddres == (byte)0) {
sb.append("0");
}
sb.append(tmp);
sb.setLength(17);
return sb.toString();
}
+
+ /**
+ * Returns the ids of the currently operative DPNs
+ *
+ * @param dataBroker
+ * @return
+ */
+ public static List<BigInteger> getOperativeDPNs(DataBroker dataBroker) {
+ List<BigInteger> result = new LinkedList<BigInteger>();
+ InstanceIdentifier<Nodes> nodesInstanceIdentifier = InstanceIdentifier.builder(Nodes.class).build();
+ Optional<Nodes> nodesOptional = MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
+ nodesInstanceIdentifier);
+ if (!nodesOptional.isPresent()) {
+ return result;
+ }
+ Nodes nodes = nodesOptional.get();
+ List<Node> nodeList = nodes.getNode();
+ for (Node node : nodeList) {
+ NodeId nodeId = node.getId();
+ if (nodeId != null) {
+ BigInteger dpnId = MDSALUtil.getDpnIdFromNodeName(nodeId);
+ result.add(dpnId);
+ }
+ }
+ return result;
+ }
}
// Ingress (w.r.t switch) service indexes
public static final short DEFAULT_SERVICE_INDEX = 0;
- public static final short DHCP_SERVICE_INDEX = 1;
- public static final short ACL_SERVICE_INDEX = 2;
+ public static final short ACL_SERVICE_INDEX = 1;
+ public static final short DHCP_SERVICE_INDEX = 2;
public static final short IPV6_SERVICE_INDEX = 3;
public static final short SCF_SERVICE_INDEX = 4;
+ public static final short SFC_SERVICE_INDEX = 4;
public static final short L3VPN_SERVICE_INDEX = 5;
public static final short ELAN_SERVICE_INDEX = 6;
public static final short DEFAULT_EGRESS_SERVICE_INDEX = 7;
public static final String ACL_SERVICE_NAME = "ACL_SERVICE";
public static final String IPV6_SERVICE_NAME = "IPV6_SERVICE";
public static final String SCF_SERVICE_NAME = "SCF_SERVICE";
+ public static final String SFC_SERVICE_NAME = "SFC_SERVICE";
public static final String L3VPN_SERVICE_NAME = "L3VPN_SERVICE";
public static final String ELAN_SERVICE_NAME = "ELAN_SERVICE";
public static final String DEFAULT_EGRESS_SERVICE_NAME = "DEFAULT_EGRESS_SERVICE";
public static final short SCF_UP_SUB_FILTER_TCP_BASED_TABLE = 70;
public static final short SCF_DOWN_SUB_FILTER_TCP_BASED_TABLE = 72;
public static final short SCF_CHAIN_FWD_TABLE = 75;
+ public static final short SFC_TRANSPORT_INGRESS_TABLE = 76;
+ public static final short SFC_TRANSPORT_PATH_MAPPER_TABLE = 77;
+ public static final short SFC_TRANSPORT_NEXT_HOP_TABLE = 78;
+ public static final short SFC_TRANSPORT_EGRESS_TABLE = 79;
public static final short L3_INTERFACE_TABLE = 80;
public static final short EGRESS_LPORT_DISPATCHER_TABLE = 220;
public static final short EGRESS_ACL_TABLE = 251;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MatchField;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg5;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.ExtensionKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxAugMatchNodesNodeTableFlowBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxCtStateKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxCtZoneKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxReg5Key;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxReg6Key;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmOfTcpDstKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmOfTcpSrcKey;
}
}
},
+ nxm_reg_5 {
+ @Override
+ protected Class<? extends MatchField> getMatchType() {
+ return NxmNxReg.class;
+ }
+
+ @Override
+ public void createInnerMatchBuilder(NxMatchInfo matchInfo, Map<Class<?>, Object> mapMatchBuilder) {
+ NxmNxRegBuilder nxmNxRegBuilder = (NxmNxRegBuilder) mapMatchBuilder.get(NxmNxRegBuilder.class);
+
+ if (nxmNxRegBuilder == null) {
+ nxmNxRegBuilder = new NxmNxRegBuilder();
+ mapMatchBuilder.put(NxmNxRegBuilder.class, nxmNxRegBuilder);
+ }
+
+ nxmNxRegBuilder.setReg(NxmNxReg5.class).setValue(matchInfo.getMatchValues()[0]).build();
+ }
+
+ @Override
+ public void setMatch(MatchBuilder matchBuilderInOut, MatchInfoBase matchInfo,
+ Map<Class<?>, Object> mapMatchBuilder) {
+ NxmNxRegBuilder nxmNxRegBuilder = (NxmNxRegBuilder) mapMatchBuilder.remove(NxmNxRegBuilder.class);
+
+ if (nxmNxRegBuilder != null) {
+ NxAugMatchNodesNodeTableFlow nxAugMatch = new NxAugMatchNodesNodeTableFlowBuilder()
+ .setNxmNxReg(nxmNxRegBuilder.build()).build();
+ GeneralAugMatchNodesNodeTableFlow existingAugmentations = matchBuilderInOut
+ .getAugmentation(GeneralAugMatchNodesNodeTableFlow.class);
+ GeneralAugMatchNodesNodeTableFlow genAugMatch = generalAugMatchBuilder(existingAugmentations,
+ nxAugMatch, NxmNxReg5Key.class);
+ matchBuilderInOut.addAugmentation(GeneralAugMatchNodesNodeTableFlow.class, genAugMatch);
+ }
+ }
+ },
nxm_reg_6 {
@Override
protected Class<? extends MatchField> getMatchType() {
private InstanceIdentifier identifier;
private short action;
- public ActionableResourceImpl(String key) {
+ public ActionableResourceImpl(String key){
this.key = key;
}
+ public ActionableResourceImpl(String key, InstanceIdentifier identifier, short action,Object updatedData, Object oldData) {
+ this.instance = updatedData;
+ this.oldInstance = oldData;
+ this.key = key;
+ this.identifier = identifier;
+ this.action = action;
+ }
+
public void setInstance(Object instance) {
this.instance = instance;
}
--- /dev/null
+/*
+ * Copyright (c) 2016 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.genius.utils.batching;
+
+import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import java.util.List;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+
+
+public class DefaultBatchHandler implements ResourceHandler {
+
+ private static DataBroker dataBroker;
+ public static Integer batchSize;
+ public static Integer batchInterval;
+ public LogicalDatastoreType datastoreType;
+
+ public DefaultBatchHandler(DataBroker dataBroker,LogicalDatastoreType dataStoreType,Integer batchSize,Integer batchInterval) {
+
+ this.dataBroker = dataBroker;
+ this.batchSize = batchSize;
+ this.batchInterval = batchInterval;
+ this.datastoreType = dataStoreType;
+
+ }
+ public void update(WriteTransaction tx, LogicalDatastoreType datastoreType,
+ final InstanceIdentifier identifier, final Object original, final Object update, List<SubTransaction> transactionObjects) {
+ if ((update != null) && !(update instanceof DataObject)) {
+ return;
+ }
+ if (datastoreType != getDatastoreType()) {
+ return;
+ }
+
+ SubTransaction subTransaction = new SubTransactionImpl();
+ subTransaction.setAction(SubTransaction.UPDATE);
+ subTransaction.setInstance(update);
+ subTransaction.setInstanceIdentifier(identifier);
+ transactionObjects.add(subTransaction);
+
+ tx.merge(datastoreType, identifier, (DataObject) update, true);
+ }
+
+ public void create(WriteTransaction tx, final LogicalDatastoreType datastoreType,
+ final InstanceIdentifier identifier, final Object data, List<SubTransaction> transactionObjects) {
+ if ((data != null) && !(data instanceof DataObject)) {
+ return;
+ }
+ if (datastoreType != getDatastoreType()) {
+ return;
+ }
+
+ SubTransaction subTransaction = new SubTransactionImpl();
+ subTransaction.setAction(SubTransaction.CREATE);
+ subTransaction.setInstance(data);
+ subTransaction.setInstanceIdentifier(identifier);
+ transactionObjects.add(subTransaction);
+
+ tx.put(datastoreType, identifier, (DataObject) data, true);
+ }
+
+ public void delete(WriteTransaction tx, final LogicalDatastoreType datastoreType,
+ final InstanceIdentifier identifier, final Object data, List<SubTransaction> transactionObjects) {
+ if ((data != null) && !(data instanceof DataObject)) {
+ return;
+ }
+ if (datastoreType != getDatastoreType()) {
+ return;
+ }
+
+ SubTransaction subTransaction = new SubTransactionImpl();
+ subTransaction.setAction(SubTransaction.DELETE);
+ subTransaction.setInstanceIdentifier(identifier);
+ transactionObjects.add(subTransaction);
+
+ tx.delete(datastoreType, identifier);
+ }
+
+ public DataBroker getResourceBroker() {
+ return dataBroker;
+ }
+
+ public int getBatchSize() {
+ return batchSize;
+ }
+
+ public int getBatchInterval() {
+ return batchInterval;
+ }
+
+ public LogicalDatastoreType getDatastoreType() {
+ return datastoreType;
+ }
+}
+
public void registerBatchableResource(String resourceType, final BlockingQueue<ActionableResource> resQueue, final ResourceHandler resHandler) {
Preconditions.checkNotNull(resQueue, "ResourceQueue to use for batching cannot not be null.");
Preconditions.checkNotNull(resHandler, "ResourceHandler cannot not be null.");
+ if (resourceHandlerMapper.contains(resourceType)) {
+ throw new RuntimeException("Resource type already registered");
+ }
resourceHandlerMapper.put(resourceType, new ImmutablePair<BlockingQueue, ResourceHandler>(resQueue, resHandler));
ScheduledThreadPoolExecutor resDelegatorService =(ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(1);
resourceBatchingThreadMapper.put(resourceType, resDelegatorService);
resDelegatorService.scheduleWithFixedDelay(new Batcher(resourceType), INITIAL_DELAY, resHandler.getBatchInterval(), TIME_UNIT);
}
+ public void put(String resourceType, InstanceIdentifier identifier, DataObject updatedData) {
+ BlockingQueue<ActionableResource> queue = getQueue(resourceType);
+ if (queue != null) {
+ ActionableResource actResource = new ActionableResourceImpl(identifier.toString(),
+ identifier, ActionableResource.CREATE, updatedData, null/*oldData*/);
+ queue.add(actResource);
+ }
+ }
+
+ public void merge(String resourceType, InstanceIdentifier identifier, DataObject updatedData) {
+ BlockingQueue<ActionableResource> queue = getQueue(resourceType);
+ if (queue != null) {
+ ActionableResource actResource = new ActionableResourceImpl(identifier.toString(),
+ identifier, ActionableResource.UPDATE, updatedData, null/*oldData*/);
+ queue.add(actResource);
+ }
+ }
+
+ public void delete(String resourceType, InstanceIdentifier identifier) {
+ BlockingQueue<ActionableResource> queue = getQueue(resourceType);
+ if (queue != null) {
+ ActionableResource actResource = new ActionableResourceImpl(identifier.toString(),
+ identifier, ActionableResource.DELETE, null, null/*oldData*/);
+ queue.add(actResource);
+ }
+ }
+
+ private BlockingQueue<ActionableResource> getQueue(String resourceType) {
+ if (resourceHandlerMapper.containsKey(resourceType)) {
+ return resourceHandlerMapper.get(resourceType).getLeft();
+ }
+ return null;
+ }
+
+
public void deregisterBatchableResource(String resourceType) {
resourceHandlerMapper.remove(resourceType);
resourceBatchingThreadMapper.remove(resourceType);
DataBroker broker = resHandler.getResourceBroker();
LogicalDatastoreType dsType = resHandler.getDatastoreType();
WriteTransaction tx = broker.newWriteOnlyTransaction();
+ List<SubTransaction> transactionObjects = new ArrayList<>();
for (ActionableResource actResource : actResourceList)
{
switch (actResource.getAction()) {
case ActionableResource.CREATE:
identifier = actResource.getInstanceIdentifier();
instance = actResource.getInstance();
- resHandler.create(tx, dsType, identifier, instance);
+ resHandler.create(tx, dsType, identifier, instance,transactionObjects);
break;
case ActionableResource.UPDATE:
identifier = actResource.getInstanceIdentifier();
Object updated = actResource.getInstance();
Object original = actResource.getOldInstance();
- resHandler.update(tx, dsType, identifier, original, updated);
+ resHandler.update(tx, dsType, identifier, original, updated,transactionObjects);
break;
case ActionableResource.DELETE:
identifier = actResource.getInstanceIdentifier();
instance = actResource.getInstance();
- resHandler.delete(tx, dsType, identifier, instance);
+ resHandler.delete(tx, dsType, identifier, instance,transactionObjects);
break;
default:
LOG.error("Unable to determine Action for ResourceType {} with ResourceKey {}", resourceType,
} catch (InterruptedException | ExecutionException e)
{
- LOG.error("Exception occurred while writing to datastore: " + e);
+ LOG.error("Exception occurred while batch writing to datastore {} ", e);
+ LOG.info("Trying to submit transaction operations one at a time for resType {}", resourceType);
+ for (SubTransaction object : transactionObjects) {
+ WriteTransaction writeTransaction = broker.newWriteOnlyTransaction();
+ switch (object.getAction()) {
+ case SubTransaction.CREATE :
+ writeTransaction.put(dsType, object.getInstanceIdentifier(), (DataObject)object.getInstance(), true);
+ break;
+ case SubTransaction.DELETE :
+ writeTransaction.delete(dsType, object.getInstanceIdentifier());
+ break;
+ case SubTransaction.UPDATE :
+ writeTransaction.merge(dsType, object.getInstanceIdentifier(), (DataObject)object.getInstance(), true);
+ break;
+ default:
+ LOG.error("Unable to determine Action for transaction object with id {}", object.getInstanceIdentifier());
+ }
+ CheckedFuture<Void, TransactionCommitFailedException> futureOperation = writeTransaction.submit();
+ try {
+ futureOperation.get();
+ } catch (InterruptedException | ExecutionException exception) {
+ LOG.error("Error {} to datastore (path, data) : ({}, {})", object.getAction(), object.getInstanceIdentifier(), object.getInstance());
+ LOG.error(exception.getMessage());
+ }
+ }
}
} catch (final Exception e)
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import java.util.List;
+
public interface ResourceHandler {
- void create(WriteTransaction tx, LogicalDatastoreType datastoreType, InstanceIdentifier identifer, Object vrfEntry);
- void delete(WriteTransaction tx, LogicalDatastoreType datastoreType, InstanceIdentifier identifer, Object vrfEntry);
+ void create(WriteTransaction tx, LogicalDatastoreType datastoreType, InstanceIdentifier identifer, Object vrfEntry,List<SubTransaction> transactionObjects);
+ void delete(WriteTransaction tx, LogicalDatastoreType datastoreType, InstanceIdentifier identifer, Object vrfEntry,List<SubTransaction> transactionObjects);
void update(WriteTransaction tx, LogicalDatastoreType datastoreType, InstanceIdentifier identifier, Object original,
- Object update);
+ Object update,List<SubTransaction> transactionObjects);
LogicalDatastoreType getDatastoreType();
int getBatchSize();
int getBatchInterval();
--- /dev/null
+/*
+ * Copyright (c) 2016 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.genius.utils.batching;
+
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public interface SubTransaction {
+ static final short CREATE = 1;
+ static final short UPDATE = 2;
+ static final short DELETE = 3;
+
+ InstanceIdentifier getInstanceIdentifier();
+ void setInstanceIdentifier(InstanceIdentifier identifier);
+ Object getInstance();
+ void setInstance(Object instance);
+ short getAction();
+ void setAction(short action);
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 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.genius.utils.batching;
+
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class SubTransactionImpl implements SubTransaction {
+ private Object instance;
+ private InstanceIdentifier identifier;
+ private short action;
+
+ public SubTransactionImpl() { }
+
+ public void setInstance(Object instance) {
+ this.instance = instance;
+ }
+
+ public Object getInstance() {
+ return this.instance;
+ }
+
+ public void setInstanceIdentifier(InstanceIdentifier identifier) {
+ this.identifier = identifier;
+ }
+
+ public InstanceIdentifier getInstanceIdentifier() {
+ return this.identifier;
+ }
+
+ public void setAction(short action) {
+ this.action = action;
+ }
+
+ public short getAction(){
+ return action;
+ }
+}
import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
import org.opendaylight.genius.utils.SystemPropertyReader;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class ClusteringUtils {
-
+ private static final Logger LOG = LoggerFactory.getLogger(ClusteringUtils.class);
static DataStoreJobCoordinator dataStoreJobCoordinator;
static DataStoreJobCoordinator getDataStoreJobCoordinator() {
return getResultFuture();
}
}
+ LOG.trace("EntityOwnershipState for entity type {} is not yet available. {} retries left",
+ entity.getType(), retries);
Thread.sleep(sleepBetweenRetries);
}
checkNodeEntityfuture.setException(new EntityOwnerNotPresentException("Entity Owner Not Present"));
--- /dev/null
+/*
+ * Copyright (c) 2016 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.genius.utils.hwvtep;
+
+public abstract class DebugEvent {
+
+ private final long eventTimeStamp;
+
+ public DebugEvent() {
+ this.eventTimeStamp = System.currentTimeMillis();
+ }
+
+ public long getEventTimeStamp() {
+ return eventTimeStamp;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 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.genius.utils.hwvtep;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+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.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.LinkedBlockingQueue;
+
+public class HwvtepHACache {
+
+ private static final int MAX_EVENT_BUFFER_SIZE = 500000;
+ private static final int EVENT_DRAIN_BUFFER_SIZE = 100000;
+
+ private static HwvtepHACache instance = new HwvtepHACache();
+
+ private ConcurrentHashMap<InstanceIdentifier<Node>, Set<InstanceIdentifier<Node>>> parentToChildMap = new ConcurrentHashMap<>();
+ private ConcurrentHashMap<InstanceIdentifier<Node>, InstanceIdentifier<Node>> childToParentMap = new ConcurrentHashMap<>();
+ private ConcurrentHashMap<String, Boolean> childNodeIds = new ConcurrentHashMap<>();
+ private ConcurrentHashMap<String, Boolean> connectedNodes = new ConcurrentHashMap<>();
+ private LinkedBlockingQueue<DebugEvent> debugEvents = new LinkedBlockingQueue<>(MAX_EVENT_BUFFER_SIZE);
+
+ public static HwvtepHACache getInstance() {
+ return instance;
+ }
+
+ public synchronized void addChild(InstanceIdentifier<Node> parent, InstanceIdentifier<Node> child) {
+ if (parent == null || child == null) {
+ return;
+ }
+ if (parentToChildMap.get(parent) == null) {
+ parentToChildMap.put(parent, new HashSet<InstanceIdentifier<Node>>());
+ }
+ parentToChildMap.get(parent).add(child);
+ childToParentMap.put(child, parent);
+ String childNodeId = child.firstKeyOf(Node.class).getNodeId().getValue();
+ childNodeIds.put(childNodeId, Boolean.TRUE);
+ addDebugEvent(new NodeEvent.ChildAddedEvent(childNodeId));
+ }
+
+ public boolean isHAEnabledDevice(InstanceIdentifier<?> iid) {
+ boolean enabled = childToParentMap.containsKey(iid);
+ if (!enabled) {
+ String psNodeId = iid.firstKeyOf(Node.class).getNodeId().getValue();
+ int idx = psNodeId.indexOf(HwvtepSouthboundConstants.PSWITCH_URI_PREFIX);
+ if (idx > 0) {
+ String globalNodeId = psNodeId.substring(0, idx - 1);
+ return childNodeIds.containsKey(globalNodeId);
+ }
+ }
+ return enabled;
+ }
+
+ public boolean isHAParentNode(InstanceIdentifier<Node> node) {
+ return parentToChildMap.containsKey(node);
+ }
+
+ public Set<InstanceIdentifier<Node>> getChildrenForHANode(InstanceIdentifier<Node> parent) {
+ if (parent != null && parentToChildMap.containsKey(parent)) {
+ return new HashSet(parentToChildMap.get(parent));
+ } else {
+ return Collections.emptySet();
+ }
+ }
+
+ public Set<InstanceIdentifier<Node>> getHAParentNodes() {
+ return parentToChildMap.keySet();
+ }
+
+ public Set<InstanceIdentifier<Node>> getHAChildNodes() {
+ return childToParentMap.keySet();
+ }
+
+ public InstanceIdentifier<Node> getParent(InstanceIdentifier<Node> child) {
+ if (child != null) {
+ return childToParentMap.get(child);
+ }
+ return null;
+ }
+
+ public synchronized void cleanupParent(InstanceIdentifier<Node> parent) {
+ if (parent == null) {
+ return;
+ }
+
+ if (parentToChildMap.get(parent) != null) {
+ Set<InstanceIdentifier<Node>> childs = parentToChildMap.get(parent);
+ for (InstanceIdentifier<Node> child : childs) {
+ childToParentMap.remove(child);
+ String childNodeId = child.firstKeyOf(Node.class).getNodeId().getValue();
+ childNodeIds.remove(childNodeId);
+ }
+ }
+ parentToChildMap.remove(parent);
+ }
+
+ public void updateConnectedNodeStatus(InstanceIdentifier<Node> iid) {
+ String nodeId = iid.firstKeyOf(Node.class).getNodeId().getValue();
+ connectedNodes.put(nodeId, true);
+ DebugEvent event = new NodeEvent.NodeConnectedEvent(nodeId);
+ addDebugEvent(event);
+ }
+
+ public void updateDisconnectedNodeStatus(InstanceIdentifier<Node> iid) {
+ String nodeId = iid.firstKeyOf(Node.class).getNodeId().getValue();
+ connectedNodes.put(nodeId, false);
+ DebugEvent event = new NodeEvent.NodeDisconnectedEvent(nodeId);
+ addDebugEvent(event);
+ }
+
+ public Map<String, Boolean> getConnectedNodes() {
+ return ImmutableMap.copyOf(connectedNodes);
+ }
+
+ public void addDebugEvent(DebugEvent debugEvent) {
+ //Try adding the event to event queue
+ if (!debugEvents.offer(debugEvent)) {
+ //buffer is exhausted
+ Collection<DebugEvent> list = new ArrayList<>();
+ //do not clear all events , make some place by clearing few old events
+ debugEvents.drainTo(list, EVENT_DRAIN_BUFFER_SIZE);
+ debugEvents.offer(debugEvent);
+ }
+ }
+
+ public List<DebugEvent> getNodeEvents() {
+ return ImmutableList.copyOf(debugEvents);
+ }
+}
*/
package org.opendaylight.genius.utils.hwvtep;
+import com.google.common.collect.ImmutableBiMap;
+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.MacAddress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.EncapsulationTypeBase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.EncapsulationTypeVxlanOverIpv4;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
-import com.google.common.collect.ImmutableBiMap;
-
// TODO (eperefr) Remove this class once it's been added to hwvtep-southbound
public class HwvtepSouthboundConstants {
- public static final TopologyId HWVTEP_TOPOLOGY_ID = new TopologyId("hwvtep:1");
public static final String HWVTEP_ENTITY_TYPE = "hwvtep";
- public static final Object PSWITCH_URI_PREFIX = "physicalswitch";
public static final ImmutableBiMap<Class<? extends EncapsulationTypeBase>, String> ENCAPS_TYPE_MAP = new ImmutableBiMap.Builder<Class<? extends EncapsulationTypeBase>, String>()
.put(EncapsulationTypeVxlanOverIpv4.class, "vxlan_over_ipv4").build();
public static final String ELAN_ENTITY_TYPE = "elan";
public static final String ELAN_ENTITY_NAME = "elan";
public static final String TEP_PREFIX = "vxlan_over_ipv4:";
+ public static final String PSWITCH_URI_PREFIX = "physicalswitch";
+ public static final TopologyId HWVTEP_TOPOLOGY_ID = new TopologyId(new Uri("hwvtep:1"));
}
--- /dev/null
+/*
+ * Copyright (c) 2016 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.genius.utils.hwvtep;
+
+import java.io.PrintStream;
+import java.util.Objects;
+
+public abstract class NodeEvent extends DebugEvent {
+
+ protected final String nodeId;
+
+ public NodeEvent(String nodeId) {
+ super();
+ this.nodeId = nodeId;
+ }
+
+ public String getNodeId() {
+ return nodeId;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (this == other) {
+ return true;
+ }
+ if (other instanceof NodeEvent) {
+ return Objects.equals(nodeId, ((NodeEvent) other).nodeId);
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return nodeId != null ? nodeId.hashCode() : 0;
+ }
+
+ static enum NodeStatus {
+ Connected,Disconnected;
+ }
+
+ public static class NodeConnectedEvent extends NodeEvent {
+
+ public NodeConnectedEvent(String nodeId) {
+ super(nodeId);
+ }
+
+ public void print(PrintStream out) {
+ out.print(nodeId);
+ out.print(" connected");
+ }
+ }
+
+ public static class NodeDisconnectedEvent extends NodeEvent {
+
+ public NodeDisconnectedEvent(String nodeId) {
+ super(nodeId);
+ }
+
+ public void print(PrintStream out) {
+ out.print(nodeId);
+ out.print(" disconnected");
+ }
+ }
+
+ public static class ChildAddedEvent extends NodeEvent {
+
+ public ChildAddedEvent(String nodeId) {
+ super(nodeId);
+ }
+
+ public void print(PrintStream out) {
+ out.print(nodeId);
+ out.print(" became HA child");
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Red Hat 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.genius.mdsalutil.hwvtep;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.genius.utils.hwvtep.DebugEvent;
+import org.opendaylight.genius.utils.hwvtep.HwvtepHACache;
+import org.opendaylight.genius.utils.hwvtep.HwvtepSouthboundConstants;
+import org.opendaylight.genius.utils.hwvtep.NodeEvent;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
+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;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class HwvtepHACacheTest {
+
+ HwvtepHACache hwvtepHACache = HwvtepHACache.getInstance();
+
+ @Test
+ public void testAddHAChild() {
+
+ InstanceIdentifier<Node> parent = newNodeInstanceIdentifier("ha");
+ InstanceIdentifier<Node> child1 = newNodeInstanceIdentifier("d1");
+ InstanceIdentifier<Node> child2 = newNodeInstanceIdentifier("d1");
+ String child1NodeId = child1.firstKeyOf(Node.class).getNodeId().getValue();
+ String child2NodeId = child2.firstKeyOf(Node.class).getNodeId().getValue();
+
+ hwvtepHACache.addChild(parent, child1);
+
+ assertTrue(hwvtepHACache.isHAEnabledDevice(child1));
+ assertTrue(hwvtepHACache.isHAParentNode(parent));
+
+ hwvtepHACache.addChild(parent, child2);
+ assertTrue(hwvtepHACache.isHAEnabledDevice(child1));
+ assertTrue(hwvtepHACache.isHAEnabledDevice(child2));
+ assertTrue(hwvtepHACache.isHAParentNode(parent));
+
+ assertTrue(hwvtepHACache.getHAChildNodes().contains(child1));
+ assertTrue(hwvtepHACache.getHAChildNodes().contains(child2));
+ assertTrue(hwvtepHACache.getHAParentNodes().contains(parent));
+
+ assertTrue(hwvtepHACache.getChildrenForHANode(parent).contains(child1));
+ assertTrue(hwvtepHACache.getChildrenForHANode(parent).contains(child2));
+
+ List<DebugEvent> events = hwvtepHACache.getNodeEvents();
+ assertTrue(events.contains(new NodeEvent.ChildAddedEvent(child1NodeId)));
+ assertTrue(events.contains(new NodeEvent.ChildAddedEvent(child2NodeId)));
+
+ hwvtepHACache.updateConnectedNodeStatus(child1);
+ assertTrue(hwvtepHACache.getNodeEvents().contains(new NodeEvent.NodeConnectedEvent(child1NodeId)));
+
+ hwvtepHACache.updateDisconnectedNodeStatus(child1);
+ assertTrue(hwvtepHACache.getNodeEvents().contains(new NodeEvent.NodeDisconnectedEvent(child1NodeId)));
+
+ hwvtepHACache.cleanupParent(parent);
+ assertFalse(hwvtepHACache.isHAEnabledDevice(child1));
+ assertFalse(hwvtepHACache.isHAEnabledDevice(child2));
+ assertFalse(hwvtepHACache.isHAParentNode(parent));
+ }
+
+ public static InstanceIdentifier<Node> newNodeInstanceIdentifier(String id) {
+ String nodeString = "hwvtep://uuid/" + java.util.UUID.nameUUIDFromBytes(id.getBytes()).toString();
+ NodeId nodeId = new NodeId(new Uri(nodeString));
+ NodeKey nodeKey = new NodeKey(nodeId);
+ TopologyKey topoKey = new TopologyKey(HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID);
+ return InstanceIdentifier.builder(NetworkTopology.class)
+ .child(Topology.class, topoKey)
+ .child(Node.class, nodeKey)
+ .build();
+ }
+}