LogicallyAttachedClassifier implements ClassifierInterface { @Override public FlowDetails createClassifierOutFlow(String flowKey, Match match, SfcNshHeader sfcNshHeader, String classifierNodeName) { if ( Strings.isNullOrEmpty(flowKey) || sfcNshHeader == null || Strings.isNullOrEmpty(classifierNodeName) ) { LOG.error("createClassifierOutFlow - Wrong inputs; either the flow key of the NSH header are not correct"); return null; } LOG.info("createClassifierOutFlow - Validated inputs"); List<Action> theActions = buildNshActions(sfcNshHeader); InstructionsBuilder isb; DpnIdType classifierNodeDpnId = LogicalClassifierDataGetter.getDpnIdFromNodeName(classifierNodeName); DpnIdType firstHopDataplaneId = logicalSffDataGetter.getFirstHopDataplaneId(sfcNshHeader.getRsp()) .orElseThrow(IllegalArgumentException::new); if(classifierNodeDpnId.equals(firstHopDataplaneId)) { LOG.info("createClassifierOutFlow - Classifier co-located w/ first SFF; jump to transport ingress: {}", ClassifierGeniusIntegration.getTransportIngressTable()); isb = SfcOpenflowUtils.wrapActionsIntoApplyActionsInstruction(theActions); SfcOpenflowUtils.appendGotoTableInstruction(isb, ClassifierGeniusIntegration.getTransportIngressTable()); } else { String theTunnelIf = logicalSffDataGetter.getInterfaceBetweenDpnIds(classifierNodeDpnId, firstHopDataplaneId) .orElseThrow(RuntimeException::new); LOG.info("createClassifierOutFlow - Must go through tunnel: {}. src: {}; dst: {}", theTunnelIf, classifierNodeDpnId.getValue().toString(), firstHopDataplaneId.getValue().toString()); List<Action> actionList = logicalSffDataGetter.getEgressActionsForTunnelInterface(theTunnelIf, theActions.size()); if (!actionList.isEmpty()) { theActions.addAll(actionList); } isb = SfcOpenflowUtils.wrapActionsIntoApplyActionsInstruction(theActions); } FlowBuilder flowb = new FlowBuilder(); flowb.setId(new FlowId(flowKey)) .setTableId(ClassifierGeniusIntegration.getClassifierTable()) .setKey(new FlowKey(new FlowId(flowKey))) .setPriority(SfcScfOfUtils.FLOW_PRIORITY_CLASSIFIER) .setMatch(match) .setInstructions(isb.build()); return classifierHandler.addRspRelatedFlowIntoNode(classifierNodeName, flowb, sfcNshHeader.getNshNsp()); } LogicallyAttachedClassifier(LogicalClassifierDataGetter theDataGetter); @Override FlowDetails initClassifierTable(String nodeName); @Override FlowDetails createClassifierOutFlow(String flowKey,
                                               Match match,
                                               SfcNshHeader sfcNshHeader,
                                               String classifierNodeName); @Override FlowDetails createClassifierInFlow(String flowKey, SfcNshHeader sfcNshHeader, Long outPort, String nodeName); @Override FlowDetails createClassifierRelayFlow(String flowKey, SfcNshHeader sfcNshHeader, String nodeName); @Override List<FlowDetails> createDpdkFlows(String nodeName, long rspPathId); @Override Optional<String> getNodeName(String theInterfaceName); @Override Optional<Long> getInPort(String ifName, String nodeName);  }
@Test public void outFlowPositiveCoLocated() { FlowDetails flowDetails = logicalScf.createClassifierOutFlow("the-key", aclMatch, SfcNshHeader.getSfcNshHeader(new RspName("RSP_1")), FIRST_SF_NODE_NAME); Flow flow = flowDetails.getFlow(); Assert.assertEquals(2, flow.getInstructions().getInstruction().size()); Assert.assertEquals(10, ((ApplyActionsCase) flow.getInstructions().getInstruction().get(0).getInstruction()) .getApplyActions().getAction().size()); Assert.assertEquals(10, ((ApplyActionsCase) flow.getInstructions().getInstruction().get(0).getInstruction()) .getApplyActions().getAction().size()); Assert.assertEquals(new Short("83"), ((GoToTableCase) flow.getInstructions().getInstruction().get(1).getInstruction()) .getGoToTable().getTableId()); }
@Test public void outFlowPositiveUseTunnel() { PowerMockito.when(LogicalClassifierDataGetter.getDpnIdFromNodeName(FIRST_SF_NODE_NAME)) .thenReturn(FIRST_SF_DPNID); PowerMockito.when(LogicalClassifierDataGetter.getDpnIdFromNodeName(CLASSIFIER_NODE_NAME)) .thenReturn(CLASSIFIER_DPNID); FlowDetails flowDetails = logicalScf.createClassifierOutFlow("the-key", aclMatch, SfcNshHeader.getSfcNshHeader(new RspName("RSP_1")), CLASSIFIER_NODE_NAME); Flow flow = flowDetails.getFlow(); Assert.assertEquals(1, flow.getInstructions().getInstruction().size()); Assert.assertEquals(10, ((ApplyActionsCase) flow.getInstructions().getInstruction().get(0).getInstruction()) .getApplyActions().getAction().size()); }
@Test public void outFlowEmptyFlowKey() { Assert.assertNull(logicalScf.createClassifierOutFlow( null, aclMatch, SfcNshHeader.getSfcNshHeader(new RspName("RSP_1")), FIRST_SF_NODE_NAME)); }
@Test public void outFlowEmptyNshHeader() { Assert.assertNull(logicalScf.createClassifierOutFlow( "the-key", aclMatch, null, FIRST_SF_NODE_NAME)); }