ca9ae5ccf8705beab5acf5835f850eee0e67a59d
[onosfw.git] /
1 /*
2  * Copyright 2015 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 com.google.common.collect.Lists;
19 import org.apache.felix.scr.annotations.Activate;
20 import org.apache.felix.scr.annotations.Component;
21 import org.apache.felix.scr.annotations.Deactivate;
22 import org.apache.felix.scr.annotations.Reference;
23 import org.apache.felix.scr.annotations.ReferenceCardinality;
24 import org.onosproject.core.ApplicationId;
25 import org.onosproject.core.CoreService;
26 import org.onosproject.net.ConnectPoint;
27 import org.onosproject.net.Link;
28 import org.onosproject.net.flow.DefaultFlowRule;
29 import org.onosproject.net.flow.DefaultTrafficSelector;
30 import org.onosproject.net.flow.DefaultTrafficTreatment;
31 import org.onosproject.net.flow.FlowRule;
32 import org.onosproject.net.flow.TrafficSelector;
33 import org.onosproject.net.flow.TrafficTreatment;
34 import org.onosproject.net.flow.criteria.Criteria;
35 import org.onosproject.net.flow.instructions.Instructions;
36 import org.onosproject.net.intent.FlowRuleIntent;
37 import org.onosproject.net.intent.Intent;
38 import org.onosproject.net.intent.IntentCompiler;
39 import org.onosproject.net.intent.IntentExtensionService;
40 import org.onosproject.net.intent.OpticalPathIntent;
41 import org.onosproject.net.resource.link.LinkResourceAllocations;
42 import org.onosproject.net.resource.link.LinkResourceService;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
45
46 import java.util.Collections;
47 import java.util.LinkedList;
48 import java.util.List;
49 import java.util.Set;
50
51 @Component(immediate = true)
52 public class OpticalPathIntentCompiler implements IntentCompiler<OpticalPathIntent> {
53
54     private static final Logger log = LoggerFactory.getLogger(OpticalPathIntentCompiler.class);
55
56     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
57     protected IntentExtensionService intentManager;
58
59     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
60     protected CoreService coreService;
61
62     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
63     protected LinkResourceService resourceService;
64
65     private ApplicationId appId;
66
67     @Activate
68     public void activate() {
69         appId = coreService.registerApplication("org.onosproject.net.intent");
70         intentManager.registerCompiler(OpticalPathIntent.class, this);
71     }
72
73     @Deactivate
74     public void deactivate() {
75         intentManager.unregisterCompiler(OpticalPathIntent.class);
76     }
77
78     @Override
79     public List<Intent> compile(OpticalPathIntent intent, List<Intent> installable,
80                                 Set<LinkResourceAllocations> resources) {
81         log.debug("Compiling optical path intent between {} and {}", intent.src(), intent.dst());
82
83         // Create rules for forward and reverse path
84         List<FlowRule> rules = createRules(intent);
85         if (intent.isBidirectional()) {
86             rules.addAll(createReverseRules(intent));
87         }
88
89         return Collections.singletonList(new FlowRuleIntent(appId, rules, intent.resources()));
90     }
91
92     /**
93      * Create rules for the forward path of the intent.
94      *
95      * @param intent the intent
96      * @return list of flow rules
97      */
98     private List<FlowRule> createRules(OpticalPathIntent intent) {
99         TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
100         selectorBuilder.matchInPort(intent.src().port());
101
102         List<FlowRule> rules = new LinkedList<>();
103         ConnectPoint current = intent.src();
104
105         for (Link link : intent.path().links()) {
106             TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
107             treatmentBuilder.add(Instructions.modL0Lambda(intent.lambda()));
108             treatmentBuilder.setOutput(link.src().port());
109
110             FlowRule rule = DefaultFlowRule.builder()
111                     .forDevice(current.deviceId())
112                     .withSelector(selectorBuilder.build())
113                     .withTreatment(treatmentBuilder.build())
114                     .withPriority(intent.priority())
115                     .fromApp(appId)
116                     .makePermanent()
117                     .build();
118
119             rules.add(rule);
120
121             current = link.dst();
122             selectorBuilder.matchInPort(link.dst().port());
123             selectorBuilder.add(Criteria.matchLambda(intent.lambda()));
124             selectorBuilder.add(Criteria.matchOchSignalType(intent.signalType()));
125         }
126
127         // Build the egress ROADM rule
128         TrafficTreatment.Builder treatmentLast = DefaultTrafficTreatment.builder();
129         treatmentLast.setOutput(intent.dst().port());
130
131         FlowRule rule = new DefaultFlowRule.Builder()
132                 .forDevice(intent.dst().deviceId())
133                 .withSelector(selectorBuilder.build())
134                 .withTreatment(treatmentLast.build())
135                 .withPriority(intent.priority())
136                 .fromApp(appId)
137                 .makePermanent()
138                 .build();
139         rules.add(rule);
140
141         return rules;
142     }
143
144     /**
145      * Create rules for the reverse path of the intent.
146      *
147      * @param intent the intent
148      * @return list of flow rules
149      */
150     private List<FlowRule> createReverseRules(OpticalPathIntent intent) {
151         TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
152         selectorBuilder.matchInPort(intent.dst().port());
153
154         List<FlowRule> rules = new LinkedList<>();
155         ConnectPoint current = intent.dst();
156
157         for (Link link : Lists.reverse(intent.path().links())) {
158             TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
159             treatmentBuilder.add(Instructions.modL0Lambda(intent.lambda()));
160             treatmentBuilder.setOutput(link.dst().port());
161
162             FlowRule rule = DefaultFlowRule.builder()
163                     .forDevice(current.deviceId())
164                     .withSelector(selectorBuilder.build())
165                     .withTreatment(treatmentBuilder.build())
166                     .withPriority(intent.priority())
167                     .fromApp(appId)
168                     .makePermanent()
169                     .build();
170
171             rules.add(rule);
172
173             current = link.src();
174             selectorBuilder.matchInPort(link.src().port());
175             selectorBuilder.add(Criteria.matchLambda(intent.lambda()));
176             selectorBuilder.add(Criteria.matchOchSignalType(intent.signalType()));
177         }
178
179         // Build the egress ROADM rule
180         TrafficTreatment.Builder treatmentLast = DefaultTrafficTreatment.builder();
181         treatmentLast.setOutput(intent.src().port());
182
183         FlowRule rule = new DefaultFlowRule.Builder()
184                 .forDevice(intent.src().deviceId())
185                 .withSelector(selectorBuilder.build())
186                 .withTreatment(treatmentLast.build())
187                 .withPriority(intent.priority())
188                 .fromApp(appId)
189                 .makePermanent()
190                 .build();
191         rules.add(rule);
192
193         return rules;
194     }
195 }