blob: cecff78501f1b85d0f9f475dce79b23d4b3aab32 [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
18import org.apache.felix.scr.annotations.Component;
19import org.apache.felix.scr.annotations.Reference;
20import org.apache.felix.scr.annotations.ReferenceCardinality;
21import org.onlab.onos.net.ElementId;
22import org.onlab.onos.net.Path;
23import org.onlab.onos.net.intent.ConnectivityIntent;
24import org.onlab.onos.net.intent.Constraint;
25import org.onlab.onos.net.intent.IntentCompiler;
26import org.onlab.onos.net.intent.IntentExtensionService;
27import org.onlab.onos.net.provider.ProviderId;
28import org.onlab.onos.net.resource.LinkResourceService;
29import org.onlab.onos.net.topology.LinkWeight;
30import org.onlab.onos.net.topology.PathService;
31import org.onlab.onos.net.topology.TopologyEdge;
32
33import java.util.Iterator;
34import java.util.List;
35import java.util.Set;
36
37/**
38 * Base class for compilers of various
39 * {@link org.onlab.onos.net.intent.ConnectivityIntent connectivity intents}.
40 */
41@Component(immediate = true)
42public abstract class ConnectivityIntentCompiler<T extends ConnectivityIntent>
43 implements IntentCompiler<T> {
44
45 private static final ProviderId PID = new ProviderId("core", "org.onlab.onos.core", true);
46
47 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
48 protected IntentExtensionService intentManager;
49
50 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
51 protected PathService pathService;
52
53 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
54 protected LinkResourceService resourceService;
55
56 /**
57 * Returns an edge-weight capable of evaluating links on the basis of the
58 * specified constraints.
59 *
60 * @param constraints path constraints
61 * @return edge-weight function
62 */
63 protected LinkWeight weight(List<Constraint> constraints) {
64 return new ConstraintBasedLinkWeight(constraints);
65 }
66
67 /**
68 * Validates the specified path against the given constraints.
69 *
70 * @param path path to be checked
71 * @return true if the path passes all constraints
72 */
73 protected boolean checkPath(Path path, List<Constraint> constraints) {
74 for (Constraint constraint : constraints) {
75 if (!constraint.validate(path, resourceService)) {
76 return false;
77 }
78 }
79 return true;
80 }
81
82 /**
83 * Computes a path between two ConnectPoints.
84 *
85 * @param one start of the path
86 * @param two end of the path
87 * @return Path between the two
88 * @throws PathNotFoundException if a path cannot be found
89 */
90 protected Path getPath(ConnectivityIntent intent,
91 ElementId one, ElementId two) {
92 Set<Path> paths = pathService.getPaths(one, two, weight(intent.constraints()));
93 if (paths.isEmpty()) {
94 throw new PathNotFoundException("No packet path from " + one + " to " + two);
95 }
96 // TODO: let's be more intelligent about this eventually
97 return paths.iterator().next();
98 }
99
100 /**
101 * Edge-weight capable of evaluating link cost using a set of constraints.
102 */
103 protected class ConstraintBasedLinkWeight implements LinkWeight {
104
105 private final List<Constraint> constraints;
106
107 /**
108 * Creates a new edge-weight function capable of evaluating links
109 * on the basis of the specified constraints.
110 *
111 * @param constraints path constraints
112 */
113 ConstraintBasedLinkWeight(List<Constraint> constraints) {
114 this.constraints = constraints;
115 }
116
117 @Override
118 public double weight(TopologyEdge edge) {
119 if (constraints == null) {
120 return 1.0;
121 }
122
123 // iterate over all constraints in order and return the weight of
124 // the first one with fast fail over the first failure
125 Iterator<Constraint> it = constraints.iterator();
126 double cost = it.next().cost(edge.link(), resourceService);
127 while (it.hasNext() && cost > 0) {
128 if (it.next().cost(edge.link(), resourceService) < 0) {
129 return -1;
130 }
131 }
132 return cost;
133 }
134 }
135
136}