@Test public void testUpdateAction_ChainNameNull() { ActionBuilder actionBuilder = mock(ActionBuilder.class); List<ActionBuilder> actions = Collections.singletonList(actionBuilder); Map<String, Object> params = new HashMap<>(); params.put(ChainActionDefinition.SFC_CHAIN_NAME, null); Integer order = 0; NetworkElements netElements = mock(NetworkElements.class); OfWriter ofWriter = mock(OfWriter.class); List<ActionBuilder> result = chainAction.updateAction(actions, params, order, netElements, ofWriter, ctx, Direction.In); Assert.assertNull(result); }
@Override public List<ActionBuilder> updateAction(List<ActionBuilder> actions, Map<String, Object> params, Integer order, NetworkElements netElements, OfWriter ofWriter, OfContext ctx, Direction direction) { String chainName = null; if (params != null) { LOG.debug("updateAction: Searching for named chain"); for (String name : params.keySet()) { if (name.equals(ChainActionDefinition.SFC_CHAIN_NAME)) { chainName = (String) params.get(name); if (chainName == null) { LOG.error("updateAction: Chain name was null"); return null; } } } } else { LOG.error("updateAction: Parameters null for chain action"); return null; } if (chainName == null) { LOG.error("updateAction: Chain name was null"); return null; } Long tunnelId; ServiceFunctionPath sfcPath = getSfcPath(new SfcName(chainName)); if (sfcPath == null || sfcPath.getName() == null) { LOG.error("updateAction: SFC Path was invalid. Either null or name was null.", sfcPath); return null; } String tenantName = netElements.getSrcEp().getTenant().getValue(); RspName rspName = new RspName(sfcPath.getName().getValue() + tenantName + "-gbp-rsp"); ReadOnlyTransaction rTx = ctx.getDataBroker().newReadOnlyTransaction(); RenderedServicePath renderedServicePath; RenderedServicePath rsp = getRspByName(rspName, rTx); tunnelId = (long) netElements.getSrcEpOrdinals().getTunnelId(); if (rsp == null) { renderedServicePath = createRsp(sfcPath, rspName); if (renderedServicePath != null) { LOG.info("updateAction: Could not find RSP {} for Chain {}, created.", rspName, chainName); } else { LOG.error("updateAction: Could not create RSP {} for Chain {}", rspName, chainName); return null; } } else { renderedServicePath = rsp; } try { if (sfcPath.isSymmetric() && resolvedSymmetricChains.contains(chainName)) { rspName = new RspName(rspName.getValue() + "-Reverse"); rsp = getRspByName(rspName, rTx); tunnelId = (long) netElements.getDstEpOrdinals().getTunnelId(); if (rsp == null) { LOG.info("updateAction: Could not find Reverse RSP {} for Chain {}", rspName, chainName); renderedServicePath = createSymmetricRsp(renderedServicePath); if (renderedServicePath == null) { LOG.error("updateAction: Could not create RSP {} for Chain {}", rspName, chainName); return null; } } else { renderedServicePath = rsp; } } } catch (Exception e) { LOG.error("updateAction: Attempting to determine if srcEp {} was consumer.", netElements.getSrcEp().getKey(), e); return null; } RenderedServicePathFirstHop rspFirstHop = SfcProviderRenderedPathAPI.readRenderedServicePathFirstHop(rspName); if (!isValidRspFirstHop(rspFirstHop)) { return null; } NodeId tunnelDestNodeId = netElements.getDstNodeId(); IpAddress tunnelDest = ctx.getSwitchManager().getTunnelIP(tunnelDestNodeId, TunnelTypeVxlanGpe.class); if (tunnelDest == null || tunnelDest.getIpv4Address() == null) { LOG.error("updateAction: Invalid tunnelDest for NodeId: {}", tunnelDestNodeId); return null; } RenderedServicePathHop firstRspHop = renderedServicePath.getRenderedServicePathHop().get(0); RenderedServicePathHop lastRspHop = Iterables.getLast(renderedServicePath.getRenderedServicePathHop()); SfcNshHeader sfcNshHeader = new SfcNshHeaderBuilder().setNshTunIpDst(IetfModelCodec.ipv4Address2010(rspFirstHop.getIp().getIpv4Address())) .setNshTunUdpPort(IetfModelCodec.portNumber2010(rspFirstHop.getPort())) .setNshNsiToChain(firstRspHop.getServiceIndex()) .setNshNspToChain(renderedServicePath.getPathId()) .setNshNsiFromChain((short) (lastRspHop.getServiceIndex().intValue() - 1)) .setNshNspFromChain(renderedServicePath.getPathId()) .setNshMetaC1(SfcNshHeader.convertIpAddressToLong(tunnelDest.getIpv4Address())) .setNshMetaC2(tunnelId) .build(); createChainTunnelFlows(sfcNshHeader, netElements, ofWriter, ctx, direction); if (direction.equals(Direction.Out) ) { actions = addActionBuilder(actions, nxPushNshAction(), order); actions = addActionBuilder(actions, nxLoadNshMdtypeAction(Short.valueOf((short)0x1)), order); actions = addActionBuilder(actions, nxLoadNshNpAction(Short.valueOf((short)0x3)), order); actions = addActionBuilder(actions, nxSetNsiAction(sfcNshHeader.getNshNsiToChain()), order); actions = addActionBuilder(actions, nxSetNspAction(sfcNshHeader.getNshNspToChain()), order); } else { return null; } return actions; }
ChainAction extends Action { @Override public List<ActionBuilder> updateAction(List<ActionBuilder> actions, Map<String, Object> params, Integer order, NetworkElements netElements, OfWriter ofWriter, OfContext ctx, Direction direction) { String chainName = null; if (params != null) { LOG.debug("updateAction: Searching for named chain"); for (String name : params.keySet()) { if (name.equals(ChainActionDefinition.SFC_CHAIN_NAME)) { chainName = (String) params.get(name); if (chainName == null) { LOG.error("updateAction: Chain name was null"); return null; } } } } else { LOG.error("updateAction: Parameters null for chain action"); return null; } if (chainName == null) { LOG.error("updateAction: Chain name was null"); return null; } Long tunnelId; ServiceFunctionPath sfcPath = getSfcPath(new SfcName(chainName)); if (sfcPath == null || sfcPath.getName() == null) { LOG.error("updateAction: SFC Path was invalid. Either null or name was null.", sfcPath); return null; } String tenantName = netElements.getSrcEp().getTenant().getValue(); RspName rspName = new RspName(sfcPath.getName().getValue() + tenantName + "-gbp-rsp"); ReadOnlyTransaction rTx = ctx.getDataBroker().newReadOnlyTransaction(); RenderedServicePath renderedServicePath; RenderedServicePath rsp = getRspByName(rspName, rTx); tunnelId = (long) netElements.getSrcEpOrdinals().getTunnelId(); if (rsp == null) { renderedServicePath = createRsp(sfcPath, rspName); if (renderedServicePath != null) { LOG.info("updateAction: Could not find RSP {} for Chain {}, created.", rspName, chainName); } else { LOG.error("updateAction: Could not create RSP {} for Chain {}", rspName, chainName); return null; } } else { renderedServicePath = rsp; } try { if (sfcPath.isSymmetric() && resolvedSymmetricChains.contains(chainName)) { rspName = new RspName(rspName.getValue() + "-Reverse"); rsp = getRspByName(rspName, rTx); tunnelId = (long) netElements.getDstEpOrdinals().getTunnelId(); if (rsp == null) { LOG.info("updateAction: Could not find Reverse RSP {} for Chain {}", rspName, chainName); renderedServicePath = createSymmetricRsp(renderedServicePath); if (renderedServicePath == null) { LOG.error("updateAction: Could not create RSP {} for Chain {}", rspName, chainName); return null; } } else { renderedServicePath = rsp; } } } catch (Exception e) { LOG.error("updateAction: Attempting to determine if srcEp {} was consumer.", netElements.getSrcEp().getKey(), e); return null; } RenderedServicePathFirstHop rspFirstHop = SfcProviderRenderedPathAPI.readRenderedServicePathFirstHop(rspName); if (!isValidRspFirstHop(rspFirstHop)) { return null; } NodeId tunnelDestNodeId = netElements.getDstNodeId(); IpAddress tunnelDest = ctx.getSwitchManager().getTunnelIP(tunnelDestNodeId, TunnelTypeVxlanGpe.class); if (tunnelDest == null || tunnelDest.getIpv4Address() == null) { LOG.error("updateAction: Invalid tunnelDest for NodeId: {}", tunnelDestNodeId); return null; } RenderedServicePathHop firstRspHop = renderedServicePath.getRenderedServicePathHop().get(0); RenderedServicePathHop lastRspHop = Iterables.getLast(renderedServicePath.getRenderedServicePathHop()); SfcNshHeader sfcNshHeader = new SfcNshHeaderBuilder().setNshTunIpDst(IetfModelCodec.ipv4Address2010(rspFirstHop.getIp().getIpv4Address())) .setNshTunUdpPort(IetfModelCodec.portNumber2010(rspFirstHop.getPort())) .setNshNsiToChain(firstRspHop.getServiceIndex()) .setNshNspToChain(renderedServicePath.getPathId()) .setNshNsiFromChain((short) (lastRspHop.getServiceIndex().intValue() - 1)) .setNshNspFromChain(renderedServicePath.getPathId()) .setNshMetaC1(SfcNshHeader.convertIpAddressToLong(tunnelDest.getIpv4Address())) .setNshMetaC2(tunnelId) .build(); createChainTunnelFlows(sfcNshHeader, netElements, ofWriter, ctx, direction); if (direction.equals(Direction.Out) ) { actions = addActionBuilder(actions, nxPushNshAction(), order); actions = addActionBuilder(actions, nxLoadNshMdtypeAction(Short.valueOf((short)0x1)), order); actions = addActionBuilder(actions, nxLoadNshNpAction(Short.valueOf((short)0x3)), order); actions = addActionBuilder(actions, nxSetNsiAction(sfcNshHeader.getNshNsiToChain()), order); actions = addActionBuilder(actions, nxSetNspAction(sfcNshHeader.getNshNspToChain()), order); } else { return null; } return actions; } }
ChainAction extends Action { @Override public List<ActionBuilder> updateAction(List<ActionBuilder> actions, Map<String, Object> params, Integer order, NetworkElements netElements, OfWriter ofWriter, OfContext ctx, Direction direction) { String chainName = null; if (params != null) { LOG.debug("updateAction: Searching for named chain"); for (String name : params.keySet()) { if (name.equals(ChainActionDefinition.SFC_CHAIN_NAME)) { chainName = (String) params.get(name); if (chainName == null) { LOG.error("updateAction: Chain name was null"); return null; } } } } else { LOG.error("updateAction: Parameters null for chain action"); return null; } if (chainName == null) { LOG.error("updateAction: Chain name was null"); return null; } Long tunnelId; ServiceFunctionPath sfcPath = getSfcPath(new SfcName(chainName)); if (sfcPath == null || sfcPath.getName() == null) { LOG.error("updateAction: SFC Path was invalid. Either null or name was null.", sfcPath); return null; } String tenantName = netElements.getSrcEp().getTenant().getValue(); RspName rspName = new RspName(sfcPath.getName().getValue() + tenantName + "-gbp-rsp"); ReadOnlyTransaction rTx = ctx.getDataBroker().newReadOnlyTransaction(); RenderedServicePath renderedServicePath; RenderedServicePath rsp = getRspByName(rspName, rTx); tunnelId = (long) netElements.getSrcEpOrdinals().getTunnelId(); if (rsp == null) { renderedServicePath = createRsp(sfcPath, rspName); if (renderedServicePath != null) { LOG.info("updateAction: Could not find RSP {} for Chain {}, created.", rspName, chainName); } else { LOG.error("updateAction: Could not create RSP {} for Chain {}", rspName, chainName); return null; } } else { renderedServicePath = rsp; } try { if (sfcPath.isSymmetric() && resolvedSymmetricChains.contains(chainName)) { rspName = new RspName(rspName.getValue() + "-Reverse"); rsp = getRspByName(rspName, rTx); tunnelId = (long) netElements.getDstEpOrdinals().getTunnelId(); if (rsp == null) { LOG.info("updateAction: Could not find Reverse RSP {} for Chain {}", rspName, chainName); renderedServicePath = createSymmetricRsp(renderedServicePath); if (renderedServicePath == null) { LOG.error("updateAction: Could not create RSP {} for Chain {}", rspName, chainName); return null; } } else { renderedServicePath = rsp; } } } catch (Exception e) { LOG.error("updateAction: Attempting to determine if srcEp {} was consumer.", netElements.getSrcEp().getKey(), e); return null; } RenderedServicePathFirstHop rspFirstHop = SfcProviderRenderedPathAPI.readRenderedServicePathFirstHop(rspName); if (!isValidRspFirstHop(rspFirstHop)) { return null; } NodeId tunnelDestNodeId = netElements.getDstNodeId(); IpAddress tunnelDest = ctx.getSwitchManager().getTunnelIP(tunnelDestNodeId, TunnelTypeVxlanGpe.class); if (tunnelDest == null || tunnelDest.getIpv4Address() == null) { LOG.error("updateAction: Invalid tunnelDest for NodeId: {}", tunnelDestNodeId); return null; } RenderedServicePathHop firstRspHop = renderedServicePath.getRenderedServicePathHop().get(0); RenderedServicePathHop lastRspHop = Iterables.getLast(renderedServicePath.getRenderedServicePathHop()); SfcNshHeader sfcNshHeader = new SfcNshHeaderBuilder().setNshTunIpDst(IetfModelCodec.ipv4Address2010(rspFirstHop.getIp().getIpv4Address())) .setNshTunUdpPort(IetfModelCodec.portNumber2010(rspFirstHop.getPort())) .setNshNsiToChain(firstRspHop.getServiceIndex()) .setNshNspToChain(renderedServicePath.getPathId()) .setNshNsiFromChain((short) (lastRspHop.getServiceIndex().intValue() - 1)) .setNshNspFromChain(renderedServicePath.getPathId()) .setNshMetaC1(SfcNshHeader.convertIpAddressToLong(tunnelDest.getIpv4Address())) .setNshMetaC2(tunnelId) .build(); createChainTunnelFlows(sfcNshHeader, netElements, ofWriter, ctx, direction); if (direction.equals(Direction.Out) ) { actions = addActionBuilder(actions, nxPushNshAction(), order); actions = addActionBuilder(actions, nxLoadNshMdtypeAction(Short.valueOf((short)0x1)), order); actions = addActionBuilder(actions, nxLoadNshNpAction(Short.valueOf((short)0x3)), order); actions = addActionBuilder(actions, nxSetNsiAction(sfcNshHeader.getNshNsiToChain()), order); actions = addActionBuilder(actions, nxSetNspAction(sfcNshHeader.getNshNspToChain()), order); } else { return null; } return actions; }  }
ChainAction extends Action { @Override public List<ActionBuilder> updateAction(List<ActionBuilder> actions, Map<String, Object> params, Integer order, NetworkElements netElements, OfWriter ofWriter, OfContext ctx, Direction direction) { String chainName = null; if (params != null) { LOG.debug("updateAction: Searching for named chain"); for (String name : params.keySet()) { if (name.equals(ChainActionDefinition.SFC_CHAIN_NAME)) { chainName = (String) params.get(name); if (chainName == null) { LOG.error("updateAction: Chain name was null"); return null; } } } } else { LOG.error("updateAction: Parameters null for chain action"); return null; } if (chainName == null) { LOG.error("updateAction: Chain name was null"); return null; } Long tunnelId; ServiceFunctionPath sfcPath = getSfcPath(new SfcName(chainName)); if (sfcPath == null || sfcPath.getName() == null) { LOG.error("updateAction: SFC Path was invalid. Either null or name was null.", sfcPath); return null; } String tenantName = netElements.getSrcEp().getTenant().getValue(); RspName rspName = new RspName(sfcPath.getName().getValue() + tenantName + "-gbp-rsp"); ReadOnlyTransaction rTx = ctx.getDataBroker().newReadOnlyTransaction(); RenderedServicePath renderedServicePath; RenderedServicePath rsp = getRspByName(rspName, rTx); tunnelId = (long) netElements.getSrcEpOrdinals().getTunnelId(); if (rsp == null) { renderedServicePath = createRsp(sfcPath, rspName); if (renderedServicePath != null) { LOG.info("updateAction: Could not find RSP {} for Chain {}, created.", rspName, chainName); } else { LOG.error("updateAction: Could not create RSP {} for Chain {}", rspName, chainName); return null; } } else { renderedServicePath = rsp; } try { if (sfcPath.isSymmetric() && resolvedSymmetricChains.contains(chainName)) { rspName = new RspName(rspName.getValue() + "-Reverse"); rsp = getRspByName(rspName, rTx); tunnelId = (long) netElements.getDstEpOrdinals().getTunnelId(); if (rsp == null) { LOG.info("updateAction: Could not find Reverse RSP {} for Chain {}", rspName, chainName); renderedServicePath = createSymmetricRsp(renderedServicePath); if (renderedServicePath == null) { LOG.error("updateAction: Could not create RSP {} for Chain {}", rspName, chainName); return null; } } else { renderedServicePath = rsp; } } } catch (Exception e) { LOG.error("updateAction: Attempting to determine if srcEp {} was consumer.", netElements.getSrcEp().getKey(), e); return null; } RenderedServicePathFirstHop rspFirstHop = SfcProviderRenderedPathAPI.readRenderedServicePathFirstHop(rspName); if (!isValidRspFirstHop(rspFirstHop)) { return null; } NodeId tunnelDestNodeId = netElements.getDstNodeId(); IpAddress tunnelDest = ctx.getSwitchManager().getTunnelIP(tunnelDestNodeId, TunnelTypeVxlanGpe.class); if (tunnelDest == null || tunnelDest.getIpv4Address() == null) { LOG.error("updateAction: Invalid tunnelDest for NodeId: {}", tunnelDestNodeId); return null; } RenderedServicePathHop firstRspHop = renderedServicePath.getRenderedServicePathHop().get(0); RenderedServicePathHop lastRspHop = Iterables.getLast(renderedServicePath.getRenderedServicePathHop()); SfcNshHeader sfcNshHeader = new SfcNshHeaderBuilder().setNshTunIpDst(IetfModelCodec.ipv4Address2010(rspFirstHop.getIp().getIpv4Address())) .setNshTunUdpPort(IetfModelCodec.portNumber2010(rspFirstHop.getPort())) .setNshNsiToChain(firstRspHop.getServiceIndex()) .setNshNspToChain(renderedServicePath.getPathId()) .setNshNsiFromChain((short) (lastRspHop.getServiceIndex().intValue() - 1)) .setNshNspFromChain(renderedServicePath.getPathId()) .setNshMetaC1(SfcNshHeader.convertIpAddressToLong(tunnelDest.getIpv4Address())) .setNshMetaC2(tunnelId) .build(); createChainTunnelFlows(sfcNshHeader, netElements, ofWriter, ctx, direction); if (direction.equals(Direction.Out) ) { actions = addActionBuilder(actions, nxPushNshAction(), order); actions = addActionBuilder(actions, nxLoadNshMdtypeAction(Short.valueOf((short)0x1)), order); actions = addActionBuilder(actions, nxLoadNshNpAction(Short.valueOf((short)0x3)), order); actions = addActionBuilder(actions, nxSetNsiAction(sfcNshHeader.getNshNsiToChain()), order); actions = addActionBuilder(actions, nxSetNspAction(sfcNshHeader.getNshNspToChain()), order); } else { return null; } return actions; }  void setResolvedSymmetricChains(List<String> resolvedSymmetricChains); @Override ActionDefinitionId getId(); @Override ActionDefinition getActionDef(); @Override List<ActionBuilder> updateAction(List<ActionBuilder> actions, Map<String, Object> params, Integer order,
                                            NetworkElements netElements, OfWriter ofWriter,
                                            OfContext ctx, Direction direction); @Override ValidationResult validate(ActionInstance actionInstance); static ServiceFunctionPath getSfcPath(SfcName chainName); @Override List<SupportedParameterValues> getSupportedParameterValues(); }
ChainAction extends Action { @Override public List<ActionBuilder> updateAction(List<ActionBuilder> actions, Map<String, Object> params, Integer order, NetworkElements netElements, OfWriter ofWriter, OfContext ctx, Direction direction) { String chainName = null; if (params != null) { LOG.debug("updateAction: Searching for named chain"); for (String name : params.keySet()) { if (name.equals(ChainActionDefinition.SFC_CHAIN_NAME)) { chainName = (String) params.get(name); if (chainName == null) { LOG.error("updateAction: Chain name was null"); return null; } } } } else { LOG.error("updateAction: Parameters null for chain action"); return null; } if (chainName == null) { LOG.error("updateAction: Chain name was null"); return null; } Long tunnelId; ServiceFunctionPath sfcPath = getSfcPath(new SfcName(chainName)); if (sfcPath == null || sfcPath.getName() == null) { LOG.error("updateAction: SFC Path was invalid. Either null or name was null.", sfcPath); return null; } String tenantName = netElements.getSrcEp().getTenant().getValue(); RspName rspName = new RspName(sfcPath.getName().getValue() + tenantName + "-gbp-rsp"); ReadOnlyTransaction rTx = ctx.getDataBroker().newReadOnlyTransaction(); RenderedServicePath renderedServicePath; RenderedServicePath rsp = getRspByName(rspName, rTx); tunnelId = (long) netElements.getSrcEpOrdinals().getTunnelId(); if (rsp == null) { renderedServicePath = createRsp(sfcPath, rspName); if (renderedServicePath != null) { LOG.info("updateAction: Could not find RSP {} for Chain {}, created.", rspName, chainName); } else { LOG.error("updateAction: Could not create RSP {} for Chain {}", rspName, chainName); return null; } } else { renderedServicePath = rsp; } try { if (sfcPath.isSymmetric() && resolvedSymmetricChains.contains(chainName)) { rspName = new RspName(rspName.getValue() + "-Reverse"); rsp = getRspByName(rspName, rTx); tunnelId = (long) netElements.getDstEpOrdinals().getTunnelId(); if (rsp == null) { LOG.info("updateAction: Could not find Reverse RSP {} for Chain {}", rspName, chainName); renderedServicePath = createSymmetricRsp(renderedServicePath); if (renderedServicePath == null) { LOG.error("updateAction: Could not create RSP {} for Chain {}", rspName, chainName); return null; } } else { renderedServicePath = rsp; } } } catch (Exception e) { LOG.error("updateAction: Attempting to determine if srcEp {} was consumer.", netElements.getSrcEp().getKey(), e); return null; } RenderedServicePathFirstHop rspFirstHop = SfcProviderRenderedPathAPI.readRenderedServicePathFirstHop(rspName); if (!isValidRspFirstHop(rspFirstHop)) { return null; } NodeId tunnelDestNodeId = netElements.getDstNodeId(); IpAddress tunnelDest = ctx.getSwitchManager().getTunnelIP(tunnelDestNodeId, TunnelTypeVxlanGpe.class); if (tunnelDest == null || tunnelDest.getIpv4Address() == null) { LOG.error("updateAction: Invalid tunnelDest for NodeId: {}", tunnelDestNodeId); return null; } RenderedServicePathHop firstRspHop = renderedServicePath.getRenderedServicePathHop().get(0); RenderedServicePathHop lastRspHop = Iterables.getLast(renderedServicePath.getRenderedServicePathHop()); SfcNshHeader sfcNshHeader = new SfcNshHeaderBuilder().setNshTunIpDst(IetfModelCodec.ipv4Address2010(rspFirstHop.getIp().getIpv4Address())) .setNshTunUdpPort(IetfModelCodec.portNumber2010(rspFirstHop.getPort())) .setNshNsiToChain(firstRspHop.getServiceIndex()) .setNshNspToChain(renderedServicePath.getPathId()) .setNshNsiFromChain((short) (lastRspHop.getServiceIndex().intValue() - 1)) .setNshNspFromChain(renderedServicePath.getPathId()) .setNshMetaC1(SfcNshHeader.convertIpAddressToLong(tunnelDest.getIpv4Address())) .setNshMetaC2(tunnelId) .build(); createChainTunnelFlows(sfcNshHeader, netElements, ofWriter, ctx, direction); if (direction.equals(Direction.Out) ) { actions = addActionBuilder(actions, nxPushNshAction(), order); actions = addActionBuilder(actions, nxLoadNshMdtypeAction(Short.valueOf((short)0x1)), order); actions = addActionBuilder(actions, nxLoadNshNpAction(Short.valueOf((short)0x3)), order); actions = addActionBuilder(actions, nxSetNsiAction(sfcNshHeader.getNshNsiToChain()), order); actions = addActionBuilder(actions, nxSetNspAction(sfcNshHeader.getNshNspToChain()), order); } else { return null; } return actions; }  void setResolvedSymmetricChains(List<String> resolvedSymmetricChains); @Override ActionDefinitionId getId(); @Override ActionDefinition getActionDef(); @Override List<ActionBuilder> updateAction(List<ActionBuilder> actions, Map<String, Object> params, Integer order,
                                            NetworkElements netElements, OfWriter ofWriter,
                                            OfContext ctx, Direction direction); @Override ValidationResult validate(ActionInstance actionInstance); static ServiceFunctionPath getSfcPath(SfcName chainName); @Override List<SupportedParameterValues> getSupportedParameterValues();  }