blob: fcf718de56430665381ce142814e78ea6578d7cd [file] [log] [blame]
Sho SHIMIZUf7b693e2014-08-15 16:17:13 -07001package net.onrc.onos.core.newintent;
2
3import com.google.common.base.Predicates;
4import com.google.common.collect.FluentIterable;
5import com.google.common.collect.ImmutableList;
6import net.onrc.onos.api.flowmanager.FlowId;
7import net.onrc.onos.api.flowmanager.FlowIdGenerator;
8import net.onrc.onos.api.flowmanager.FlowLink;
9import net.onrc.onos.api.flowmanager.PacketPathFlow;
10import net.onrc.onos.api.flowmanager.Path;
11import net.onrc.onos.api.newintent.Intent;
12import net.onrc.onos.api.newintent.IntentIdGenerator;
13import net.onrc.onos.api.newintent.PointToPointIntent;
14import net.onrc.onos.core.intent.ConstrainedBFSTree;
15import net.onrc.onos.core.matchaction.action.Action;
16import net.onrc.onos.core.matchaction.match.Match;
17import net.onrc.onos.core.matchaction.match.PacketMatch;
18import net.onrc.onos.core.topology.BaseTopology;
19import net.onrc.onos.core.topology.ITopologyService;
20import net.onrc.onos.core.topology.LinkEvent;
21import net.onrc.onos.core.topology.Switch;
22import net.onrc.onos.core.util.SwitchPort;
23
24import java.util.Arrays;
25import java.util.List;
26
27import static com.google.common.base.Preconditions.checkNotNull;
28
29/**
30 * A intent compiler for {@link PointToPointIntent}.
31 */
32public class PointToPointIntentCompiler
33 extends AbstractFlowGeneratingIntentCompiler<PointToPointIntent> {
34
35 private final ITopologyService topologyService;
36
37 /**
38 * Constructs an intent compiler for {@link PointToPointIntent} with the specified
39 * ID generator and topology service.
40 *
41 * @param intentIdGenerator intent ID generator
42 * @param topologyService topology service
43 */
44 public PointToPointIntentCompiler(IntentIdGenerator intentIdGenerator,
45 FlowIdGenerator flowIdGenerator,
46 ITopologyService topologyService) {
47 super(intentIdGenerator, flowIdGenerator);
48 this.topologyService = checkNotNull(topologyService);
49 }
50
51 @Override
52 public List<Intent> compile(PointToPointIntent intent) {
53 Match match = intent.getMatch();
54 if (!(match instanceof PacketMatch)) {
55 throw new IntentCompilationException(
56 "intent has unsupported type of match object: " + match
57 );
58 }
59
60 SwitchPort ingress = intent.getIngressPort();
61 SwitchPort egress = intent.getEgressPort();
62 FlowId flowId = getNextFlowId();
63 Path path = calculatePath(ingress, egress);
64
65 List<Action> actions = packActions(intent, intent.getEgressPort());
66
67 PacketPathFlow flow = new PacketPathFlow(flowId, (PacketMatch) match,
68 ingress.getPortNumber(), path, actions, 0, 0);
69 return Arrays.asList((Intent) new PathFlowIntent(getNextId(), flow));
70 }
71
72 /**
73 * Calculates a path between the specified ingress port and the specified egress port.
74 * @param ingress ingress port
75 * @param egress egress port
76 * @return path
77 */
78 private Path calculatePath(SwitchPort ingress, SwitchPort egress) {
79 BaseTopology topology = topologyService.getTopology();
80 Switch source = topology.getSwitch(ingress.getDpid());
81 Switch destination = topology.getSwitch(egress.getDpid());
82
83 if (source == null) {
84 throw new PathNotFoundException("source switch not found: " + ingress.getDpid());
85 }
86 if (destination == null) {
87 throw new PathNotFoundException("destination switch not found: " + egress.getDpid());
88 }
89
90 ConstrainedBFSTree tree = new ConstrainedBFSTree(source);
91 net.onrc.onos.core.intent.Path path = tree.getPath(destination);
92 return convertPath(path);
93 }
94
95 /**
96 * Converts a {@link net.onrc.onos.core.intent.Path} to {@link Path}.
97 *
98 * @param path original {@link net.onrc.onos.core.intent.Path}
99 * @return converted {@link Path}
100 */
101 static Path convertPath(net.onrc.onos.core.intent.Path path) {
102 // would like to use filter and transform, but Findbugs detects
103 // inconsistency of use of @Nullable annotation. Then, use of the
104 // transform is avoided.
105 // Ref: https://code.google.com/p/guava-libraries/issues/detail?id=1812
106 // TODO: replace with transform when the above issue is resolved
107 ImmutableList<LinkEvent> events = FluentIterable.from(path)
108 .filter(Predicates.notNull())
109 .toList();
110
111 Path converted = new Path();
112 for (LinkEvent event: events) {
113 converted.add(new FlowLink(event.getSrc(), event.getDst()));
114 }
115 return converted;
116 }
117}