use of org.openkilda.messaging.model.DiscoveryNode in project open-kilda by telstra.
the class DiscoveryManager method makeDiscoveryPlan.
/**
* The discovery plan takes into consideration multiple metrics to determine what should be
* discovered.
*
* At present, we want to send Discovery health checks on every ISL every x period.
* And, if the Discovery fails (either isn't an ISL or ISL is down) then we may want to give up
* checking.
*
* General algorithm:
* 1) if the node is an ISL (isFoundIsl) .. and is UP .. keep checking
* 2) if the node is not an ISL (ie !isFoundIsl), then check less frequently
* 3) if the node is an ISL .. and is DOWN .. keep checking
*/
public Plan makeDiscoveryPlan() {
Plan result = new Plan();
for (DiscoveryNode subject : pollQueue) {
if (!checkForIsl(subject)) {
continue;
}
/*
* If we get a response from FL, we clear the attempts. Otherwise, no response, and
* number of attempts grows.
*
* Further, consecutivefailures = attempts - failure limit (we wait until attempt limit before increasing)
*/
Node node = new Node(subject.getSwitchId(), subject.getPortId());
if (subject.maxAttempts(islConsecutiveFailureLimit)) {
// Time to mark it as a failure and send a failure notice ** if ** it was an ISL.
if (subject.isFoundIsl() && subject.getConsecutiveFailure() == 0) {
// It is a discovery failure if it was previously a success.
// NB:
result.discoveryFailure.add(node);
logger.info("ISL IS DOWN (NO RESPONSE): {}", subject);
}
// Increment Failure = 1 after maxAttempts failure, then increases every attempt.
subject.incConsecutiveFailure();
// NB: this node can be in both discoveryFailure and needDiscovery
}
/*
* If you get here, the following are true:
* - it isn't in some filter
* - it hasn't reached failure limit (forlorn)
* - it is either time to send discovery or not
* - NB: we'll keep trying to send discovery, even if we don't get a response.
*/
if (subject.timeToCheck()) {
subject.incAttempts();
subject.resetTickCounter();
result.needDiscovery.add(node);
} else {
subject.incTick();
}
}
return result;
}
use of org.openkilda.messaging.model.DiscoveryNode in project open-kilda by telstra.
the class DiscoveryManager method handleFailed.
/**
* ISL Failure Event
* @return true if this is new .. ie this isn't a consecutive failure.
*/
public boolean handleFailed(String switchId, String portId) {
boolean stateChanged = false;
Node node = new Node(switchId, portId);
List<DiscoveryNode> subjectList = filterQueue(node);
if (subjectList.size() == 0) {
logger.warn("Ignoring \"FAILED\" request for {}: node not found", node);
} else {
DiscoveryNode subject = subjectList.get(0);
if (subject.isFoundIsl() && subject.getConsecutiveFailure() == 0) {
// This is the first failure for an ISL. That is a state change.
// IF this isn't an ISL and we receive a failure, that isn't a state change.
stateChanged = true;
logger.info("ISL IS DOWN (GOT RESPONSE): {}", subject);
}
subject.renew();
subject.incConsecutiveFailure();
subject.clearConsecutiveSuccess();
}
return stateChanged;
}
use of org.openkilda.messaging.model.DiscoveryNode in project open-kilda by telstra.
the class DiscoveryManager method handleDiscovered.
/**
* ISL Discovery Event
* @return true if this is a new event (ie first time discovered or prior failure)
*/
public boolean handleDiscovered(String switchId, String portId) {
boolean stateChanged = false;
Node node = new Node(switchId, portId);
List<DiscoveryNode> subjectList = filterQueue(node);
if (subjectList.size() == 0) {
logger.warn("Ignore \"AVAIL\" request for {}: node not found", node);
} else {
DiscoveryNode subject = subjectList.get(0);
if (!subject.isFoundIsl()) {
// "forever" mark this port as part of an ISL
// "forever" changes if we get another Switch UP message - this is documented
// elsewhere .. in short, be conservative - maybe ports changed, or TE state
// has been deleted.
// TODO: is marking foundIsl false the right way to do this? All we want is "resend to TE if it is an ISL"
subject.setFoundIsl(true);
stateChanged = true;
logger.info("FOUND ISL: {}", subject);
} else if (subject.getConsecutiveFailure() > 0) {
// We've found failures, but now we've had success, so that is a state change.
// To repeat, current model for state change is just 1 failure. If we change this
// policy, then change the test above.
stateChanged = true;
logger.info("ISL IS UP: {}", subject);
}
subject.renew();
subject.incConsecutiveSuccess();
subject.clearConsecutiveFailure();
// If one of the logs above wasn't reachd, don't log anything .. ISL was up and is still up
}
if (stateChanged) {
// Add logic to ensure we send a discovery packet for the opposite direction.
// TODO: in order to do this here, we need more information (ie the other end of the ISL)
// Since that isn't passed in and isn't available in our state, have to rely on the
// calling function.
}
return stateChanged;
}
use of org.openkilda.messaging.model.DiscoveryNode in project open-kilda by telstra.
the class DiscoveryManager method handleSwitchUp.
public void handleSwitchUp(String switchId) {
logger.info("Register switch {} into ISL discovery manager", switchId);
// TODO: this method *use to not* do anything .. but it should register the switch.
// At least, it seems like it should do something to register a switch, even
// though this can be lazily done when the first port event arrives.
/*
* If a switch comes up, clear any "isFoundIsl" flags, in case something has changed,
* and/or if the TE has cleared it's state .. this will pass along the ISL.
*/
Node node = new Node(switchId, null);
List<DiscoveryNode> subjectList = filterQueue(node, false);
if (subjectList.size() > 0) {
logger.info("Received SWITCH UP (id:{}) with EXISTING NODES. Clearing isFoundISL flags", switchId);
for (DiscoveryNode subject : subjectList) {
subject.setFoundIsl(false);
// ensure we bypass forlorn
subject.clearConsecutiveFailure();
}
}
}
use of org.openkilda.messaging.model.DiscoveryNode in project open-kilda by telstra.
the class DiscoveryManager method handlePortDown.
public void handlePortDown(String switchId, String portId) {
DiscoveryNode subject;
Node node = new Node(switchId, portId);
List<DiscoveryNode> subjectList = filterQueue(node, true);
if (subjectList.size() == 0) {
logger.warn("Can't update discovery {} -> node not found", node);
return;
}
subject = subjectList.get(0);
logger.info("Del {}", subject);
}
Aggregations