import javax.annotation.Nullable;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.node.SwitchListener;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayConfig.EncapsulationFormat;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayNodeConfig;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.nodes.node.ExternalInterfaces;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.nodes.node.Tunnel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.nodes.node.TunnelBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.overlay.rev150105.TunnelTypeBase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.overlay.rev150105.TunnelTypeVxlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.overlay.rev150105.TunnelTypeVxlanGpe;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Function;
import com.google.common.base.Objects;
import com.google.common.base.Predicate;
+import com.google.common.collect.Collections2;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
/**
private static final Logger LOG = LoggerFactory.getLogger(SwitchManager.class);
- protected Map<NodeId, SwitchState> switches = new HashMap<>();
+ protected static Map<NodeId, SwitchState> switches = new HashMap<>();
protected List<SwitchListener> listeners = new CopyOnWriteArrayList<>();
private final FlowCapableNodeListener nodeListener;
LOG.debug("Initialized OFOverlay switch manager");
}
+ // When first endpoint is attached to switch, it can be ready
+ public static void activatingSwitch(NodeId nodeId) {
+ SwitchState state = switches.get(nodeId);
+ if (state == null) {
+ state = new SwitchState(nodeId);
+ switches.put(nodeId, state);
+ }
+ state.setHasEndpoints(true);
+ state.updateStatus();
+ }
+
+ // When last endpoint is removed from switch, it is no longer ready
+ public static void deactivatingSwitch(NodeId nodeId) {
+ SwitchState state = switches.get(nodeId);
+ if (state == null) {
+ LOG.error("No SwitchState for {} in deactivatingSwitch. This should not happen.",nodeId);
+ return;
+ }
+ state.setHasEndpoints(false);;
+ state.updateStatus();
+ }
+
/**
* Get the collection of switches that are in the "ready" state. Note
* that the collection is immutable.
SwitchState state = switches.get(nodeId);
if (state == null)
return Collections.emptySet();
- return state.externalPorts;
+ return ImmutableSet.copyOf(state.externalPorts);
}
- public synchronized NodeConnectorId getTunnelPort(NodeId nodeId) {
+ public synchronized Collection<NodeConnectorId> getTunnelPorts(NodeId nodeId) {
+ Collection<NodeConnectorId> ncIds = new HashSet<>();
SwitchState state = switches.get(nodeId);
- if (state == null)
+ if (state == null ) {
+ return Collections.emptySet();
+ }
+ ncIds = Collections2.transform(state.tunnelBuilderByType.values(),new Function<TunnelBuilder, NodeConnectorId>() {
+
+ @Override
+ public NodeConnectorId apply(TunnelBuilder input) {
+ return input.getNodeConnectorId();
+ }
+ });
+
+ return ncIds;
+ }
+ public synchronized NodeConnectorId getTunnelPort(NodeId nodeId, Class<? extends TunnelTypeBase> tunnelType) {
+ SwitchState state = switches.get(nodeId);
+ if (state == null) {
return null;
- return state.tunnelPort;
+ }
+ TunnelBuilder tunnel = state.tunnelBuilderByType.get(tunnelType);
+ if (tunnel == null) {
+ return null;
+ }
+ return tunnel.getNodeConnectorId();
}
- public synchronized IpAddress getTunnelIP(NodeId nodeId) {
+ public synchronized IpAddress getTunnelIP(NodeId nodeId, Class<? extends TunnelTypeBase> tunnelType) {
SwitchState state = switches.get(nodeId);
- if (state == null || state.nodeConfig == null)
+ if (state == null) {
return null;
- return state.nodeConfig.getTunnelIp();
+ }
+ TunnelBuilder tunnel = state.tunnelBuilderByType.get(tunnelType);
+ if (tunnel == null) {
+ return null;
+ }
+ return tunnel.getIp();
}
/**
private FlowCapableNode fcNode;
private OfOverlayNodeConfig nodeConfig;
private Map<InstanceIdentifier<NodeConnector>, FlowCapableNodeConnector> fcncByNcIid = Maps.newHashMap();
+ private boolean hasEndpoints=false;
- NodeConnectorId tunnelPort;
+
+ public boolean isHasEndpoints() {
+ return hasEndpoints;
+ }
+
+
+ public void setHasEndpoints(boolean hasEndpoints) {
+ this.hasEndpoints = hasEndpoints;
+ }
+
+ Map<Class<? extends TunnelTypeBase>, TunnelBuilder> tunnelBuilderByType = new HashMap<>();
Set<NodeConnectorId> externalPorts = new HashSet<>();
SwitchStatus status;
public SwitchState(NodeId node, NodeConnectorId tunnelPort, Set<NodeConnectorId> externalPorts,
OfOverlayNodeConfig nodeConfig) {
this.nodeId = node;
- this.tunnelPort = tunnelPort;
- this.externalPorts = externalPorts;
this.nodeConfig = nodeConfig;
+ update();
+ this.externalPorts = externalPorts;
}
private void update() {
- HashSet<NodeConnectorId> externalPorts = new HashSet<>();
- NodeConnectorId tunnelPort = null;
+ tunnelBuilderByType = new HashMap<>();
+ externalPorts = new HashSet<>();
+ if (nodeConfig != null && nodeConfig.getExternalInterfaces() != null) {
+ for (ExternalInterfaces nc : nodeConfig.getExternalInterfaces()) {
+ externalPorts.add(nc.getNodeConnectorId());
+ }
+ }
+ if (nodeConfig != null && nodeConfig.getTunnel() != null) {
+ for (Tunnel tunnel : nodeConfig.getTunnel()) {
+ TunnelBuilder tunnelBuilder = tunnelBuilderByType.get(tunnel.getTunnelType());
+ if (tunnelBuilder == null) {
+ tunnelBuilder = new TunnelBuilder();
+ tunnelBuilderByType.put(tunnel.getTunnelType(), tunnelBuilder);
+ }
+ if (tunnel.getIp() != null) {
+ tunnelBuilder.setIp(tunnel.getIp());
+ }
+ if (tunnel.getNodeConnectorId() != null) {
+ tunnelBuilder.setNodeConnectorId(tunnel.getNodeConnectorId());
+ }
+ if (tunnel.getPort() != null) {
+ tunnelBuilder.setPort(tunnel.getPort());
+ }
+ }
+ }
for (Entry<InstanceIdentifier<NodeConnector>, FlowCapableNodeConnector> fcncByNcIidEntry : fcncByNcIid.entrySet()) {
FlowCapableNodeConnector fcnc = fcncByNcIidEntry.getValue();
if (fcnc.getName() == null) {
}
InstanceIdentifier<NodeConnector> ncIid = fcncByNcIidEntry.getKey();
NodeConnectorId ncId = ncIid.firstKeyOf(NodeConnector.class, NodeConnectorKey.class).getId();
- if (fcnc.getName().matches(".*(vxlan|tun).*")) {
- tunnelPort = ncId;
- }
- if (nodeConfig != null && nodeConfig.getExternalInterfaces() != null) {
- for (String pattern : nodeConfig.getExternalInterfaces()) {
- if (fcnc.getName().matches(pattern)) {
- externalPorts.add(ncId);
- break;
- }
+ if (fcnc.getName().matches(".*(vxlan-).*")) {
+ TunnelBuilder tunnelBuilder = tunnelBuilderByType.get(TunnelTypeVxlan.class);
+ if (tunnelBuilder == null) {
+ tunnelBuilder = new TunnelBuilder().setTunnelType(TunnelTypeVxlan.class);
+ tunnelBuilderByType.put(TunnelTypeVxlan.class, tunnelBuilder);
+ }
+ tunnelBuilder.setNodeConnectorId(ncId);
+ } else if (fcnc.getName().matches(".*(vxlangpe-).*")) {
+ TunnelBuilder tunnelBuilder = tunnelBuilderByType.get(TunnelTypeVxlanGpe.class);
+ if (tunnelBuilder == null) {
+ tunnelBuilder = new TunnelBuilder().setTunnelType(TunnelTypeVxlanGpe.class);
+ tunnelBuilderByType.put(TunnelTypeVxlanGpe.class, tunnelBuilder);
}
+ tunnelBuilder.setNodeConnectorId(ncId);
}
}
- this.tunnelPort = tunnelPort;
- this.externalPorts = Collections.unmodifiableSet(externalPorts);
}
private void updateStatus() {
- boolean tunnelPortWithIpExists = tunnelPortWithIpExists();
+ boolean tunnelWithIpAndNcExists = tunnelWithIpAndNcExists();
if (fcNode != null) {
- if (tunnelPortWithIpExists) {
+ if (tunnelWithIpAndNcExists && isHasEndpoints()) {
setStatus(SwitchStatus.READY);
} else {
setStatus(SwitchStatus.PREPARING);
this.status = newStatus;
}
- private boolean tunnelPortWithIpExists() {
- boolean tunnelPortWithIpExists = false;
- if (tunnelPort != null && nodeConfig != null && nodeConfig.getTunnelIp() != null) {
- tunnelPortWithIpExists = true;
+ private boolean tunnelWithIpAndNcExists() {
+ if (tunnelBuilderByType.isEmpty()) {
+ LOG.trace("No tunnel on switch {}", nodeId.getValue());
+ return false;
+ }
+ LOG.trace("Iterating over tunnel till tunnel with IP and node-connector is not found.");
+ for (TunnelBuilder tb : tunnelBuilderByType.values()) {
+ if (tb.getIp() != null && tb.getNodeConnectorId() != null) {
+ LOG.trace("Tunnel {} found.",tb.toString());
+ return true;
+ } else {
+ LOG.trace("Tunnel is not complete for node: {}", nodeId.getValue());
+ }
}
- LOG.trace("Status of tunnel on switch {} - tunnelPort: {} tunnelIp: {}", nodeId.getValue(),
- tunnelPort == null ? null : tunnelPort.getValue(),
- nodeConfig == null ? null : nodeConfig.getTunnelIp());
- return tunnelPortWithIpExists;
+ return false;
}
public boolean isConfigurationEmpty() {
READY
}
+
+
}