| package net.onrc.onos.core.newintent; |
| |
| import com.google.common.base.Predicates; |
| import com.google.common.collect.FluentIterable; |
| import com.google.common.collect.ImmutableList; |
| import net.onrc.onos.api.flowmanager.FlowId; |
| import net.onrc.onos.api.flowmanager.FlowLink; |
| import net.onrc.onos.api.flowmanager.PacketPathFlow; |
| import net.onrc.onos.api.flowmanager.Path; |
| import net.onrc.onos.api.newintent.Intent; |
| import net.onrc.onos.api.newintent.IntentId; |
| import net.onrc.onos.api.newintent.PointToPointIntent; |
| import net.onrc.onos.core.intent.ConstrainedBFSTree; |
| import net.onrc.onos.core.matchaction.action.Action; |
| import net.onrc.onos.core.matchaction.match.Match; |
| import net.onrc.onos.core.matchaction.match.PacketMatch; |
| import net.onrc.onos.core.topology.BaseTopology; |
| import net.onrc.onos.core.topology.ITopologyService; |
| import net.onrc.onos.core.topology.LinkData; |
| import net.onrc.onos.core.topology.Switch; |
| import net.onrc.onos.core.util.IdGenerator; |
| import net.onrc.onos.core.util.SwitchPort; |
| |
| import java.util.Arrays; |
| import java.util.List; |
| |
| import static com.google.common.base.Preconditions.checkNotNull; |
| |
| /** |
| * A intent compiler for {@link PointToPointIntent}. |
| */ |
| public class PointToPointIntentCompiler |
| extends AbstractFlowGeneratingIntentCompiler<PointToPointIntent> { |
| |
| private final ITopologyService topologyService; |
| |
| /** |
| * Constructs an intent compiler for {@link PointToPointIntent} with the specified |
| * ID generator and topology service. |
| * |
| * @param intentIdGenerator intent ID generator |
| * @param topologyService topology service |
| */ |
| public PointToPointIntentCompiler(IdGenerator<IntentId> intentIdGenerator, |
| IdGenerator<FlowId> flowIdGenerator, |
| ITopologyService topologyService) { |
| super(intentIdGenerator, flowIdGenerator); |
| this.topologyService = checkNotNull(topologyService); |
| } |
| |
| @Override |
| public List<Intent> compile(PointToPointIntent intent) { |
| Match match = intent.getMatch(); |
| if (!(match instanceof PacketMatch)) { |
| throw new IntentCompilationException( |
| "intent has unsupported type of match object: " + match |
| ); |
| } |
| |
| SwitchPort ingress = intent.getIngressPort(); |
| SwitchPort egress = intent.getEgressPort(); |
| FlowId flowId = getNextFlowId(); |
| Path path = calculatePath(ingress, egress); |
| |
| List<Action> actions = packActions(intent, intent.getEgressPort()); |
| |
| PacketPathFlow flow = new PacketPathFlow(flowId, (PacketMatch) match, |
| ingress.getPortNumber(), path, actions, 0, 0); |
| return Arrays.asList((Intent) new PathFlowIntent(getNextId(), flow)); |
| } |
| |
| /** |
| * Calculates a path between the specified ingress port and the specified egress port. |
| * @param ingress ingress port |
| * @param egress egress port |
| * @return path |
| */ |
| private Path calculatePath(SwitchPort ingress, SwitchPort egress) { |
| BaseTopology topology = topologyService.getTopology(); |
| Switch source = topology.getSwitch(ingress.getDpid()); |
| Switch destination = topology.getSwitch(egress.getDpid()); |
| |
| if (source == null) { |
| throw new PathNotFoundException("source switch not found: " + ingress.getDpid()); |
| } |
| if (destination == null) { |
| throw new PathNotFoundException("destination switch not found: " + egress.getDpid()); |
| } |
| |
| ConstrainedBFSTree tree = new ConstrainedBFSTree(source); |
| net.onrc.onos.core.intent.Path path = tree.getPath(destination); |
| return convertPath(path); |
| } |
| |
| /** |
| * Converts a {@link net.onrc.onos.core.intent.Path} to {@link Path}. |
| * |
| * @param path original {@link net.onrc.onos.core.intent.Path} |
| * @return converted {@link Path} |
| */ |
| static Path convertPath(net.onrc.onos.core.intent.Path path) { |
| // would like to use filter and transform, but Findbugs detects |
| // inconsistency of use of @Nullable annotation. Then, use of the |
| // transform is avoided. |
| // Ref: https://code.google.com/p/guava-libraries/issues/detail?id=1812 |
| // TODO: replace with transform when the above issue is resolved |
| ImmutableList<LinkData> dataEntries = FluentIterable.from(path) |
| .filter(Predicates.notNull()) |
| .toList(); |
| |
| Path converted = new Path(); |
| for (LinkData data : dataEntries) { |
| converted.add(new FlowLink(data.getSrc(), data.getDst())); |
| } |
| return converted; |
| } |
| } |