use of org.openkilda.model.FlowEncapsulationType in project open-kilda by telstra.
the class SwitchManagerTest method shouldDeleteRuleByInVlan.
@Test
public void shouldDeleteRuleByInVlan() throws Exception {
// given
final short testInVlan = 101;
FlowEncapsulationType flowEncapsulationType = FlowEncapsulationType.TRANSIT_VLAN;
expect(ofSwitchService.getActiveSwitch(dpid)).andStubReturn(iofSwitch);
expect(iofSwitch.getOFFactory()).andStubReturn(ofFactory);
mockFlowStatsRequest(cookie, DROP_RULE_COOKIE, VERIFICATION_BROADCAST_RULE_COOKIE, VERIFICATION_UNICAST_RULE_COOKIE);
Capture<OFFlowMod> capture = EasyMock.newCapture(CaptureType.ALL);
expect(iofSwitch.write(capture(capture))).andReturn(true).times(3);
mockBarrierRequest();
mockFlowStatsRequest(DROP_RULE_COOKIE, VERIFICATION_BROADCAST_RULE_COOKIE, VERIFICATION_UNICAST_RULE_COOKIE);
expectLastCall();
replay(ofSwitchService, iofSwitch);
// when
DeleteRulesCriteria criteria = DeleteRulesCriteria.builder().encapsulationId((int) testInVlan).encapsulationType(flowEncapsulationType).build();
List<Long> deletedRules = switchManager.deleteRulesByCriteria(dpid, false, null, criteria);
// then
final OFFlowMod actual = capture.getValue();
assertEquals(OFFlowModCommand.DELETE, actual.getCommand());
assertEquals(testInVlan, actual.getMatch().get(MatchField.VLAN_VID).getVlan());
assertNull(actual.getMatch().get(MatchField.IN_PORT));
assertEquals("any", actual.getOutPort().toString());
assertEquals(0, actual.getInstructions().size());
assertEquals(0L, actual.getCookie().getValue());
assertEquals(0L, actual.getCookieMask().getValue());
assertThat(deletedRules, containsInAnyOrder(cookie));
}
use of org.openkilda.model.FlowEncapsulationType in project open-kilda by telstra.
the class RevertNewRulesAction method perform.
@Override
protected void perform(State from, State to, Event event, FlowUpdateContext context, FlowUpdateFsm stateMachine) {
String flowId = stateMachine.getFlowId();
Flow flow = getFlow(flowId);
log.debug("Abandoning all pending commands: {}", stateMachine.getPendingCommands());
stateMachine.clearPendingAndRetriedAndFailedCommands();
FlowEncapsulationType encapsulationType = stateMachine.getTargetFlow().getFlowEncapsulationType();
FlowCommandBuilder commandBuilder = commandBuilderFactory.getBuilder(encapsulationType);
Collection<FlowSegmentRequestFactory> installCommands = new ArrayList<>();
// Reinstall old ingress rules that may be overridden by new ingress.
if (stateMachine.getOldPrimaryForwardPath() != null && stateMachine.getOldPrimaryReversePath() != null) {
FlowPath oldForward = getFlowPath(flow, stateMachine.getOldPrimaryForwardPath());
FlowPath oldReverse = getFlowPath(flow, stateMachine.getOldPrimaryReversePath());
SpeakerRequestBuildContext speakerContext = buildBaseSpeakerContextForInstall(oldForward.getSrcSwitchId(), oldReverse.getSrcSwitchId());
installCommands.addAll(commandBuilder.buildIngressOnly(stateMachine.getCommandContext(), flow, oldForward, oldReverse, speakerContext));
}
// need to clean previous requests
stateMachine.getIngressCommands().clear();
SpeakerInstallSegmentEmitter.INSTANCE.emitBatch(stateMachine.getCarrier(), installCommands, stateMachine.getIngressCommands());
stateMachine.getIngressCommands().forEach((key, value) -> stateMachine.addPendingCommand(key, value.getSwitchId()));
CommandContext commandContext = stateMachine.getCommandContext();
// Remove possible installed segments
MirrorContext mirrorContext = MirrorContext.builder().removeFlowOperation(true).build();
Collection<FlowSegmentRequestFactory> revertCommands = new ArrayList<>();
if (stateMachine.getNewPrimaryForwardPath() != null && stateMachine.getNewPrimaryReversePath() != null) {
FlowPath newForward = getFlowPath(flow, stateMachine.getNewPrimaryForwardPath());
FlowPath newReverse = getFlowPath(flow, stateMachine.getNewPrimaryReversePath());
if (stateMachine.getEndpointUpdate().isPartialUpdate()) {
SpeakerRequestBuildContext speakerRequestBuildContext = getSpeakerRequestBuildContextForRemoval(stateMachine, false);
Flow oldFlow = RequestedFlowMapper.INSTANCE.toFlow(stateMachine.getOriginalFlow());
switch(stateMachine.getEndpointUpdate()) {
case SOURCE:
switch(stateMachine.getFlowLoopOperation()) {
case NONE:
revertCommands.addAll(commandBuilder.buildIngressOnlyOneDirection(commandContext, flow, newForward, newReverse, speakerRequestBuildContext.getForward(), mirrorContext));
revertCommands.addAll(commandBuilder.buildEgressOnlyOneDirection(commandContext, oldFlow, newReverse, newForward, mirrorContext));
break;
case CREATE:
revertCommands.addAll(commandBuilder.buildAll(commandContext, flow, newForward, newReverse, speakerRequestBuildContext).stream().filter(f -> f instanceof IngressFlowLoopSegmentRequestFactory || f instanceof TransitFlowLoopSegmentRequestFactory).collect(Collectors.toList()));
break;
case DELETE:
default:
// No need to revert rules
break;
}
break;
case DESTINATION:
switch(stateMachine.getFlowLoopOperation()) {
case NONE:
revertCommands.addAll(commandBuilder.buildIngressOnlyOneDirection(commandContext, flow, newReverse, newForward, speakerRequestBuildContext.getReverse(), mirrorContext));
revertCommands.addAll(commandBuilder.buildEgressOnlyOneDirection(commandContext, oldFlow, newForward, newReverse, mirrorContext));
break;
case CREATE:
revertCommands.addAll(commandBuilder.buildAll(commandContext, flow, newForward, newReverse, speakerRequestBuildContext).stream().filter(f -> f instanceof IngressFlowLoopSegmentRequestFactory || f instanceof TransitFlowLoopSegmentRequestFactory).collect(Collectors.toList()));
break;
case DELETE:
default:
// No need to revert rules
break;
}
break;
default:
revertCommands.addAll(commandBuilder.buildIngressOnly(commandContext, flow, newForward, newReverse, speakerRequestBuildContext, mirrorContext));
revertCommands.addAll(commandBuilder.buildEgressOnly(commandContext, oldFlow, newForward, newReverse, mirrorContext));
break;
}
} else {
revertCommands.addAll(commandBuilder.buildAll(stateMachine.getCommandContext(), flow, newForward, newReverse, getSpeakerRequestBuildContextForRemoval(stateMachine, true), mirrorContext));
}
}
if (stateMachine.getNewProtectedForwardPath() != null && stateMachine.getNewProtectedReversePath() != null) {
FlowPath newForward = getFlowPath(flow, stateMachine.getNewProtectedForwardPath());
FlowPath newReverse = getFlowPath(flow, stateMachine.getNewProtectedReversePath());
Flow oldFlow = RequestedFlowMapper.INSTANCE.toFlow(stateMachine.getOriginalFlow());
if (stateMachine.getEndpointUpdate().isPartialUpdate()) {
switch(stateMachine.getEndpointUpdate()) {
case SOURCE:
if (stateMachine.getFlowLoopOperation() == NONE) {
revertCommands.addAll(commandBuilder.buildEgressOnlyOneDirection(commandContext, oldFlow, newReverse, newForward, mirrorContext));
}
break;
case DESTINATION:
if (stateMachine.getFlowLoopOperation() == NONE) {
revertCommands.addAll(commandBuilder.buildEgressOnlyOneDirection(commandContext, oldFlow, newForward, newReverse, mirrorContext));
}
break;
default:
revertCommands.addAll(commandBuilder.buildEgressOnly(commandContext, oldFlow, newForward, newReverse, mirrorContext));
break;
}
} else {
revertCommands.addAll(commandBuilder.buildAllExceptIngress(stateMachine.getCommandContext(), flow, newForward, newReverse, mirrorContext));
}
}
stateMachine.getRemoveCommands().clear();
SpeakerRemoveSegmentEmitter.INSTANCE.emitBatch(stateMachine.getCarrier(), revertCommands, stateMachine.getRemoveCommands());
stateMachine.getRemoveCommands().forEach((key, value) -> stateMachine.addPendingCommand(key, value.getSwitchId()));
if (stateMachine.getPendingCommands().isEmpty()) {
stateMachine.saveActionToHistory("No need to remove new rules or re-install original ingress rule");
stateMachine.fire(Event.RULES_REMOVED);
} else {
stateMachine.saveActionToHistory("Commands for removing new rules and re-installing original ingress rule have been sent");
}
}
use of org.openkilda.model.FlowEncapsulationType in project open-kilda by telstra.
the class RemoveOldRulesAction method perform.
@TimedExecution("fsm.remove_old_rules")
@Override
protected void perform(State from, State to, Event event, FlowRerouteContext context, FlowRerouteFsm stateMachine) {
FlowEncapsulationType encapsulationType = stateMachine.getOriginalEncapsulationType();
FlowCommandBuilder commandBuilder = commandBuilderFactory.getBuilder(encapsulationType);
Collection<FlowSegmentRequestFactory> factories = new ArrayList<>();
Flow originalFlow = getOriginalFlowWithPaths(stateMachine, stateMachine.getOriginalFlow());
SpeakerRequestBuildContext speakerContext = SpeakerRequestBuildContext.getEmpty();
MirrorContext mirrorContext = MirrorContext.builder().removeFlowOperation(true).build();
if (stateMachine.getOldPrimaryForwardPath() != null) {
FlowPath oldForward = getFlowPath(stateMachine.getOldPrimaryForwardPath());
speakerContext.setForward(buildPathContextForRemovalIngressOnly(oldForward.getSrcSwitchId()));
if (stateMachine.getOldPrimaryReversePath() != null) {
FlowPath oldReverse = getFlowPath(stateMachine.getOldPrimaryReversePath());
speakerContext.setReverse(buildPathContextForRemovalIngressOnly(oldReverse.getSrcSwitchId()));
factories.addAll(commandBuilder.buildAll(stateMachine.getCommandContext(), originalFlow, oldForward, oldReverse, speakerContext, mirrorContext));
} else {
factories.addAll(commandBuilder.buildAll(stateMachine.getCommandContext(), originalFlow, oldForward, speakerContext, mirrorContext));
}
} else if (stateMachine.getOldPrimaryReversePath() != null) {
FlowPath oldReverse = getFlowPath(stateMachine.getOldPrimaryReversePath());
speakerContext.setForward(buildPathContextForRemovalIngressOnly(oldReverse.getSrcSwitchId()));
factories.addAll(commandBuilder.buildAll(stateMachine.getCommandContext(), originalFlow, oldReverse, speakerContext, mirrorContext));
}
if (stateMachine.getOldProtectedForwardPath() != null) {
FlowPath oldForward = getFlowPath(stateMachine.getOldProtectedForwardPath());
if (stateMachine.getOldProtectedReversePath() != null) {
FlowPath oldReverse = getFlowPath(stateMachine.getOldProtectedReversePath());
factories.addAll(commandBuilder.buildAllExceptIngress(stateMachine.getCommandContext(), originalFlow, oldForward, oldReverse, mirrorContext));
} else {
factories.addAll(commandBuilder.buildAllExceptIngress(stateMachine.getCommandContext(), originalFlow, oldForward, mirrorContext));
}
} else if (stateMachine.getOldProtectedReversePath() != null) {
FlowPath oldReverse = getFlowPath(stateMachine.getOldProtectedReversePath());
factories.addAll(commandBuilder.buildAllExceptIngress(stateMachine.getCommandContext(), originalFlow, oldReverse, mirrorContext));
}
stateMachine.clearPendingAndRetriedAndFailedCommands();
if (factories.isEmpty()) {
stateMachine.saveActionToHistory("No need to remove old rules");
stateMachine.fire(Event.RULES_REMOVED);
} else {
Map<UUID, FlowSegmentRequestFactory> requestsStorage = stateMachine.getRemoveCommands();
for (FlowSegmentRequestFactory factory : factories) {
FlowSegmentRequest request = factory.makeRemoveRequest(commandIdGenerator.generate());
// TODO ensure no conflicts
requestsStorage.put(request.getCommandId(), factory);
stateMachine.getCarrier().sendSpeakerRequest(request);
}
requestsStorage.forEach((key, value) -> stateMachine.addPendingCommand(key, value.getSwitchId()));
stateMachine.saveActionToHistory("Remove commands for old rules have been sent");
}
}
use of org.openkilda.model.FlowEncapsulationType in project open-kilda by telstra.
the class SwapFlowPathsAction method swapProtectedPaths.
private void swapProtectedPaths(FlowUpdateFsm stateMachine) {
transactionManager.doInTransaction(() -> {
Flow flow = getFlow(stateMachine.getFlowId());
FlowPath oldForward = flow.getProtectedForwardPath();
if (oldForward != null) {
stateMachine.setOldProtectedForwardPath(oldForward.getPathId());
stateMachine.setOldProtectedForwardPathStatus(oldForward.getStatus());
oldForward.setStatus(FlowPathStatus.IN_PROGRESS);
}
FlowPath oldReverse = flow.getProtectedReversePath();
if (oldReverse != null) {
stateMachine.setOldProtectedReversePath(oldReverse.getPathId());
stateMachine.setOldProtectedReversePathStatus(oldReverse.getStatus());
oldReverse.setStatus(FlowPathStatus.IN_PROGRESS);
}
if (oldForward != null || oldReverse != null) {
FlowEncapsulationType oldFlowEncapsulationType = stateMachine.getOriginalFlow().getFlowEncapsulationType();
FlowResources oldProtectedResources = getResources(oldForward != null ? oldForward : oldReverse, oldReverse != null ? oldReverse : oldForward, oldFlowEncapsulationType);
stateMachine.getOldResources().add(oldProtectedResources);
}
PathId newForward = stateMachine.getNewProtectedForwardPath();
PathId newReverse = stateMachine.getNewProtectedReversePath();
flow.setProtectedForwardPathId(newForward);
flow.setProtectedReversePathId(newReverse);
if (newForward != null && newReverse != null) {
log.debug("Swapping the protected paths {}/{} with {}/{}", oldForward != null ? oldForward.getPathId() : null, oldReverse != null ? oldReverse.getPathId() : null, newForward, newReverse);
saveHistory(stateMachine, stateMachine.getFlowId(), newForward, newReverse);
}
});
}
use of org.openkilda.model.FlowEncapsulationType in project open-kilda by telstra.
the class PathsService method getPaths.
/**
* Get paths.
*/
public List<PathsInfoData> getPaths(SwitchId srcSwitchId, SwitchId dstSwitchId, FlowEncapsulationType requestEncapsulationType, PathComputationStrategy requestPathComputationStrategy, Duration maxLatency, Duration maxLatencyTier2) throws RecoverableException, SwitchNotFoundException, UnroutableFlowException {
if (Objects.equals(srcSwitchId, dstSwitchId)) {
throw new IllegalArgumentException(String.format("Source and destination switch IDs are equal: '%s'", srcSwitchId));
}
if (!switchRepository.exists(srcSwitchId)) {
throw new SwitchNotFoundException(srcSwitchId);
}
if (!switchRepository.exists(dstSwitchId)) {
throw new SwitchNotFoundException(dstSwitchId);
}
KildaConfiguration kildaConfiguration = kildaConfigurationRepository.getOrDefault();
FlowEncapsulationType flowEncapsulationType = Optional.ofNullable(requestEncapsulationType).orElse(kildaConfiguration.getFlowEncapsulationType());
SwitchProperties srcProperties = switchPropertiesRepository.findBySwitchId(srcSwitchId).orElseThrow(() -> new SwitchPropertiesNotFoundException(srcSwitchId));
if (!srcProperties.getSupportedTransitEncapsulation().contains(flowEncapsulationType)) {
throw new IllegalArgumentException(String.format("Switch %s doesn't support %s encapslation type. Choose " + "one of the supported encapsulation types %s or update switch properties and add needed " + "encapsulation type.", srcSwitchId, flowEncapsulationType, srcProperties.getSupportedTransitEncapsulation()));
}
SwitchProperties dstProperties = switchPropertiesRepository.findBySwitchId(dstSwitchId).orElseThrow(() -> new SwitchPropertiesNotFoundException(dstSwitchId));
if (!dstProperties.getSupportedTransitEncapsulation().contains(flowEncapsulationType)) {
throw new IllegalArgumentException(String.format("Switch %s doesn't support %s encapslation type. Choose " + "one of the supported encapsulation types %s or update switch properties and add needed " + "encapsulation type.", dstSwitchId, requestEncapsulationType, dstProperties.getSupportedTransitEncapsulation()));
}
PathComputationStrategy pathComputationStrategy = Optional.ofNullable(requestPathComputationStrategy).orElse(kildaConfiguration.getPathComputationStrategy());
List<Path> flowPaths = pathComputer.getNPaths(srcSwitchId, dstSwitchId, MAX_PATH_COUNT, flowEncapsulationType, pathComputationStrategy, maxLatency, maxLatencyTier2);
return flowPaths.stream().map(PathMapper.INSTANCE::map).map(path -> PathsInfoData.builder().path(path).build()).collect(Collectors.toList());
}
Aggregations