blob: d66e8495de3186fd6949fe0e15f1ac8dcad50926 [file] [log] [blame]
Thomas Vachuskaedc944c2014-11-04 15:42:25 -08001/*
2 * Copyright 2014 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 */
16package org.onlab.onos.net.intent.impl;
17
Sho SHIMIZU56531512014-11-10 15:27:49 -080018import com.google.common.collect.ImmutableList;
Thomas Vachuskaedc944c2014-11-04 15:42:25 -080019import org.apache.felix.scr.annotations.Component;
20import org.apache.felix.scr.annotations.Reference;
21import org.apache.felix.scr.annotations.ReferenceCardinality;
22import org.onlab.onos.net.ElementId;
23import org.onlab.onos.net.Path;
24import org.onlab.onos.net.intent.ConnectivityIntent;
25import org.onlab.onos.net.intent.Constraint;
26import org.onlab.onos.net.intent.IntentCompiler;
27import org.onlab.onos.net.intent.IntentExtensionService;
28import org.onlab.onos.net.provider.ProviderId;
29import org.onlab.onos.net.resource.LinkResourceService;
30import org.onlab.onos.net.topology.LinkWeight;
31import org.onlab.onos.net.topology.PathService;
32import org.onlab.onos.net.topology.TopologyEdge;
33
Sho SHIMIZU56531512014-11-10 15:27:49 -080034import java.util.Collections;
Thomas Vachuskaedc944c2014-11-04 15:42:25 -080035import java.util.Iterator;
36import java.util.List;
37import java.util.Set;
38
39/**
40 * Base class for compilers of various
41 * {@link org.onlab.onos.net.intent.ConnectivityIntent connectivity intents}.
42 */
43@Component(immediate = true)
44public abstract class ConnectivityIntentCompiler<T extends ConnectivityIntent>
45 implements IntentCompiler<T> {
46
47 private static final ProviderId PID = new ProviderId("core", "org.onlab.onos.core", true);
48
49 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
50 protected IntentExtensionService intentManager;
51
52 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
53 protected PathService pathService;
54
55 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
56 protected LinkResourceService resourceService;
57
58 /**
59 * Returns an edge-weight capable of evaluating links on the basis of the
60 * specified constraints.
61 *
62 * @param constraints path constraints
63 * @return edge-weight function
64 */
65 protected LinkWeight weight(List<Constraint> constraints) {
66 return new ConstraintBasedLinkWeight(constraints);
67 }
68
69 /**
70 * Validates the specified path against the given constraints.
71 *
Thomas Vachuskab14c77a2014-11-04 18:08:01 -080072 * @param path path to be checked
73 * @param constraints path constraints
Thomas Vachuskaedc944c2014-11-04 15:42:25 -080074 * @return true if the path passes all constraints
75 */
76 protected boolean checkPath(Path path, List<Constraint> constraints) {
77 for (Constraint constraint : constraints) {
78 if (!constraint.validate(path, resourceService)) {
79 return false;
80 }
81 }
82 return true;
83 }
84
85 /**
86 * Computes a path between two ConnectPoints.
87 *
Thomas Vachuskab14c77a2014-11-04 18:08:01 -080088 * @param intent intent on which behalf path is being computed
89 * @param one start of the path
90 * @param two end of the path
Thomas Vachuskaedc944c2014-11-04 15:42:25 -080091 * @return Path between the two
92 * @throws PathNotFoundException if a path cannot be found
93 */
94 protected Path getPath(ConnectivityIntent intent,
95 ElementId one, ElementId two) {
96 Set<Path> paths = pathService.getPaths(one, two, weight(intent.constraints()));
97 if (paths.isEmpty()) {
98 throw new PathNotFoundException("No packet path from " + one + " to " + two);
99 }
100 // TODO: let's be more intelligent about this eventually
101 return paths.iterator().next();
102 }
103
104 /**
105 * Edge-weight capable of evaluating link cost using a set of constraints.
106 */
107 protected class ConstraintBasedLinkWeight implements LinkWeight {
108
109 private final List<Constraint> constraints;
110
111 /**
112 * Creates a new edge-weight function capable of evaluating links
113 * on the basis of the specified constraints.
114 *
115 * @param constraints path constraints
116 */
117 ConstraintBasedLinkWeight(List<Constraint> constraints) {
Sho SHIMIZU56531512014-11-10 15:27:49 -0800118 if (constraints == null) {
119 this.constraints = Collections.emptyList();
120 } else {
121 this.constraints = ImmutableList.copyOf(constraints);
122 }
Thomas Vachuskaedc944c2014-11-04 15:42:25 -0800123 }
124
125 @Override
126 public double weight(TopologyEdge edge) {
Sho SHIMIZU56531512014-11-10 15:27:49 -0800127 if (!constraints.iterator().hasNext()) {
Thomas Vachuskaedc944c2014-11-04 15:42:25 -0800128 return 1.0;
129 }
130
131 // iterate over all constraints in order and return the weight of
132 // the first one with fast fail over the first failure
133 Iterator<Constraint> it = constraints.iterator();
Ray Milkey460f4022014-11-05 15:41:43 -0800134
Thomas Vachuskaedc944c2014-11-04 15:42:25 -0800135 double cost = it.next().cost(edge.link(), resourceService);
136 while (it.hasNext() && cost > 0) {
137 if (it.next().cost(edge.link(), resourceService) < 0) {
138 return -1;
139 }
140 }
141 return cost;
Ray Milkey460f4022014-11-05 15:41:43 -0800142
Thomas Vachuskaedc944c2014-11-04 15:42:25 -0800143 }
144 }
145
146}