Ray Milkey

Flow Objective compiler for link collections intents

Change-Id: Ie9d820b1d7d4cdee5411a7318c246c90e3fa91d0
1 +/*
2 + * Copyright 2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onosproject.net.intent.impl.compiler;
17 +
18 +import java.util.ArrayList;
19 +import java.util.Collections;
20 +import java.util.List;
21 +import java.util.Set;
22 +import java.util.stream.Collectors;
23 +
24 +import org.apache.felix.scr.annotations.Activate;
25 +import org.apache.felix.scr.annotations.Component;
26 +import org.apache.felix.scr.annotations.Deactivate;
27 +import org.apache.felix.scr.annotations.Reference;
28 +import org.apache.felix.scr.annotations.ReferenceCardinality;
29 +import org.onosproject.core.ApplicationId;
30 +import org.onosproject.core.CoreService;
31 +import org.onosproject.net.ConnectPoint;
32 +import org.onosproject.net.DeviceId;
33 +import org.onosproject.net.Link;
34 +import org.onosproject.net.PortNumber;
35 +import org.onosproject.net.flow.DefaultTrafficSelector;
36 +import org.onosproject.net.flow.DefaultTrafficTreatment;
37 +import org.onosproject.net.flow.TrafficSelector;
38 +import org.onosproject.net.flow.TrafficTreatment;
39 +import org.onosproject.net.flowobjective.DefaultForwardingObjective;
40 +import org.onosproject.net.flowobjective.ForwardingObjective;
41 +import org.onosproject.net.flowobjective.Objective;
42 +import org.onosproject.net.intent.FlowObjectiveIntent;
43 +import org.onosproject.net.intent.Intent;
44 +import org.onosproject.net.intent.IntentCompiler;
45 +import org.onosproject.net.intent.IntentExtensionService;
46 +import org.onosproject.net.intent.LinkCollectionIntent;
47 +import org.onosproject.net.resource.link.LinkResourceAllocations;
48 +
49 +import com.google.common.collect.HashMultimap;
50 +import com.google.common.collect.SetMultimap;
51 +
52 +/**
53 + * Compiler to produce flow objectives from link collections.
54 + */
55 +@Component(immediate = true)
56 +public class LinkCollectionIntentFlowObjectivesCompiler implements IntentCompiler<LinkCollectionIntent> {
57 +
58 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
59 + protected IntentExtensionService intentManager;
60 +
61 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
62 + protected CoreService coreService;
63 +
64 + private ApplicationId appId;
65 +
66 + @Activate
67 + public void activate() {
68 + appId = coreService.registerApplication("org.onosproject.net.intent");
69 + //intentManager.registerCompiler(LinkCollectionIntent.class, this);
70 + }
71 +
72 + @Deactivate
73 + public void deactivate() {
74 + //intentManager.unregisterCompiler(LinkCollectionIntent.class);
75 + }
76 +
77 + @Override
78 + public List<Intent> compile(LinkCollectionIntent intent, List<Intent> installable,
79 + Set<LinkResourceAllocations> resources) {
80 + SetMultimap<DeviceId, PortNumber> inputPorts = HashMultimap.create();
81 + SetMultimap<DeviceId, PortNumber> outputPorts = HashMultimap.create();
82 +
83 + for (Link link : intent.links()) {
84 + inputPorts.put(link.dst().deviceId(), link.dst().port());
85 + outputPorts.put(link.src().deviceId(), link.src().port());
86 + }
87 +
88 + for (ConnectPoint ingressPoint : intent.ingressPoints()) {
89 + inputPorts.put(ingressPoint.deviceId(), ingressPoint.port());
90 + }
91 +
92 + for (ConnectPoint egressPoint : intent.egressPoints()) {
93 + outputPorts.put(egressPoint.deviceId(), egressPoint.port());
94 + }
95 +
96 + List<Objective> objectives = new ArrayList<>();
97 + List<DeviceId> devices = new ArrayList<>();
98 + for (DeviceId deviceId: outputPorts.keys()) {
99 + List<Objective> deviceObjectives =
100 + createRules(intent,
101 + deviceId,
102 + inputPorts.get(deviceId),
103 + outputPorts.get(deviceId));
104 + deviceObjectives.forEach(objective -> {
105 + objectives.add(objective);
106 + devices.add(deviceId);
107 + });
108 + }
109 + return Collections.singletonList(
110 + new FlowObjectiveIntent(appId, devices, objectives, intent.resources()));
111 + }
112 +
113 + private List<Objective> createRules(LinkCollectionIntent intent, DeviceId deviceId,
114 + Set<PortNumber> inPorts, Set<PortNumber> outPorts) {
115 + Set<PortNumber> ingressPorts = intent.ingressPoints().stream()
116 + .filter(point -> point.deviceId().equals(deviceId))
117 + .map(ConnectPoint::port)
118 + .collect(Collectors.toSet());
119 +
120 + TrafficTreatment.Builder defaultTreatmentBuilder = DefaultTrafficTreatment.builder();
121 + outPorts.stream()
122 + .forEach(defaultTreatmentBuilder::setOutput);
123 + TrafficTreatment defaultTreatment = defaultTreatmentBuilder.build();
124 +
125 + TrafficTreatment.Builder ingressTreatmentBuilder = DefaultTrafficTreatment.builder(intent.treatment());
126 + outPorts.stream()
127 + .forEach(ingressTreatmentBuilder::setOutput);
128 + TrafficTreatment ingressTreatment = ingressTreatmentBuilder.build();
129 +
130 + List<Objective> objectives = new ArrayList<>(inPorts.size());
131 + for (PortNumber inPort: inPorts) {
132 + TrafficSelector selector = DefaultTrafficSelector.builder(intent.selector()).matchInPort(inPort).build();
133 + TrafficTreatment treatment;
134 + if (ingressPorts.contains(inPort)) {
135 + treatment = ingressTreatment;
136 + } else {
137 + treatment = defaultTreatment;
138 + }
139 +
140 + Objective objective = DefaultForwardingObjective.builder()
141 + .withSelector(selector)
142 + .withTreatment(treatment)
143 + .withPriority(intent.priority())
144 + .fromApp(appId)
145 + .makePermanent()
146 + .withFlag(ForwardingObjective.Flag.VERSATILE)
147 + .add();
148 +
149 + objectives.add(objective);
150 + }
151 +
152 + return objectives;
153 + }
154 +}